diff --git a/.gitignore b/.gitignore index f7275bb..38b9c32 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,42 @@ +*.log +db.sqlite3 +*.pyc +*.DS_Store +build/ +*.egg_info +#editors && utilites. +*.swp +*~ +__pycache__/ +.ropeproject/ +#django +local_settings.py + +!.keep +media/ +!media/keep +/CACHE/ +/static/ + +\#*# +.\#* +*~ + +secret-key + +node_modules/ +*.db +ungleich.db +*~* + +secret-key + +*.psd + +.idea/ + +.env +*.mo + venv/ +dal/ldap_max_uid_file diff --git a/dal/dal/__init__.py b/dal/__init__.py similarity index 100% rename from dal/dal/__init__.py rename to dal/__init__.py diff --git a/dal/dal/models.py b/dal/dal/models.py deleted file mode 100644 index 7dee319..0000000 --- a/dal/dal/models.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.db import models - -# Basic DB to correlate tokens, users and creation time - -class ResetToken(models.Model): - - # users wouldn't use usernames >100 chars - user = models.CharField(max_length=100) - # Not so sure about tokens, better make it big - # should be <100, but big usernames make bigger tokens - # if I read that correctly - token = models.CharField(max_length=255) - # creation time in epoch (UTC) - # BigInt just so we are save for the next few decades ;) - creation = models.BigIntegerField() diff --git a/dal/dal/static/datacenterlight/font-awesome/css/font-awesome.min.css b/dal/dal/static/datacenterlight/font-awesome/css/font-awesome.min.css deleted file mode 100644 index 540440c..0000000 --- a/dal/dal/static/datacenterlight/font-awesome/css/font-awesome.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/dal/dal/templates/includes/_footer.html b/dal/dal/templates/includes/_footer.html deleted file mode 100644 index e61ed59..0000000 --- a/dal/dal/templates/includes/_footer.html +++ /dev/null @@ -1,44 +0,0 @@ -{% load i18n %} - - - - diff --git a/dal/dal/templates/landing.html b/dal/dal/templates/landing.html deleted file mode 100644 index f56d2bb..0000000 --- a/dal/dal/templates/landing.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends "base_short.html" %} -{% load staticfiles %} - - -{% block content %} - - -
-
-
-
-
-

Login

- {% include 'includes/_messages.html' %} -
- {% csrf_token %} -
-
-
-

- -
-
- -
-
-
-
- -{% endblock %} diff --git a/dal/dal/env.sample b/dal/env.sample similarity index 100% rename from dal/dal/env.sample rename to dal/env.sample diff --git a/dal/forms.py b/dal/forms.py new file mode 100644 index 0000000..d4bc028 --- /dev/null +++ b/dal/forms.py @@ -0,0 +1,31 @@ +from django import forms +from django.contrib.auth import authenticate +from django.utils.translation import ugettext_lazy as _ + + +class LoginForm(forms.Form): + email = forms.CharField(widget=forms.TextInput()) + password = forms.CharField(widget=forms.PasswordInput()) + + class Meta: + fields = ['email', 'password'] + + def clean(self): + email = self.cleaned_data.get('email') + password = self.cleaned_data.get('password') + if self.errors: + return self.cleaned_data + is_auth = authenticate(username=email, password=password) + if not is_auth: + raise forms.ValidationError( + _("Your username and/or password were incorrect.") + ) + # elif is_auth.validated == 0: + # raise forms.ValidationError( + # _("Your account is not activated yet.") + # ) + return self.cleaned_data + + def clean_email(self): + email = self.cleaned_data.get('email') + return email diff --git a/dal/migrations/0001_initial.py b/dal/migrations/0001_initial.py new file mode 100644 index 0000000..936a832 --- /dev/null +++ b/dal/migrations/0001_initial.py @@ -0,0 +1,37 @@ +# Generated by Django 2.1.7 on 2019-02-24 17:35 + +import dal.models +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='ResetToken', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('user', models.CharField(max_length=100)), + ('token', models.CharField(max_length=255)), + ('creation', models.BigIntegerField()), + ], + ), + migrations.CreateModel( + name='UserAccountValidationDetail', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('validated', models.IntegerField(choices=[(0, 'Not validated'), (1, 'Validated')], default=0)), + ('validation_slug', models.CharField(db_index=True, default=dal.models.get_validation_slug, max_length=50, unique=True)), + ('date_validation_started', models.DateTimeField(auto_now_add=True)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/dal/migrations/__init__.py b/dal/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dal/models.py b/dal/models.py new file mode 100644 index 0000000..676b103 --- /dev/null +++ b/dal/models.py @@ -0,0 +1,32 @@ +from django.db import models +from django.contrib.auth.hashers import make_password +from django.contrib.auth.models import User + +# Basic DB to correlate tokens, users and creation time + +class ResetToken(models.Model): + + # users wouldn't use usernames >100 chars + user = models.CharField(max_length=100) + # Not so sure about tokens, better make it big + # should be <100, but big usernames make bigger tokens + # if I read that correctly + token = models.CharField(max_length=255) + # creation time in epoch (UTC) + # BigInt just so we are save for the next few decades ;) + creation = models.BigIntegerField() + + +def get_validation_slug(): + return make_password(None) + + +class UserAccountValidationDetail(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + VALIDATED_CHOICES = ((0, 'Not validated'), (1, 'Validated')) + validated = models.IntegerField(choices=VALIDATED_CHOICES, default=0) + validation_slug = models.CharField( + db_index=True, unique=True, max_length=50, + default=get_validation_slug + ) + date_validation_started = models.DateTimeField(auto_now_add=True) diff --git a/dal/dal/settings.py b/dal/settings.py similarity index 52% rename from dal/dal/settings.py rename to dal/settings.py index a284663..a302eac 100644 --- a/dal/dal/settings.py +++ b/dal/settings.py @@ -11,29 +11,50 @@ https://docs.djangoproject.com/en/1.10/ref/settings/ """ import os -import dotenv +from decouple import config, Csv import ldap from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion -# get config -dotenv.read_dotenv() - # LDAP setup -AUTH_LDAP_SERVER_URI = os.environ['LDAPSERVER'] -AUTH_LDAP_BIND_DN = os.environ['LDAPSEARCHUSER'] -AUTH_LDAP_BIND_PASSWORD = os.environ['LDAPSEARCHUSERPASSWORD'] +LDAP_SERVER = config('LDAP_SERVER') +AUTH_LDAP_SERVER_URI = config('LDAPSERVER') + +LDAP_ADMIN_DN = config('LDAP_ADMIN_DN') +LDAP_ADMIN_PASSWORD = config('LDAP_ADMIN_PASSWORD') +AUTH_LDAP_BIND_DN = LDAP_ADMIN_DN +AUTH_LDAP_BIND_PASSWORD = LDAP_ADMIN_PASSWORD +AUTH_LDAP_SERVER = AUTH_LDAP_SERVER_URI + +LDAP_CUSTOMER_DN = config('LDAP_CUSTOMER_DN') +LDAP_USERS_DN = config('LDAP_USERS_DN') +LDAP_CUSTOMER_GROUP_ID = config('LDAP_CUSTOMER_GROUP_ID', cast=int) + +LDAP_MAX_UID_FILE_PATH = config( + 'LDAP_MAX_UID_FILE_PATH', + default=os.path.join(os.path.abspath( + os.path.dirname(__file__)), 'ldap_max_uid_file' + ) +) +LDAP_DEFAULT_START_UID = config('LDAP_DEFAULT_START_UID', cast=int) # Search union over OUs -search_base = os.environ['LDAPSEARCH'].split() +search_base = config('LDAPSEARCH').split() search_base_ldap = [ LDAPSearch(x, ldap.SCOPE_SUBTREE, "(uid=%(user)s)") for x in search_base ] AUTH_LDAP_USER_SEARCH = LDAPSearchUnion(*search_base_ldap) -if os.environ['LDAP_USE_TLS']: - AUTH_LDAP_START_TLS=True +AUTH_LDAP_START_TLS = config('LDAP_USE_TLS', default=False, cast=bool) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -ALLOWED_HOSTS = [] +DEBUG = config('DEBUG', default=False, cast=bool) + +EMAIL_FROM_ADDRESS = config('EMAIL_FROM_ADDRESS') + +EMAIL_HOST = config("EMAIL_HOST", default="localhost") +EMAIL_PORT = config("EMAIL_PORT", default=25, cast=int) +EMAIL_USE_TLS = config("EMAIL_USE_TLS", default=True, cast=bool) + +ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv()) INSTALLED_APPS = [ 'django.contrib.admin', @@ -42,6 +63,7 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'bootstrap3', 'dal', ] @@ -120,7 +142,7 @@ STATIC_URL = '/static/' ############################# To be fixed -STATIC_ROOT = os.path.dirname('/home/downhill/ungleich/vuejsuserservice/dal/dal/static/') +STATIC_ROOT= os.path.join(BASE_DIR, 'static/') # Database # https://docs.djangoproject.com/en/1.10/ref/settings/#databases @@ -131,7 +153,58 @@ DATABASES = { 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } -SECRET_KEY = 'rn=f&ecp#&#escxpk!0e%a$i3sbm$z@5+g4h9q+w7-83*f2f-i' +SECRET_KEY = config('SECRET_KEY') -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +AUTH_LDAP_USER_ATTR_MAP = { + "first_name": "givenName", + "last_name": "sn", + "email": "mail" +} + +ENTIRE_SEARCH_BASE = config("ENTIRE_SEARCH_BASE") + +LOGGING = { + 'disable_existing_loggers': False, + 'version': 1, + 'formatters': { + 'standard': { + 'format': '%(asctime)s %(levelname)s %(name)s %(funcName)s %(lineno)d: %(message)s' + } + }, + 'handlers': { + 'default': { + 'level': 'DEBUG', + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': 'logs/debug.log', + 'maxBytes': 1024*1024*5, + 'backupCount': 10, + 'formatter': 'standard', + }, + 'console': { + 'class': 'logging.StreamHandler', + }, + }, +} + +if config('ENABLE_DEBUG_LOG', default=False, cast=bool): + loggers_dict = {} + modules_to_log_list = config( + 'MODULES_TO_LOG', default='django', cast=Csv() + ) + for custom_module in modules_to_log_list: + logger_item = { + custom_module: { + 'handlers': ['default'], + 'level': 'INFO', + 'propagate': True + } + } + loggers_dict.update(logger_item) + + LOGGING['loggers'] = loggers_dict + + if 'ldap3' in modules_to_log_list: + from ldap3.utils.log import ( + set_library_log_detail_level, OFF, BASIC, NETWORK, EXTENDED + ) + set_library_log_detail_level(BASIC) diff --git a/dal/dal/static/datacenterlight/css/bootstrap-3.3.7.min.css b/dal/static/datacenterlight/css/bootstrap-3.3.7.min.css similarity index 100% rename from dal/dal/static/datacenterlight/css/bootstrap-3.3.7.min.css rename to dal/static/datacenterlight/css/bootstrap-3.3.7.min.css diff --git a/dal/dal/static/datacenterlight/css/cms.css b/dal/static/datacenterlight/css/cms.css similarity index 100% rename from dal/dal/static/datacenterlight/css/cms.css rename to dal/static/datacenterlight/css/cms.css diff --git a/dal/dal/static/datacenterlight/css/common.css b/dal/static/datacenterlight/css/common.css similarity index 100% rename from dal/dal/static/datacenterlight/css/common.css rename to dal/static/datacenterlight/css/common.css diff --git a/dal/dal/static/datacenterlight/css/header-slider.css b/dal/static/datacenterlight/css/header-slider.css similarity index 100% rename from dal/dal/static/datacenterlight/css/header-slider.css rename to dal/static/datacenterlight/css/header-slider.css diff --git a/dal/dal/static/datacenterlight/css/hosting.css b/dal/static/datacenterlight/css/hosting.css similarity index 100% rename from dal/dal/static/datacenterlight/css/hosting.css rename to dal/static/datacenterlight/css/hosting.css diff --git a/dal/dal/static/datacenterlight/css/landing-page.css b/dal/static/datacenterlight/css/landing-page.css similarity index 100% rename from dal/dal/static/datacenterlight/css/landing-page.css rename to dal/static/datacenterlight/css/landing-page.css diff --git a/dal/static/datacenterlight/font-awesome/css/font-awesome.min.css b/dal/static/datacenterlight/font-awesome/css/font-awesome.min.css new file mode 100644 index 0000000..248ea7a --- /dev/null +++ b/dal/static/datacenterlight/font-awesome/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale} .fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%} .fa-2x{font-size:2em} .fa-3x{font-size:3em} .fa-4x{font-size:4em} .fa-5x{font-size:5em} .fa-fw{width:1.28571429em;text-align:center} .fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none} .fa-ul>li{position:relative} .fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center} .fa-li.fa-lg{left:-1.85714286em} .fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em} .fa-pull-left{float:left} .fa-pull-right{float:right} .fa.fa-pull-left{margin-right:.3em} .fa.fa-pull-right{margin-left:.3em} .pull-right{float:right} .pull-left{float:left} .fa.pull-left{margin-right:.3em} .fa.pull-right{margin-left:.3em} .fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear} .fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)} @-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}} @keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}} .fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)} .fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)} .fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)} .fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)} .fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)} :root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none} .fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle} .fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center} .fa-stack-1x{line-height:inherit} .fa-stack-2x{font-size:2em} .fa-inverse{color:#fff} .fa-glass:before{content:"\f000"} .fa-music:before{content:"\f001"} .fa-search:before{content:"\f002"} .fa-envelope-o:before{content:"\f003"} .fa-heart:before{content:"\f004"} .fa-star:before{content:"\f005"} .fa-star-o:before{content:"\f006"} .fa-user:before{content:"\f007"} .fa-film:before{content:"\f008"} .fa-th-large:before{content:"\f009"} .fa-th:before{content:"\f00a"} .fa-th-list:before{content:"\f00b"} .fa-check:before{content:"\f00c"} .fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"} .fa-search-plus:before{content:"\f00e"} .fa-search-minus:before{content:"\f010"} .fa-power-off:before{content:"\f011"} .fa-signal:before{content:"\f012"} .fa-gear:before,.fa-cog:before{content:"\f013"} .fa-trash-o:before{content:"\f014"} .fa-home:before{content:"\f015"} .fa-file-o:before{content:"\f016"} .fa-clock-o:before{content:"\f017"} .fa-road:before{content:"\f018"} .fa-download:before{content:"\f019"} .fa-arrow-circle-o-down:before{content:"\f01a"} .fa-arrow-circle-o-up:before{content:"\f01b"} .fa-inbox:before{content:"\f01c"} .fa-play-circle-o:before{content:"\f01d"} .fa-rotate-right:before,.fa-repeat:before{content:"\f01e"} .fa-refresh:before{content:"\f021"} .fa-list-alt:before{content:"\f022"} .fa-lock:before{content:"\f023"} .fa-flag:before{content:"\f024"} .fa-headphones:before{content:"\f025"} .fa-volume-off:before{content:"\f026"} .fa-volume-down:before{content:"\f027"} .fa-volume-up:before{content:"\f028"} .fa-qrcode:before{content:"\f029"} .fa-barcode:before{content:"\f02a"} .fa-tag:before{content:"\f02b"} .fa-tags:before{content:"\f02c"} .fa-book:before{content:"\f02d"} .fa-bookmark:before{content:"\f02e"} .fa-print:before{content:"\f02f"} .fa-camera:before{content:"\f030"} .fa-font:before{content:"\f031"} .fa-bold:before{content:"\f032"} .fa-italic:before{content:"\f033"} .fa-text-height:before{content:"\f034"} .fa-text-width:before{content:"\f035"} .fa-align-left:before{content:"\f036"} .fa-align-center:before{content:"\f037"} .fa-align-right:before{content:"\f038"} .fa-align-justify:before{content:"\f039"} .fa-list:before{content:"\f03a"} .fa-dedent:before,.fa-outdent:before{content:"\f03b"} .fa-indent:before{content:"\f03c"} .fa-video-camera:before{content:"\f03d"} .fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"} .fa-pencil:before{content:"\f040"} .fa-map-marker:before{content:"\f041"} .fa-adjust:before{content:"\f042"} .fa-tint:before{content:"\f043"} .fa-edit:before,.fa-pencil-square-o:before{content:"\f044"} .fa-share-square-o:before{content:"\f045"} .fa-check-square-o:before{content:"\f046"} .fa-arrows:before{content:"\f047"} .fa-step-backward:before{content:"\f048"} .fa-fast-backward:before{content:"\f049"} .fa-backward:before{content:"\f04a"} .fa-play:before{content:"\f04b"} .fa-pause:before{content:"\f04c"} .fa-stop:before{content:"\f04d"} .fa-forward:before{content:"\f04e"} .fa-fast-forward:before{content:"\f050"} .fa-step-forward:before{content:"\f051"} .fa-eject:before{content:"\f052"} .fa-chevron-left:before{content:"\f053"} .fa-chevron-right:before{content:"\f054"} .fa-plus-circle:before{content:"\f055"} .fa-minus-circle:before{content:"\f056"} .fa-times-circle:before{content:"\f057"} .fa-check-circle:before{content:"\f058"} .fa-question-circle:before{content:"\f059"} .fa-info-circle:before{content:"\f05a"} .fa-crosshairs:before{content:"\f05b"} .fa-times-circle-o:before{content:"\f05c"} .fa-check-circle-o:before{content:"\f05d"} .fa-ban:before{content:"\f05e"} .fa-arrow-left:before{content:"\f060"} .fa-arrow-right:before{content:"\f061"} .fa-arrow-up:before{content:"\f062"} .fa-arrow-down:before{content:"\f063"} .fa-mail-forward:before,.fa-share:before{content:"\f064"} .fa-expand:before{content:"\f065"} .fa-compress:before{content:"\f066"} .fa-plus:before{content:"\f067"} .fa-minus:before{content:"\f068"} .fa-asterisk:before{content:"\f069"} .fa-exclamation-circle:before{content:"\f06a"} .fa-gift:before{content:"\f06b"} .fa-leaf:before{content:"\f06c"} .fa-fire:before{content:"\f06d"} .fa-eye:before{content:"\f06e"} .fa-eye-slash:before{content:"\f070"} .fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"} .fa-plane:before{content:"\f072"} .fa-calendar:before{content:"\f073"} .fa-random:before{content:"\f074"} .fa-comment:before{content:"\f075"} .fa-magnet:before{content:"\f076"} .fa-chevron-up:before{content:"\f077"} .fa-chevron-down:before{content:"\f078"} .fa-retweet:before{content:"\f079"} .fa-shopping-cart:before{content:"\f07a"} .fa-folder:before{content:"\f07b"} .fa-folder-open:before{content:"\f07c"} .fa-arrows-v:before{content:"\f07d"} .fa-arrows-h:before{content:"\f07e"} .fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"} .fa-twitter-square:before{content:"\f081"} .fa-facebook-square:before{content:"\f082"} .fa-camera-retro:before{content:"\f083"} .fa-key:before{content:"\f084"} .fa-gears:before,.fa-cogs:before{content:"\f085"} .fa-comments:before{content:"\f086"} .fa-thumbs-o-up:before{content:"\f087"} .fa-thumbs-o-down:before{content:"\f088"} .fa-star-half:before{content:"\f089"} .fa-heart-o:before{content:"\f08a"} .fa-sign-out:before{content:"\f08b"} .fa-linkedin-square:before{content:"\f08c"} .fa-thumb-tack:before{content:"\f08d"} .fa-external-link:before{content:"\f08e"} .fa-sign-in:before{content:"\f090"} .fa-trophy:before{content:"\f091"} .fa-github-square:before{content:"\f092"} .fa-upload:before{content:"\f093"} .fa-lemon-o:before{content:"\f094"} .fa-phone:before{content:"\f095"} .fa-square-o:before{content:"\f096"} .fa-bookmark-o:before{content:"\f097"} .fa-phone-square:before{content:"\f098"} .fa-twitter:before{content:"\f099"} .fa-facebook-f:before,.fa-facebook:before{content:"\f09a"} .fa-github:before{content:"\f09b"} .fa-unlock:before{content:"\f09c"} .fa-credit-card:before{content:"\f09d"} .fa-feed:before,.fa-rss:before{content:"\f09e"} .fa-hdd-o:before{content:"\f0a0"} .fa-bullhorn:before{content:"\f0a1"} .fa-bell:before{content:"\f0f3"} .fa-certificate:before{content:"\f0a3"} .fa-hand-o-right:before{content:"\f0a4"} .fa-hand-o-left:before{content:"\f0a5"} .fa-hand-o-up:before{content:"\f0a6"} .fa-hand-o-down:before{content:"\f0a7"} .fa-arrow-circle-left:before{content:"\f0a8"} .fa-arrow-circle-right:before{content:"\f0a9"} .fa-arrow-circle-up:before{content:"\f0aa"} .fa-arrow-circle-down:before{content:"\f0ab"} .fa-globe:before{content:"\f0ac"} .fa-wrench:before{content:"\f0ad"} .fa-tasks:before{content:"\f0ae"} .fa-filter:before{content:"\f0b0"} .fa-briefcase:before{content:"\f0b1"} .fa-arrows-alt:before{content:"\f0b2"} .fa-group:before,.fa-users:before{content:"\f0c0"} .fa-chain:before,.fa-link:before{content:"\f0c1"} .fa-cloud:before{content:"\f0c2"} .fa-flask:before{content:"\f0c3"} .fa-cut:before,.fa-scissors:before{content:"\f0c4"} .fa-copy:before,.fa-files-o:before{content:"\f0c5"} .fa-paperclip:before{content:"\f0c6"} .fa-save:before,.fa-floppy-o:before{content:"\f0c7"} .fa-square:before{content:"\f0c8"} .fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"} .fa-list-ul:before{content:"\f0ca"} .fa-list-ol:before{content:"\f0cb"} .fa-strikethrough:before{content:"\f0cc"} .fa-underline:before{content:"\f0cd"} .fa-table:before{content:"\f0ce"} .fa-magic:before{content:"\f0d0"} .fa-truck:before{content:"\f0d1"} .fa-pinterest:before{content:"\f0d2"} .fa-pinterest-square:before{content:"\f0d3"} .fa-google-plus-square:before{content:"\f0d4"} .fa-google-plus:before{content:"\f0d5"} .fa-money:before{content:"\f0d6"} .fa-caret-down:before{content:"\f0d7"} .fa-caret-up:before{content:"\f0d8"} .fa-caret-left:before{content:"\f0d9"} .fa-caret-right:before{content:"\f0da"} .fa-columns:before{content:"\f0db"} .fa-unsorted:before,.fa-sort:before{content:"\f0dc"} .fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"} .fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"} .fa-envelope:before{content:"\f0e0"} .fa-linkedin:before{content:"\f0e1"} .fa-rotate-left:before,.fa-undo:before{content:"\f0e2"} .fa-legal:before,.fa-gavel:before{content:"\f0e3"} .fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"} .fa-comment-o:before{content:"\f0e5"} .fa-comments-o:before{content:"\f0e6"} .fa-flash:before,.fa-bolt:before{content:"\f0e7"} .fa-sitemap:before{content:"\f0e8"} .fa-umbrella:before{content:"\f0e9"} .fa-paste:before,.fa-clipboard:before{content:"\f0ea"} .fa-lightbulb-o:before{content:"\f0eb"} .fa-exchange:before{content:"\f0ec"} .fa-cloud-download:before{content:"\f0ed"} .fa-cloud-upload:before{content:"\f0ee"} .fa-user-md:before{content:"\f0f0"} .fa-stethoscope:before{content:"\f0f1"} .fa-suitcase:before{content:"\f0f2"} .fa-bell-o:before{content:"\f0a2"} .fa-coffee:before{content:"\f0f4"} .fa-cutlery:before{content:"\f0f5"} .fa-file-text-o:before{content:"\f0f6"} .fa-building-o:before{content:"\f0f7"} .fa-hospital-o:before{content:"\f0f8"} .fa-ambulance:before{content:"\f0f9"} .fa-medkit:before{content:"\f0fa"} .fa-fighter-jet:before{content:"\f0fb"} .fa-beer:before{content:"\f0fc"} .fa-h-square:before{content:"\f0fd"} .fa-plus-square:before{content:"\f0fe"} .fa-angle-double-left:before{content:"\f100"} .fa-angle-double-right:before{content:"\f101"} .fa-angle-double-up:before{content:"\f102"} .fa-angle-double-down:before{content:"\f103"} .fa-angle-left:before{content:"\f104"} .fa-angle-right:before{content:"\f105"} .fa-angle-up:before{content:"\f106"} .fa-angle-down:before{content:"\f107"} .fa-desktop:before{content:"\f108"} .fa-laptop:before{content:"\f109"} .fa-tablet:before{content:"\f10a"} .fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"} .fa-circle-o:before{content:"\f10c"} .fa-quote-left:before{content:"\f10d"} .fa-quote-right:before{content:"\f10e"} .fa-spinner:before{content:"\f110"} .fa-circle:before{content:"\f111"} .fa-mail-reply:before,.fa-reply:before{content:"\f112"} .fa-github-alt:before{content:"\f113"} .fa-folder-o:before{content:"\f114"} .fa-folder-open-o:before{content:"\f115"} .fa-smile-o:before{content:"\f118"} .fa-frown-o:before{content:"\f119"} .fa-meh-o:before{content:"\f11a"} .fa-gamepad:before{content:"\f11b"} .fa-keyboard-o:before{content:"\f11c"} .fa-flag-o:before{content:"\f11d"} .fa-flag-checkered:before{content:"\f11e"} .fa-terminal:before{content:"\f120"} .fa-code:before{content:"\f121"} .fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"} .fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"} .fa-location-arrow:before{content:"\f124"} .fa-crop:before{content:"\f125"} .fa-code-fork:before{content:"\f126"} .fa-unlink:before,.fa-chain-broken:before{content:"\f127"} .fa-question:before{content:"\f128"} .fa-info:before{content:"\f129"} .fa-exclamation:before{content:"\f12a"} .fa-superscript:before{content:"\f12b"} .fa-subscript:before{content:"\f12c"} .fa-eraser:before{content:"\f12d"} .fa-puzzle-piece:before{content:"\f12e"} .fa-microphone:before{content:"\f130"} .fa-microphone-slash:before{content:"\f131"} .fa-shield:before{content:"\f132"} .fa-calendar-o:before{content:"\f133"} .fa-fire-extinguisher:before{content:"\f134"} .fa-rocket:before{content:"\f135"} .fa-maxcdn:before{content:"\f136"} .fa-chevron-circle-left:before{content:"\f137"} .fa-chevron-circle-right:before{content:"\f138"} .fa-chevron-circle-up:before{content:"\f139"} .fa-chevron-circle-down:before{content:"\f13a"} .fa-html5:before{content:"\f13b"} .fa-css3:before{content:"\f13c"} .fa-anchor:before{content:"\f13d"} .fa-unlock-alt:before{content:"\f13e"} .fa-bullseye:before{content:"\f140"} .fa-ellipsis-h:before{content:"\f141"} .fa-ellipsis-v:before{content:"\f142"} .fa-rss-square:before{content:"\f143"} .fa-play-circle:before{content:"\f144"} .fa-ticket:before{content:"\f145"} .fa-minus-square:before{content:"\f146"} .fa-minus-square-o:before{content:"\f147"} .fa-level-up:before{content:"\f148"} .fa-level-down:before{content:"\f149"} .fa-check-square:before{content:"\f14a"} .fa-pencil-square:before{content:"\f14b"} .fa-external-link-square:before{content:"\f14c"} .fa-share-square:before{content:"\f14d"} .fa-compass:before{content:"\f14e"} .fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"} .fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"} .fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"} .fa-euro:before,.fa-eur:before{content:"\f153"} .fa-gbp:before{content:"\f154"} .fa-dollar:before,.fa-usd:before{content:"\f155"} .fa-rupee:before,.fa-inr:before{content:"\f156"} .fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"} .fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"} .fa-won:before,.fa-krw:before{content:"\f159"} .fa-bitcoin:before,.fa-btc:before{content:"\f15a"} .fa-file:before{content:"\f15b"} .fa-file-text:before{content:"\f15c"} .fa-sort-alpha-asc:before{content:"\f15d"} .fa-sort-alpha-desc:before{content:"\f15e"} .fa-sort-amount-asc:before{content:"\f160"} .fa-sort-amount-desc:before{content:"\f161"} .fa-sort-numeric-asc:before{content:"\f162"} .fa-sort-numeric-desc:before{content:"\f163"} .fa-thumbs-up:before{content:"\f164"} .fa-thumbs-down:before{content:"\f165"} .fa-youtube-square:before{content:"\f166"} .fa-youtube:before{content:"\f167"} .fa-xing:before{content:"\f168"} .fa-xing-square:before{content:"\f169"} .fa-youtube-play:before{content:"\f16a"} .fa-dropbox:before{content:"\f16b"} .fa-stack-overflow:before{content:"\f16c"} .fa-instagram:before{content:"\f16d"} .fa-flickr:before{content:"\f16e"} .fa-adn:before{content:"\f170"} .fa-bitbucket:before{content:"\f171"} .fa-bitbucket-square:before{content:"\f172"} .fa-tumblr:before{content:"\f173"} .fa-tumblr-square:before{content:"\f174"} .fa-long-arrow-down:before{content:"\f175"} .fa-long-arrow-up:before{content:"\f176"} .fa-long-arrow-left:before{content:"\f177"} .fa-long-arrow-right:before{content:"\f178"} .fa-apple:before{content:"\f179"} .fa-windows:before{content:"\f17a"} .fa-android:before{content:"\f17b"} .fa-linux:before{content:"\f17c"} .fa-dribbble:before{content:"\f17d"} .fa-skype:before{content:"\f17e"} .fa-foursquare:before{content:"\f180"} .fa-trello:before{content:"\f181"} .fa-female:before{content:"\f182"} .fa-male:before{content:"\f183"} .fa-gittip:before,.fa-gratipay:before{content:"\f184"} .fa-sun-o:before{content:"\f185"} .fa-moon-o:before{content:"\f186"} .fa-archive:before{content:"\f187"} .fa-bug:before{content:"\f188"} .fa-vk:before{content:"\f189"} .fa-weibo:before{content:"\f18a"} .fa-renren:before{content:"\f18b"} .fa-pagelines:before{content:"\f18c"} .fa-stack-exchange:before{content:"\f18d"} .fa-arrow-circle-o-right:before{content:"\f18e"} .fa-arrow-circle-o-left:before{content:"\f190"} .fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"} .fa-dot-circle-o:before{content:"\f192"} .fa-wheelchair:before{content:"\f193"} .fa-vimeo-square:before{content:"\f194"} .fa-turkish-lira:before,.fa-try:before{content:"\f195"} .fa-plus-square-o:before{content:"\f196"} .fa-space-shuttle:before{content:"\f197"} .fa-slack:before{content:"\f198"} .fa-envelope-square:before{content:"\f199"} .fa-wordpress:before{content:"\f19a"} .fa-openid:before{content:"\f19b"} .fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"} .fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"} .fa-yahoo:before{content:"\f19e"} .fa-google:before{content:"\f1a0"} .fa-reddit:before{content:"\f1a1"} .fa-reddit-square:before{content:"\f1a2"} .fa-stumbleupon-circle:before{content:"\f1a3"} .fa-stumbleupon:before{content:"\f1a4"} .fa-delicious:before{content:"\f1a5"} .fa-digg:before{content:"\f1a6"} .fa-pied-piper-pp:before{content:"\f1a7"} .fa-pied-piper-alt:before{content:"\f1a8"} .fa-drupal:before{content:"\f1a9"} .fa-joomla:before{content:"\f1aa"} .fa-language:before{content:"\f1ab"} .fa-fax:before{content:"\f1ac"} .fa-building:before{content:"\f1ad"} .fa-child:before{content:"\f1ae"} .fa-paw:before{content:"\f1b0"} .fa-spoon:before{content:"\f1b1"} .fa-cube:before{content:"\f1b2"} .fa-cubes:before{content:"\f1b3"} .fa-behance:before{content:"\f1b4"} .fa-behance-square:before{content:"\f1b5"} .fa-steam:before{content:"\f1b6"} .fa-steam-square:before{content:"\f1b7"} .fa-recycle:before{content:"\f1b8"} .fa-automobile:before,.fa-car:before{content:"\f1b9"} .fa-cab:before,.fa-taxi:before{content:"\f1ba"} .fa-tree:before{content:"\f1bb"} .fa-spotify:before{content:"\f1bc"} .fa-deviantart:before{content:"\f1bd"} .fa-soundcloud:before{content:"\f1be"} .fa-database:before{content:"\f1c0"} .fa-file-pdf-o:before{content:"\f1c1"} .fa-file-word-o:before{content:"\f1c2"} .fa-file-excel-o:before{content:"\f1c3"} .fa-file-powerpoint-o:before{content:"\f1c4"} .fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"} .fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"} .fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"} .fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"} .fa-file-code-o:before{content:"\f1c9"} .fa-vine:before{content:"\f1ca"} .fa-codepen:before{content:"\f1cb"} .fa-jsfiddle:before{content:"\f1cc"} .fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"} .fa-circle-o-notch:before{content:"\f1ce"} .fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"} .fa-ge:before,.fa-empire:before{content:"\f1d1"} .fa-git-square:before{content:"\f1d2"} .fa-git:before{content:"\f1d3"} .fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"} .fa-tencent-weibo:before{content:"\f1d5"} .fa-qq:before{content:"\f1d6"} .fa-wechat:before,.fa-weixin:before{content:"\f1d7"} .fa-send:before,.fa-paper-plane:before{content:"\f1d8"} .fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"} .fa-history:before{content:"\f1da"} .fa-circle-thin:before{content:"\f1db"} .fa-header:before{content:"\f1dc"} .fa-paragraph:before{content:"\f1dd"} .fa-sliders:before{content:"\f1de"} .fa-share-alt:before{content:"\f1e0"} .fa-share-alt-square:before{content:"\f1e1"} .fa-bomb:before{content:"\f1e2"} .fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"} .fa-tty:before{content:"\f1e4"} .fa-binoculars:before{content:"\f1e5"} .fa-plug:before{content:"\f1e6"} .fa-slideshare:before{content:"\f1e7"} .fa-twitch:before{content:"\f1e8"} .fa-yelp:before{content:"\f1e9"} .fa-newspaper-o:before{content:"\f1ea"} .fa-wifi:before{content:"\f1eb"} .fa-calculator:before{content:"\f1ec"} .fa-paypal:before{content:"\f1ed"} .fa-google-wallet:before{content:"\f1ee"} .fa-cc-visa:before{content:"\f1f0"} .fa-cc-mastercard:before{content:"\f1f1"} .fa-cc-discover:before{content:"\f1f2"} .fa-cc-amex:before{content:"\f1f3"} .fa-cc-paypal:before{content:"\f1f4"} .fa-cc-stripe:before{content:"\f1f5"} .fa-bell-slash:before{content:"\f1f6"} .fa-bell-slash-o:before{content:"\f1f7"} .fa-trash:before{content:"\f1f8"} .fa-copyright:before{content:"\f1f9"} .fa-at:before{content:"\f1fa"} .fa-eyedropper:before{content:"\f1fb"} .fa-paint-brush:before{content:"\f1fc"} .fa-birthday-cake:before{content:"\f1fd"} .fa-area-chart:before{content:"\f1fe"} .fa-pie-chart:before{content:"\f200"} .fa-line-chart:before{content:"\f201"} .fa-lastfm:before{content:"\f202"} .fa-lastfm-square:before{content:"\f203"} .fa-toggle-off:before{content:"\f204"} .fa-toggle-on:before{content:"\f205"} .fa-bicycle:before{content:"\f206"} .fa-bus:before{content:"\f207"} .fa-ioxhost:before{content:"\f208"} .fa-angellist:before{content:"\f209"} .fa-cc:before{content:"\f20a"} .fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"} .fa-meanpath:before{content:"\f20c"} .fa-buysellads:before{content:"\f20d"} .fa-connectdevelop:before{content:"\f20e"} .fa-dashcube:before{content:"\f210"} .fa-forumbee:before{content:"\f211"} .fa-leanpub:before{content:"\f212"} .fa-sellsy:before{content:"\f213"} .fa-shirtsinbulk:before{content:"\f214"} .fa-simplybuilt:before{content:"\f215"} .fa-skyatlas:before{content:"\f216"} .fa-cart-plus:before{content:"\f217"} .fa-cart-arrow-down:before{content:"\f218"} .fa-diamond:before{content:"\f219"} .fa-ship:before{content:"\f21a"} .fa-user-secret:before{content:"\f21b"} .fa-motorcycle:before{content:"\f21c"} .fa-street-view:before{content:"\f21d"} .fa-heartbeat:before{content:"\f21e"} .fa-venus:before{content:"\f221"} .fa-mars:before{content:"\f222"} .fa-mercury:before{content:"\f223"} .fa-intersex:before,.fa-transgender:before{content:"\f224"} .fa-transgender-alt:before{content:"\f225"} .fa-venus-double:before{content:"\f226"} .fa-mars-double:before{content:"\f227"} .fa-venus-mars:before{content:"\f228"} .fa-mars-stroke:before{content:"\f229"} .fa-mars-stroke-v:before{content:"\f22a"} .fa-mars-stroke-h:before{content:"\f22b"} .fa-neuter:before{content:"\f22c"} .fa-genderless:before{content:"\f22d"} .fa-facebook-official:before{content:"\f230"} .fa-pinterest-p:before{content:"\f231"} .fa-whatsapp:before{content:"\f232"} .fa-server:before{content:"\f233"} .fa-user-plus:before{content:"\f234"} .fa-user-times:before{content:"\f235"} .fa-hotel:before,.fa-bed:before{content:"\f236"} .fa-viacoin:before{content:"\f237"} .fa-train:before{content:"\f238"} .fa-subway:before{content:"\f239"} .fa-medium:before{content:"\f23a"} .fa-yc:before,.fa-y-combinator:before{content:"\f23b"} .fa-optin-monster:before{content:"\f23c"} .fa-opencart:before{content:"\f23d"} .fa-expeditedssl:before{content:"\f23e"} .fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"} .fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"} .fa-battery-2:before,.fa-battery-half:before{content:"\f242"} .fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"} .fa-battery-0:before,.fa-battery-empty:before{content:"\f244"} .fa-mouse-pointer:before{content:"\f245"} .fa-i-cursor:before{content:"\f246"} .fa-object-group:before{content:"\f247"} .fa-object-ungroup:before{content:"\f248"} .fa-sticky-note:before{content:"\f249"} .fa-sticky-note-o:before{content:"\f24a"} .fa-cc-jcb:before{content:"\f24b"} .fa-cc-diners-club:before{content:"\f24c"} .fa-clone:before{content:"\f24d"} .fa-balance-scale:before{content:"\f24e"} .fa-hourglass-o:before{content:"\f250"} .fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"} .fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"} .fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"} .fa-hourglass:before{content:"\f254"} .fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"} .fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"} .fa-hand-scissors-o:before{content:"\f257"} .fa-hand-lizard-o:before{content:"\f258"} .fa-hand-spock-o:before{content:"\f259"} .fa-hand-pointer-o:before{content:"\f25a"} .fa-hand-peace-o:before{content:"\f25b"} .fa-trademark:before{content:"\f25c"} .fa-registered:before{content:"\f25d"} .fa-creative-commons:before{content:"\f25e"} .fa-gg:before{content:"\f260"} .fa-gg-circle:before{content:"\f261"} .fa-tripadvisor:before{content:"\f262"} .fa-odnoklassniki:before{content:"\f263"} .fa-odnoklassniki-square:before{content:"\f264"} .fa-get-pocket:before{content:"\f265"} .fa-wikipedia-w:before{content:"\f266"} .fa-safari:before{content:"\f267"} .fa-chrome:before{content:"\f268"} .fa-firefox:before{content:"\f269"} .fa-opera:before{content:"\f26a"} .fa-internet-explorer:before{content:"\f26b"} .fa-tv:before,.fa-television:before{content:"\f26c"} .fa-contao:before{content:"\f26d"} .fa-500px:before{content:"\f26e"} .fa-amazon:before{content:"\f270"} .fa-calendar-plus-o:before{content:"\f271"} .fa-calendar-minus-o:before{content:"\f272"} .fa-calendar-times-o:before{content:"\f273"} .fa-calendar-check-o:before{content:"\f274"} .fa-industry:before{content:"\f275"} .fa-map-pin:before{content:"\f276"} .fa-map-signs:before{content:"\f277"} .fa-map-o:before{content:"\f278"} .fa-map:before{content:"\f279"} .fa-commenting:before{content:"\f27a"} .fa-commenting-o:before{content:"\f27b"} .fa-houzz:before{content:"\f27c"} .fa-vimeo:before{content:"\f27d"} .fa-black-tie:before{content:"\f27e"} .fa-fonticons:before{content:"\f280"} .fa-reddit-alien:before{content:"\f281"} .fa-edge:before{content:"\f282"} .fa-credit-card-alt:before{content:"\f283"} .fa-codiepie:before{content:"\f284"} .fa-modx:before{content:"\f285"} .fa-fort-awesome:before{content:"\f286"} .fa-usb:before{content:"\f287"} .fa-product-hunt:before{content:"\f288"} .fa-mixcloud:before{content:"\f289"} .fa-scribd:before{content:"\f28a"} .fa-pause-circle:before{content:"\f28b"} .fa-pause-circle-o:before{content:"\f28c"} .fa-stop-circle:before{content:"\f28d"} .fa-stop-circle-o:before{content:"\f28e"} .fa-shopping-bag:before{content:"\f290"} .fa-shopping-basket:before{content:"\f291"} .fa-hashtag:before{content:"\f292"} .fa-bluetooth:before{content:"\f293"} .fa-bluetooth-b:before{content:"\f294"} .fa-percent:before{content:"\f295"} .fa-gitlab:before{content:"\f296"} .fa-wpbeginner:before{content:"\f297"} .fa-wpforms:before{content:"\f298"} .fa-envira:before{content:"\f299"} .fa-universal-access:before{content:"\f29a"} .fa-wheelchair-alt:before{content:"\f29b"} .fa-question-circle-o:before{content:"\f29c"} .fa-blind:before{content:"\f29d"} .fa-audio-description:before{content:"\f29e"} .fa-volume-control-phone:before{content:"\f2a0"} .fa-braille:before{content:"\f2a1"} .fa-assistive-listening-systems:before{content:"\f2a2"} .fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"} .fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"} .fa-glide:before{content:"\f2a5"} .fa-glide-g:before{content:"\f2a6"} .fa-signing:before,.fa-sign-language:before{content:"\f2a7"} .fa-low-vision:before{content:"\f2a8"} .fa-viadeo:before{content:"\f2a9"} .fa-viadeo-square:before{content:"\f2aa"} .fa-snapchat:before{content:"\f2ab"} .fa-snapchat-ghost:before{content:"\f2ac"} .fa-snapchat-square:before{content:"\f2ad"} .fa-pied-piper:before{content:"\f2ae"} .fa-first-order:before{content:"\f2b0"} .fa-yoast:before{content:"\f2b1"} .fa-themeisle:before{content:"\f2b2"} .fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"} .fa-fa:before,.fa-font-awesome:before{content:"\f2b4"} .fa-handshake-o:before{content:"\f2b5"} .fa-envelope-open:before{content:"\f2b6"} .fa-envelope-open-o:before{content:"\f2b7"} .fa-linode:before{content:"\f2b8"} .fa-address-book:before{content:"\f2b9"} .fa-address-book-o:before{content:"\f2ba"} .fa-vcard:before,.fa-address-card:before{content:"\f2bb"} .fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"} .fa-user-circle:before{content:"\f2bd"} .fa-user-circle-o:before{content:"\f2be"} .fa-user-o:before{content:"\f2c0"} .fa-id-badge:before{content:"\f2c1"} .fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"} .fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"} .fa-quora:before{content:"\f2c4"} .fa-free-code-camp:before{content:"\f2c5"} .fa-telegram:before{content:"\f2c6"} .fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"} .fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"} .fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"} .fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"} .fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"} .fa-shower:before{content:"\f2cc"} .fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"} .fa-podcast:before{content:"\f2ce"} .fa-window-maximize:before{content:"\f2d0"} .fa-window-minimize:before{content:"\f2d1"} .fa-window-restore:before{content:"\f2d2"} .fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"} .fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"} .fa-bandcamp:before{content:"\f2d5"} .fa-grav:before{content:"\f2d6"} .fa-etsy:before{content:"\f2d7"} .fa-imdb:before{content:"\f2d8"} .fa-ravelry:before{content:"\f2d9"} .fa-eercast:before{content:"\f2da"} .fa-microchip:before{content:"\f2db"} .fa-snowflake-o:before{content:"\f2dc"} .fa-superpowers:before{content:"\f2dd"} .fa-wpexplorer:before{content:"\f2de"} .fa-meetup:before{content:"\f2e0"} .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0} .sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/dal/dal/static/datacenterlight/font-awesome/fonts/FontAwesome.otf b/dal/static/datacenterlight/font-awesome/fonts/FontAwesome.otf similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/fonts/FontAwesome.otf rename to dal/static/datacenterlight/font-awesome/fonts/FontAwesome.otf diff --git a/dal/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.eot b/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.eot similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.eot rename to dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.eot diff --git a/dal/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.svg b/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.svg similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.svg rename to dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.svg diff --git a/dal/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.ttf b/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.ttf similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.ttf rename to dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.ttf diff --git a/dal/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.woff b/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.woff similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.woff rename to dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.woff diff --git a/dal/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.woff2 b/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.woff2 similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.woff2 rename to dal/static/datacenterlight/font-awesome/fonts/fontawesome-webfont.woff2 diff --git a/dal/dal/static/datacenterlight/font-awesome/less/bordered-pulled.less b/dal/static/datacenterlight/font-awesome/less/bordered-pulled.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/bordered-pulled.less rename to dal/static/datacenterlight/font-awesome/less/bordered-pulled.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/core.less b/dal/static/datacenterlight/font-awesome/less/core.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/core.less rename to dal/static/datacenterlight/font-awesome/less/core.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/fixed-width.less b/dal/static/datacenterlight/font-awesome/less/fixed-width.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/fixed-width.less rename to dal/static/datacenterlight/font-awesome/less/fixed-width.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/font-awesome.less b/dal/static/datacenterlight/font-awesome/less/font-awesome.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/font-awesome.less rename to dal/static/datacenterlight/font-awesome/less/font-awesome.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/icons.less b/dal/static/datacenterlight/font-awesome/less/icons.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/icons.less rename to dal/static/datacenterlight/font-awesome/less/icons.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/larger.less b/dal/static/datacenterlight/font-awesome/less/larger.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/larger.less rename to dal/static/datacenterlight/font-awesome/less/larger.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/list.less b/dal/static/datacenterlight/font-awesome/less/list.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/list.less rename to dal/static/datacenterlight/font-awesome/less/list.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/mixins.less b/dal/static/datacenterlight/font-awesome/less/mixins.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/mixins.less rename to dal/static/datacenterlight/font-awesome/less/mixins.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/path.less b/dal/static/datacenterlight/font-awesome/less/path.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/path.less rename to dal/static/datacenterlight/font-awesome/less/path.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/rotated-flipped.less b/dal/static/datacenterlight/font-awesome/less/rotated-flipped.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/rotated-flipped.less rename to dal/static/datacenterlight/font-awesome/less/rotated-flipped.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/spinning.less b/dal/static/datacenterlight/font-awesome/less/spinning.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/spinning.less rename to dal/static/datacenterlight/font-awesome/less/spinning.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/stacked.less b/dal/static/datacenterlight/font-awesome/less/stacked.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/stacked.less rename to dal/static/datacenterlight/font-awesome/less/stacked.less diff --git a/dal/dal/static/datacenterlight/font-awesome/less/variables.less b/dal/static/datacenterlight/font-awesome/less/variables.less similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/less/variables.less rename to dal/static/datacenterlight/font-awesome/less/variables.less diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_bordered-pulled.scss b/dal/static/datacenterlight/font-awesome/scss/_bordered-pulled.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_bordered-pulled.scss rename to dal/static/datacenterlight/font-awesome/scss/_bordered-pulled.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_core.scss b/dal/static/datacenterlight/font-awesome/scss/_core.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_core.scss rename to dal/static/datacenterlight/font-awesome/scss/_core.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_fixed-width.scss b/dal/static/datacenterlight/font-awesome/scss/_fixed-width.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_fixed-width.scss rename to dal/static/datacenterlight/font-awesome/scss/_fixed-width.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_icons.scss b/dal/static/datacenterlight/font-awesome/scss/_icons.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_icons.scss rename to dal/static/datacenterlight/font-awesome/scss/_icons.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_larger.scss b/dal/static/datacenterlight/font-awesome/scss/_larger.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_larger.scss rename to dal/static/datacenterlight/font-awesome/scss/_larger.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_list.scss b/dal/static/datacenterlight/font-awesome/scss/_list.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_list.scss rename to dal/static/datacenterlight/font-awesome/scss/_list.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_mixins.scss b/dal/static/datacenterlight/font-awesome/scss/_mixins.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_mixins.scss rename to dal/static/datacenterlight/font-awesome/scss/_mixins.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_path.scss b/dal/static/datacenterlight/font-awesome/scss/_path.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_path.scss rename to dal/static/datacenterlight/font-awesome/scss/_path.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_rotated-flipped.scss b/dal/static/datacenterlight/font-awesome/scss/_rotated-flipped.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_rotated-flipped.scss rename to dal/static/datacenterlight/font-awesome/scss/_rotated-flipped.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_spinning.scss b/dal/static/datacenterlight/font-awesome/scss/_spinning.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_spinning.scss rename to dal/static/datacenterlight/font-awesome/scss/_spinning.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_stacked.scss b/dal/static/datacenterlight/font-awesome/scss/_stacked.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_stacked.scss rename to dal/static/datacenterlight/font-awesome/scss/_stacked.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/_variables.scss b/dal/static/datacenterlight/font-awesome/scss/_variables.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/_variables.scss rename to dal/static/datacenterlight/font-awesome/scss/_variables.scss diff --git a/dal/dal/static/datacenterlight/font-awesome/scss/font-awesome.scss b/dal/static/datacenterlight/font-awesome/scss/font-awesome.scss similarity index 100% rename from dal/dal/static/datacenterlight/font-awesome/scss/font-awesome.scss rename to dal/static/datacenterlight/font-awesome/scss/font-awesome.scss diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Black.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Black.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Black.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-Black.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-BlackItalic.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-BlackItalic.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-BlackItalic.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-BlackItalic.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Bold.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Bold.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Bold.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-Bold.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-BoldItalic.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-BoldItalic.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-BoldItalic.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-BoldItalic.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraBold.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraBold.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraBold.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraBold.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraBoldItalic.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraBoldItalic.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraBoldItalic.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraBoldItalic.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraLight.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraLight.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraLight.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraLight.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraLightItalic.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraLightItalic.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraLightItalic.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-ExtraLightItalic.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Italic.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Italic.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Italic.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-Italic.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Light.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Light.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Light.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-Light.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-LightItalic.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-LightItalic.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-LightItalic.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-LightItalic.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Medium.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Medium.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Medium.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-Medium.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-MediumItalic.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-MediumItalic.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-MediumItalic.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-MediumItalic.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Regular.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Regular.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Regular.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-Regular.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-SemiBold.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-SemiBold.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-SemiBold.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-SemiBold.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-SemiBoldItalic.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-SemiBoldItalic.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-SemiBoldItalic.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-SemiBoldItalic.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Thin.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Thin.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-Thin.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-Thin.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ThinItalic.ttf b/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ThinItalic.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/Montserrat-ThinItalic.ttf rename to dal/static/datacenterlight/fonts/Montserrat/Montserrat-ThinItalic.ttf diff --git a/dal/dal/static/datacenterlight/fonts/Montserrat/OFL.txt b/dal/static/datacenterlight/fonts/Montserrat/OFL.txt similarity index 100% rename from dal/dal/static/datacenterlight/fonts/Montserrat/OFL.txt rename to dal/static/datacenterlight/fonts/Montserrat/OFL.txt diff --git a/dal/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.eot b/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from dal/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.eot rename to dal/static/datacenterlight/fonts/glyphicons-halflings-regular.eot diff --git a/dal/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.svg b/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from dal/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.svg rename to dal/static/datacenterlight/fonts/glyphicons-halflings-regular.svg diff --git a/dal/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.ttf b/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from dal/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.ttf rename to dal/static/datacenterlight/fonts/glyphicons-halflings-regular.ttf diff --git a/dal/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.woff b/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from dal/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.woff rename to dal/static/datacenterlight/fonts/glyphicons-halflings-regular.woff diff --git a/dal/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.woff2 b/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.woff2 similarity index 100% rename from dal/dal/static/datacenterlight/fonts/glyphicons-halflings-regular.woff2 rename to dal/static/datacenterlight/fonts/glyphicons-halflings-regular.woff2 diff --git a/dal/dal/static/datacenterlight/img/Ceph_Logo.png b/dal/static/datacenterlight/img/Ceph_Logo.png similarity index 100% rename from dal/dal/static/datacenterlight/img/Ceph_Logo.png rename to dal/static/datacenterlight/img/Ceph_Logo.png diff --git a/dal/dal/static/datacenterlight/img/banner-bg copy.jpg b/dal/static/datacenterlight/img/banner-bg copy.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/banner-bg copy.jpg rename to dal/static/datacenterlight/img/banner-bg copy.jpg diff --git a/dal/dal/static/datacenterlight/img/banner-bg.jpg b/dal/static/datacenterlight/img/banner-bg.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/banner-bg.jpg rename to dal/static/datacenterlight/img/banner-bg.jpg diff --git a/dal/dal/static/datacenterlight/img/bg.png b/dal/static/datacenterlight/img/bg.png similarity index 100% rename from dal/dal/static/datacenterlight/img/bg.png rename to dal/static/datacenterlight/img/bg.png diff --git a/dal/dal/static/datacenterlight/img/cdistbyungleich.png b/dal/static/datacenterlight/img/cdistbyungleich.png similarity index 100% rename from dal/dal/static/datacenterlight/img/cdistbyungleich.png rename to dal/static/datacenterlight/img/cdistbyungleich.png diff --git a/dal/dal/static/datacenterlight/img/checkmark.png b/dal/static/datacenterlight/img/checkmark.png similarity index 100% rename from dal/dal/static/datacenterlight/img/checkmark.png rename to dal/static/datacenterlight/img/checkmark.png diff --git a/dal/dal/static/datacenterlight/img/configure.jpg b/dal/static/datacenterlight/img/configure.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/configure.jpg rename to dal/static/datacenterlight/img/configure.jpg diff --git a/dal/dal/static/datacenterlight/img/datacenterlight.png b/dal/static/datacenterlight/img/datacenterlight.png similarity index 100% rename from dal/dal/static/datacenterlight/img/datacenterlight.png rename to dal/static/datacenterlight/img/datacenterlight.png diff --git a/dal/dal/static/datacenterlight/img/dcl-email-bg.jpg b/dal/static/datacenterlight/img/dcl-email-bg.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/dcl-email-bg.jpg rename to dal/static/datacenterlight/img/dcl-email-bg.jpg diff --git a/dal/dal/static/datacenterlight/img/deluxeroom.jpg b/dal/static/datacenterlight/img/deluxeroom.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/deluxeroom.jpg rename to dal/static/datacenterlight/img/deluxeroom.jpg diff --git a/dal/dal/static/datacenterlight/img/devuan.png b/dal/static/datacenterlight/img/devuan.png similarity index 100% rename from dal/dal/static/datacenterlight/img/devuan.png rename to dal/static/datacenterlight/img/devuan.png diff --git a/dal/dal/static/datacenterlight/img/django.png b/dal/static/datacenterlight/img/django.png similarity index 100% rename from dal/dal/static/datacenterlight/img/django.png rename to dal/static/datacenterlight/img/django.png diff --git a/dal/dal/static/datacenterlight/img/dog.png b/dal/static/datacenterlight/img/dog.png similarity index 100% rename from dal/dal/static/datacenterlight/img/dog.png rename to dal/static/datacenterlight/img/dog.png diff --git a/dal/dal/static/datacenterlight/img/economy.jpg b/dal/static/datacenterlight/img/economy.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/economy.jpg rename to dal/static/datacenterlight/img/economy.jpg diff --git a/dal/dal/static/datacenterlight/img/facebook_logo.svg b/dal/static/datacenterlight/img/facebook_logo.svg similarity index 100% rename from dal/dal/static/datacenterlight/img/facebook_logo.svg rename to dal/static/datacenterlight/img/facebook_logo.svg diff --git a/dal/dal/static/datacenterlight/img/favicon.ico b/dal/static/datacenterlight/img/favicon.ico similarity index 100% rename from dal/dal/static/datacenterlight/img/favicon.ico rename to dal/static/datacenterlight/img/favicon.ico diff --git a/dal/dal/static/datacenterlight/img/header-bg.jpg b/dal/static/datacenterlight/img/header-bg.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/header-bg.jpg rename to dal/static/datacenterlight/img/header-bg.jpg diff --git a/dal/dal/static/datacenterlight/img/home.png b/dal/static/datacenterlight/img/home.png similarity index 100% rename from dal/dal/static/datacenterlight/img/home.png rename to dal/static/datacenterlight/img/home.png diff --git a/dal/dal/static/datacenterlight/img/how.png b/dal/static/datacenterlight/img/how.png similarity index 100% rename from dal/dal/static/datacenterlight/img/how.png rename to dal/static/datacenterlight/img/how.png diff --git a/dal/dal/static/datacenterlight/img/how1.png b/dal/static/datacenterlight/img/how1.png similarity index 100% rename from dal/dal/static/datacenterlight/img/how1.png rename to dal/static/datacenterlight/img/how1.png diff --git a/dal/dal/static/datacenterlight/img/how2.png b/dal/static/datacenterlight/img/how2.png similarity index 100% rename from dal/dal/static/datacenterlight/img/how2.png rename to dal/static/datacenterlight/img/how2.png diff --git a/dal/dal/static/datacenterlight/img/how3.png b/dal/static/datacenterlight/img/how3.png similarity index 100% rename from dal/dal/static/datacenterlight/img/how3.png rename to dal/static/datacenterlight/img/how3.png diff --git a/dal/dal/static/datacenterlight/img/how4.png b/dal/static/datacenterlight/img/how4.png similarity index 100% rename from dal/dal/static/datacenterlight/img/how4.png rename to dal/static/datacenterlight/img/how4.png diff --git a/dal/dal/static/datacenterlight/img/intro-bg.jpg b/dal/static/datacenterlight/img/intro-bg.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/intro-bg.jpg rename to dal/static/datacenterlight/img/intro-bg.jpg diff --git a/dal/dal/static/datacenterlight/img/ipad.png b/dal/static/datacenterlight/img/ipad.png similarity index 100% rename from dal/dal/static/datacenterlight/img/ipad.png rename to dal/static/datacenterlight/img/ipad.png diff --git a/dal/dal/static/datacenterlight/img/loading.gif b/dal/static/datacenterlight/img/loading.gif similarity index 100% rename from dal/dal/static/datacenterlight/img/loading.gif rename to dal/static/datacenterlight/img/loading.gif diff --git a/dal/dal/static/datacenterlight/img/logo_black.png b/dal/static/datacenterlight/img/logo_black.png similarity index 100% rename from dal/dal/static/datacenterlight/img/logo_black.png rename to dal/static/datacenterlight/img/logo_black.png diff --git a/dal/dal/static/datacenterlight/img/logo_black.svg b/dal/static/datacenterlight/img/logo_black.svg similarity index 100% rename from dal/dal/static/datacenterlight/img/logo_black.svg rename to dal/static/datacenterlight/img/logo_black.svg diff --git a/dal/dal/static/datacenterlight/img/logo_white.svg b/dal/static/datacenterlight/img/logo_white.svg similarity index 100% rename from dal/dal/static/datacenterlight/img/logo_white.svg rename to dal/static/datacenterlight/img/logo_white.svg diff --git a/dal/dal/static/datacenterlight/img/opennebula.png b/dal/static/datacenterlight/img/opennebula.png similarity index 100% rename from dal/dal/static/datacenterlight/img/opennebula.png rename to dal/static/datacenterlight/img/opennebula.png diff --git a/dal/dal/static/datacenterlight/img/pattern.jpg b/dal/static/datacenterlight/img/pattern.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/pattern.jpg rename to dal/static/datacenterlight/img/pattern.jpg diff --git a/dal/dal/static/datacenterlight/img/phones.png b/dal/static/datacenterlight/img/phones.png similarity index 100% rename from dal/dal/static/datacenterlight/img/phones.png rename to dal/static/datacenterlight/img/phones.png diff --git a/dal/dal/static/datacenterlight/img/presidentialroom.jpg b/dal/static/datacenterlight/img/presidentialroom.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/presidentialroom.jpg rename to dal/static/datacenterlight/img/presidentialroom.jpg diff --git a/dal/dal/static/datacenterlight/img/prometheus.png b/dal/static/datacenterlight/img/prometheus.png similarity index 100% rename from dal/dal/static/datacenterlight/img/prometheus.png rename to dal/static/datacenterlight/img/prometheus.png diff --git a/dal/dal/static/datacenterlight/img/python-logo.png b/dal/static/datacenterlight/img/python-logo.png similarity index 100% rename from dal/dal/static/datacenterlight/img/python-logo.png rename to dal/static/datacenterlight/img/python-logo.png diff --git a/dal/dal/static/datacenterlight/img/ssd.jpg b/dal/static/datacenterlight/img/ssd.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/ssd.jpg rename to dal/static/datacenterlight/img/ssd.jpg diff --git a/dal/dal/static/datacenterlight/img/standardroom.jpg b/dal/static/datacenterlight/img/standardroom.jpg similarity index 100% rename from dal/dal/static/datacenterlight/img/standardroom.jpg rename to dal/static/datacenterlight/img/standardroom.jpg diff --git a/dal/dal/static/datacenterlight/img/tayga.png b/dal/static/datacenterlight/img/tayga.png similarity index 100% rename from dal/dal/static/datacenterlight/img/tayga.png rename to dal/static/datacenterlight/img/tayga.png diff --git a/dal/dal/static/datacenterlight/img/ubuntu.png b/dal/static/datacenterlight/img/ubuntu.png similarity index 100% rename from dal/dal/static/datacenterlight/img/ubuntu.png rename to dal/static/datacenterlight/img/ubuntu.png diff --git a/dal/dal/static/datacenterlight/js/bootstrap-3.3.7.min.js b/dal/static/datacenterlight/js/bootstrap-3.3.7.min.js similarity index 100% rename from dal/dal/static/datacenterlight/js/bootstrap-3.3.7.min.js rename to dal/static/datacenterlight/js/bootstrap-3.3.7.min.js diff --git a/dal/dal/static/datacenterlight/js/form.js b/dal/static/datacenterlight/js/form.js similarity index 100% rename from dal/dal/static/datacenterlight/js/form.js rename to dal/static/datacenterlight/js/form.js diff --git a/dal/dal/static/datacenterlight/js/jquery-2.2.4.min.js b/dal/static/datacenterlight/js/jquery-2.2.4.min.js similarity index 100% rename from dal/dal/static/datacenterlight/js/jquery-2.2.4.min.js rename to dal/static/datacenterlight/js/jquery-2.2.4.min.js diff --git a/dal/dal/static/datacenterlight/js/main.js b/dal/static/datacenterlight/js/main.js similarity index 100% rename from dal/dal/static/datacenterlight/js/main.js rename to dal/static/datacenterlight/js/main.js diff --git a/dal/dal/static/hosting/card-django.png b/dal/static/hosting/card-django.png similarity index 100% rename from dal/dal/static/hosting/card-django.png rename to dal/static/hosting/card-django.png diff --git a/dal/dal/static/hosting/card-nodejs.png b/dal/static/hosting/card-nodejs.png similarity index 100% rename from dal/dal/static/hosting/card-nodejs.png rename to dal/static/hosting/card-nodejs.png diff --git a/dal/dal/static/hosting/card-rails.png b/dal/static/hosting/card-rails.png similarity index 100% rename from dal/dal/static/hosting/card-rails.png rename to dal/static/hosting/card-rails.png diff --git a/dal/dal/static/hosting/css/commons.css b/dal/static/hosting/css/commons.css similarity index 100% rename from dal/dal/static/hosting/css/commons.css rename to dal/static/hosting/css/commons.css diff --git a/dal/dal/static/hosting/css/dashboard.css b/dal/static/hosting/css/dashboard.css similarity index 100% rename from dal/dal/static/hosting/css/dashboard.css rename to dal/static/hosting/css/dashboard.css diff --git a/dal/dal/static/hosting/css/landing-page.css b/dal/static/hosting/css/landing-page.css similarity index 100% rename from dal/dal/static/hosting/css/landing-page.css rename to dal/static/hosting/css/landing-page.css diff --git a/dal/dal/static/hosting/css/nodejshosting.css b/dal/static/hosting/css/nodejshosting.css similarity index 100% rename from dal/dal/static/hosting/css/nodejshosting.css rename to dal/static/hosting/css/nodejshosting.css diff --git a/dal/dal/static/hosting/css/order.css b/dal/static/hosting/css/order.css similarity index 100% rename from dal/dal/static/hosting/css/order.css rename to dal/static/hosting/css/order.css diff --git a/dal/dal/static/hosting/css/orders.css b/dal/static/hosting/css/orders.css similarity index 100% rename from dal/dal/static/hosting/css/orders.css rename to dal/static/hosting/css/orders.css diff --git a/dal/dal/static/hosting/css/payment.css b/dal/static/hosting/css/payment.css similarity index 100% rename from dal/dal/static/hosting/css/payment.css rename to dal/static/hosting/css/payment.css diff --git a/dal/dal/static/hosting/css/price_calculator.css b/dal/static/hosting/css/price_calculator.css similarity index 100% rename from dal/dal/static/hosting/css/price_calculator.css rename to dal/static/hosting/css/price_calculator.css diff --git a/dal/dal/static/hosting/css/pricing.css b/dal/static/hosting/css/pricing.css similarity index 100% rename from dal/dal/static/hosting/css/pricing.css rename to dal/static/hosting/css/pricing.css diff --git a/dal/dal/static/hosting/css/user_keys.css b/dal/static/hosting/css/user_keys.css similarity index 100% rename from dal/dal/static/hosting/css/user_keys.css rename to dal/static/hosting/css/user_keys.css diff --git a/dal/dal/static/hosting/css/virtual-machine.css b/dal/static/hosting/css/virtual-machine.css similarity index 100% rename from dal/dal/static/hosting/css/virtual-machine.css rename to dal/static/hosting/css/virtual-machine.css diff --git a/dal/dal/static/hosting/django-intro-bg.png b/dal/static/hosting/django-intro-bg.png similarity index 100% rename from dal/dal/static/hosting/django-intro-bg.png rename to dal/static/hosting/django-intro-bg.png diff --git a/dal/dal/static/hosting/img/24-hours-support.svg b/dal/static/hosting/img/24-hours-support.svg similarity index 100% rename from dal/dal/static/hosting/img/24-hours-support.svg rename to dal/static/hosting/img/24-hours-support.svg diff --git a/dal/dal/static/hosting/img/CH_flag.png b/dal/static/hosting/img/CH_flag.png similarity index 100% rename from dal/dal/static/hosting/img/CH_flag.png rename to dal/static/hosting/img/CH_flag.png diff --git a/dal/dal/static/hosting/img/DE_flag.png b/dal/static/hosting/img/DE_flag.png similarity index 100% rename from dal/dal/static/hosting/img/DE_flag.png rename to dal/static/hosting/img/DE_flag.png diff --git a/dal/dal/static/hosting/img/ajax-loader.gif b/dal/static/hosting/img/ajax-loader.gif similarity index 100% rename from dal/dal/static/hosting/img/ajax-loader.gif rename to dal/static/hosting/img/ajax-loader.gif diff --git a/dal/dal/static/hosting/img/auth-bg-sm.jpg b/dal/static/hosting/img/auth-bg-sm.jpg similarity index 100% rename from dal/dal/static/hosting/img/auth-bg-sm.jpg rename to dal/static/hosting/img/auth-bg-sm.jpg diff --git a/dal/dal/static/hosting/img/auth-bg.jpg b/dal/static/hosting/img/auth-bg.jpg similarity index 100% rename from dal/dal/static/hosting/img/auth-bg.jpg rename to dal/static/hosting/img/auth-bg.jpg diff --git a/dal/dal/static/hosting/img/banner-bg copy.jpg b/dal/static/hosting/img/banner-bg copy.jpg similarity index 100% rename from dal/dal/static/hosting/img/banner-bg copy.jpg rename to dal/static/hosting/img/banner-bg copy.jpg diff --git a/dal/dal/static/hosting/img/banner-bg.jpg b/dal/static/hosting/img/banner-bg.jpg similarity index 100% rename from dal/dal/static/hosting/img/banner-bg.jpg rename to dal/static/hosting/img/banner-bg.jpg diff --git a/dal/dal/static/hosting/img/billing.svg b/dal/static/hosting/img/billing.svg similarity index 100% rename from dal/dal/static/hosting/img/billing.svg rename to dal/static/hosting/img/billing.svg diff --git a/dal/dal/static/hosting/img/card-django.png b/dal/static/hosting/img/card-django.png similarity index 100% rename from dal/dal/static/hosting/img/card-django.png rename to dal/static/hosting/img/card-django.png diff --git a/dal/dal/static/hosting/img/card-nodejs.png b/dal/static/hosting/img/card-nodejs.png similarity index 100% rename from dal/dal/static/hosting/img/card-nodejs.png rename to dal/static/hosting/img/card-nodejs.png diff --git a/dal/dal/static/hosting/img/card-rails.png b/dal/static/hosting/img/card-rails.png similarity index 100% rename from dal/dal/static/hosting/img/card-rails.png rename to dal/static/hosting/img/card-rails.png diff --git a/dal/dal/static/hosting/img/checkmark.png b/dal/static/hosting/img/checkmark.png similarity index 100% rename from dal/dal/static/hosting/img/checkmark.png rename to dal/static/hosting/img/checkmark.png diff --git a/dal/dal/static/hosting/img/configure.jpg b/dal/static/hosting/img/configure.jpg similarity index 100% rename from dal/dal/static/hosting/img/configure.jpg rename to dal/static/hosting/img/configure.jpg diff --git a/dal/dal/static/hosting/img/connected.svg b/dal/static/hosting/img/connected.svg similarity index 100% rename from dal/dal/static/hosting/img/connected.svg rename to dal/static/hosting/img/connected.svg diff --git a/dal/dal/static/hosting/img/copy.svg b/dal/static/hosting/img/copy.svg similarity index 100% rename from dal/dal/static/hosting/img/copy.svg rename to dal/static/hosting/img/copy.svg diff --git a/dal/dal/static/hosting/img/dashboard_settings.svg b/dal/static/hosting/img/dashboard_settings.svg similarity index 100% rename from dal/dal/static/hosting/img/dashboard_settings.svg rename to dal/static/hosting/img/dashboard_settings.svg diff --git a/dal/dal/static/hosting/img/delete.svg b/dal/static/hosting/img/delete.svg similarity index 100% rename from dal/dal/static/hosting/img/delete.svg rename to dal/static/hosting/img/delete.svg diff --git a/dal/dal/static/hosting/img/deluxeroom.jpg b/dal/static/hosting/img/deluxeroom.jpg similarity index 100% rename from dal/dal/static/hosting/img/deluxeroom.jpg rename to dal/static/hosting/img/deluxeroom.jpg diff --git a/dal/dal/static/hosting/img/django-intro-bg.png b/dal/static/hosting/img/django-intro-bg.png similarity index 100% rename from dal/dal/static/hosting/img/django-intro-bg.png rename to dal/static/hosting/img/django-intro-bg.png diff --git a/dal/dal/static/hosting/img/dog.png b/dal/static/hosting/img/dog.png similarity index 100% rename from dal/dal/static/hosting/img/dog.png rename to dal/static/hosting/img/dog.png diff --git a/dal/dal/static/hosting/img/economy.jpg b/dal/static/hosting/img/economy.jpg similarity index 100% rename from dal/dal/static/hosting/img/economy.jpg rename to dal/static/hosting/img/economy.jpg diff --git a/dal/dal/static/hosting/img/favicon.ico b/dal/static/hosting/img/favicon.ico similarity index 100% rename from dal/dal/static/hosting/img/favicon.ico rename to dal/static/hosting/img/favicon.ico diff --git a/dal/dal/static/hosting/img/g222.png b/dal/static/hosting/img/g222.png similarity index 100% rename from dal/dal/static/hosting/img/g222.png rename to dal/static/hosting/img/g222.png diff --git a/dal/dal/static/hosting/img/header-bg.jpg b/dal/static/hosting/img/header-bg.jpg similarity index 100% rename from dal/dal/static/hosting/img/header-bg.jpg rename to dal/static/hosting/img/header-bg.jpg diff --git a/dal/dal/static/hosting/img/home.png b/dal/static/hosting/img/home.png similarity index 100% rename from dal/dal/static/hosting/img/home.png rename to dal/static/hosting/img/home.png diff --git a/dal/dal/static/hosting/img/how.png b/dal/static/hosting/img/how.png similarity index 100% rename from dal/dal/static/hosting/img/how.png rename to dal/static/hosting/img/how.png diff --git a/dal/dal/static/hosting/img/how1.png b/dal/static/hosting/img/how1.png similarity index 100% rename from dal/dal/static/hosting/img/how1.png rename to dal/static/hosting/img/how1.png diff --git a/dal/dal/static/hosting/img/how2.png b/dal/static/hosting/img/how2.png similarity index 100% rename from dal/dal/static/hosting/img/how2.png rename to dal/static/hosting/img/how2.png diff --git a/dal/dal/static/hosting/img/how4.png b/dal/static/hosting/img/how4.png similarity index 100% rename from dal/dal/static/hosting/img/how4.png rename to dal/static/hosting/img/how4.png diff --git a/dal/dal/static/hosting/img/icon-pdf.svg b/dal/static/hosting/img/icon-pdf.svg similarity index 100% rename from dal/dal/static/hosting/img/icon-pdf.svg rename to dal/static/hosting/img/icon-pdf.svg diff --git a/dal/dal/static/hosting/img/icon-print.svg b/dal/static/hosting/img/icon-print.svg similarity index 100% rename from dal/dal/static/hosting/img/icon-print.svg rename to dal/static/hosting/img/icon-print.svg diff --git a/dal/dal/static/hosting/img/intro-bg.jpg b/dal/static/hosting/img/intro-bg.jpg similarity index 100% rename from dal/dal/static/hosting/img/intro-bg.jpg rename to dal/static/hosting/img/intro-bg.jpg diff --git a/dal/dal/static/hosting/img/ipad.png b/dal/static/hosting/img/ipad.png similarity index 100% rename from dal/dal/static/hosting/img/ipad.png rename to dal/static/hosting/img/ipad.png diff --git a/dal/dal/static/hosting/img/key.svg b/dal/static/hosting/img/key.svg similarity index 100% rename from dal/dal/static/hosting/img/key.svg rename to dal/static/hosting/img/key.svg diff --git a/dal/dal/static/hosting/img/login-bg.jpg b/dal/static/hosting/img/login-bg.jpg similarity index 100% rename from dal/dal/static/hosting/img/login-bg.jpg rename to dal/static/hosting/img/login-bg.jpg diff --git a/dal/dal/static/hosting/img/logo_black.png b/dal/static/hosting/img/logo_black.png similarity index 100% rename from dal/dal/static/hosting/img/logo_black.png rename to dal/static/hosting/img/logo_black.png diff --git a/dal/dal/static/hosting/img/logo_black.svg b/dal/static/hosting/img/logo_black.svg similarity index 100% rename from dal/dal/static/hosting/img/logo_black.svg rename to dal/static/hosting/img/logo_black.svg diff --git a/dal/dal/static/hosting/img/logo_white.svg b/dal/static/hosting/img/logo_white.svg similarity index 100% rename from dal/dal/static/hosting/img/logo_white.svg rename to dal/static/hosting/img/logo_white.svg diff --git a/dal/dal/static/hosting/img/nodejs-intro-bg.png b/dal/static/hosting/img/nodejs-intro-bg.png similarity index 100% rename from dal/dal/static/hosting/img/nodejs-intro-bg.png rename to dal/static/hosting/img/nodejs-intro-bg.png diff --git a/dal/dal/static/hosting/img/pattern.jpg b/dal/static/hosting/img/pattern.jpg similarity index 100% rename from dal/dal/static/hosting/img/pattern.jpg rename to dal/static/hosting/img/pattern.jpg diff --git a/dal/dal/static/hosting/img/pattern_original.jpg b/dal/static/hosting/img/pattern_original.jpg similarity index 100% rename from dal/dal/static/hosting/img/pattern_original.jpg rename to dal/static/hosting/img/pattern_original.jpg diff --git a/dal/dal/static/hosting/img/phones.png b/dal/static/hosting/img/phones.png similarity index 100% rename from dal/dal/static/hosting/img/phones.png rename to dal/static/hosting/img/phones.png diff --git a/dal/dal/static/hosting/img/plusVM.svg b/dal/static/hosting/img/plusVM.svg similarity index 100% rename from dal/dal/static/hosting/img/plusVM.svg rename to dal/static/hosting/img/plusVM.svg diff --git a/dal/dal/static/hosting/img/presidentialroom.jpg b/dal/static/hosting/img/presidentialroom.jpg similarity index 100% rename from dal/dal/static/hosting/img/presidentialroom.jpg rename to dal/static/hosting/img/presidentialroom.jpg diff --git a/dal/dal/static/hosting/img/rails-intro-bg.png b/dal/static/hosting/img/rails-intro-bg.png similarity index 100% rename from dal/dal/static/hosting/img/rails-intro-bg.png rename to dal/static/hosting/img/rails-intro-bg.png diff --git a/dal/dal/static/hosting/img/settings.svg b/dal/static/hosting/img/settings.svg similarity index 100% rename from dal/dal/static/hosting/img/settings.svg rename to dal/static/hosting/img/settings.svg diff --git a/dal/dal/static/hosting/img/shopping-cart.svg b/dal/static/hosting/img/shopping-cart.svg similarity index 100% rename from dal/dal/static/hosting/img/shopping-cart.svg rename to dal/static/hosting/img/shopping-cart.svg diff --git a/dal/dal/static/hosting/img/signup-bg.png b/dal/static/hosting/img/signup-bg.png similarity index 100% rename from dal/dal/static/hosting/img/signup-bg.png rename to dal/static/hosting/img/signup-bg.png diff --git a/dal/dal/static/hosting/img/standardroom.jpg b/dal/static/hosting/img/standardroom.jpg similarity index 100% rename from dal/dal/static/hosting/img/standardroom.jpg rename to dal/static/hosting/img/standardroom.jpg diff --git a/dal/dal/static/hosting/img/ubuntu.png b/dal/static/hosting/img/ubuntu.png similarity index 100% rename from dal/dal/static/hosting/img/ubuntu.png rename to dal/static/hosting/img/ubuntu.png diff --git a/dal/dal/static/hosting/img/vm.svg b/dal/static/hosting/img/vm.svg similarity index 100% rename from dal/dal/static/hosting/img/vm.svg rename to dal/static/hosting/img/vm.svg diff --git a/dal/dal/static/hosting/js/createvm.js b/dal/static/hosting/js/createvm.js similarity index 100% rename from dal/dal/static/hosting/js/createvm.js rename to dal/static/hosting/js/createvm.js diff --git a/dal/dal/static/hosting/js/gen-ssh-key.js b/dal/static/hosting/js/gen-ssh-key.js similarity index 100% rename from dal/dal/static/hosting/js/gen-ssh-key.js rename to dal/static/hosting/js/gen-ssh-key.js diff --git a/dal/dal/static/hosting/js/html2canvas.min.js b/dal/static/hosting/js/html2canvas.min.js similarity index 100% rename from dal/dal/static/hosting/js/html2canvas.min.js rename to dal/static/hosting/js/html2canvas.min.js diff --git a/dal/dal/static/hosting/js/html2pdf.min.js b/dal/static/hosting/js/html2pdf.min.js similarity index 100% rename from dal/dal/static/hosting/js/html2pdf.min.js rename to dal/static/hosting/js/html2pdf.min.js diff --git a/dal/dal/static/hosting/js/initial.js b/dal/static/hosting/js/initial.js similarity index 100% rename from dal/dal/static/hosting/js/initial.js rename to dal/static/hosting/js/initial.js diff --git a/dal/dal/static/hosting/js/order.js b/dal/static/hosting/js/order.js similarity index 100% rename from dal/dal/static/hosting/js/order.js rename to dal/static/hosting/js/order.js diff --git a/dal/dal/static/hosting/js/payment.js b/dal/static/hosting/js/payment.js similarity index 100% rename from dal/dal/static/hosting/js/payment.js rename to dal/static/hosting/js/payment.js diff --git a/dal/dal/static/hosting/js/pricing.js b/dal/static/hosting/js/pricing.js similarity index 100% rename from dal/dal/static/hosting/js/pricing.js rename to dal/static/hosting/js/pricing.js diff --git a/dal/dal/static/hosting/js/virtual_machine_detail.js b/dal/static/hosting/js/virtual_machine_detail.js similarity index 100% rename from dal/dal/static/hosting/js/virtual_machine_detail.js rename to dal/static/hosting/js/virtual_machine_detail.js diff --git a/dal/dal/static/hosting/nodejs-intro-bg.png b/dal/static/hosting/nodejs-intro-bg.png similarity index 100% rename from dal/dal/static/hosting/nodejs-intro-bg.png rename to dal/static/hosting/nodejs-intro-bg.png diff --git a/dal/dal/static/hosting/rails-intro-bg.png b/dal/static/hosting/rails-intro-bg.png similarity index 100% rename from dal/dal/static/hosting/rails-intro-bg.png rename to dal/static/hosting/rails-intro-bg.png diff --git a/dal/dal/templates/base.html b/dal/templates/base.html similarity index 100% rename from dal/dal/templates/base.html rename to dal/templates/base.html diff --git a/dal/dal/templates/base_short.html b/dal/templates/base_short.html similarity index 100% rename from dal/dal/templates/base_short.html rename to dal/templates/base_short.html diff --git a/dal/dal/templates/changeddata.html b/dal/templates/changeddata.html similarity index 100% rename from dal/dal/templates/changeddata.html rename to dal/templates/changeddata.html diff --git a/dal/dal/templates/changedpassword.html b/dal/templates/changedpassword.html similarity index 100% rename from dal/dal/templates/changedpassword.html rename to dal/templates/changedpassword.html diff --git a/dal/dal/templates/changepassword.html b/dal/templates/changepassword.html similarity index 100% rename from dal/dal/templates/changepassword.html rename to dal/templates/changepassword.html diff --git a/dal/dal/templates/changeuserdata.html b/dal/templates/changeuserdata.html similarity index 100% rename from dal/dal/templates/changeuserdata.html rename to dal/templates/changeuserdata.html diff --git a/dal/dal/templates/deleteaccount.html b/dal/templates/deleteaccount.html similarity index 100% rename from dal/dal/templates/deleteaccount.html rename to dal/templates/deleteaccount.html diff --git a/dal/dal/templates/deleteduser.html b/dal/templates/deleteduser.html similarity index 100% rename from dal/dal/templates/deleteduser.html rename to dal/templates/deleteduser.html diff --git a/dal/dal/templates/error.html b/dal/templates/error.html similarity index 100% rename from dal/dal/templates/error.html rename to dal/templates/error.html diff --git a/dal/dal/templates/hosting_login.html b/dal/templates/hosting_login.html similarity index 100% rename from dal/dal/templates/hosting_login.html rename to dal/templates/hosting_login.html diff --git a/dal/dal/templates/includes/_card_input.html b/dal/templates/includes/_card_input.html similarity index 100% rename from dal/dal/templates/includes/_card_input.html rename to dal/templates/includes/_card_input.html diff --git a/dal/dal/templates/includes/_contact.html b/dal/templates/includes/_contact.html similarity index 100% rename from dal/dal/templates/includes/_contact.html rename to dal/templates/includes/_contact.html diff --git a/dal/templates/includes/_footer.html b/dal/templates/includes/_footer.html new file mode 100644 index 0000000..800f7dc --- /dev/null +++ b/dal/templates/includes/_footer.html @@ -0,0 +1,12 @@ +{% load i18n %} + diff --git a/dal/dal/templates/includes/_header.html b/dal/templates/includes/_header.html similarity index 100% rename from dal/dal/templates/includes/_header.html rename to dal/templates/includes/_header.html diff --git a/dal/dal/templates/includes/_messages.html b/dal/templates/includes/_messages.html similarity index 100% rename from dal/dal/templates/includes/_messages.html rename to dal/templates/includes/_messages.html diff --git a/dal/dal/templates/includes/_navbar.html b/dal/templates/includes/_navbar.html similarity index 100% rename from dal/dal/templates/includes/_navbar.html rename to dal/templates/includes/_navbar.html diff --git a/dal/dal/templates/includes/_navbar_transparent.html b/dal/templates/includes/_navbar_transparent.html similarity index 94% rename from dal/dal/templates/includes/_navbar_transparent.html rename to dal/templates/includes/_navbar_transparent.html index e413ace..1af4bcb 100644 --- a/dal/dal/templates/includes/_navbar_transparent.html +++ b/dal/templates/includes/_navbar_transparent.html @@ -2,7 +2,6 @@ diff --git a/dal/dal/templates/includes/_navbar_user.html b/dal/templates/includes/_navbar_user.html similarity index 100% rename from dal/dal/templates/includes/_navbar_user.html rename to dal/templates/includes/_navbar_user.html diff --git a/dal/dal/templates/includes/_our_infrastructure.html b/dal/templates/includes/_our_infrastructure.html similarity index 100% rename from dal/dal/templates/includes/_our_infrastructure.html rename to dal/templates/includes/_our_infrastructure.html diff --git a/dal/dal/templates/includes/_pricing.html b/dal/templates/includes/_pricing.html similarity index 100% rename from dal/dal/templates/includes/_pricing.html rename to dal/templates/includes/_pricing.html diff --git a/dal/dal/templates/includes/_your_infrastructure.html b/dal/templates/includes/_your_infrastructure.html similarity index 100% rename from dal/dal/templates/includes/_your_infrastructure.html rename to dal/templates/includes/_your_infrastructure.html diff --git a/dal/templates/landing.html b/dal/templates/landing.html new file mode 100644 index 0000000..741fd74 --- /dev/null +++ b/dal/templates/landing.html @@ -0,0 +1,38 @@ +{% extends "base_short.html" %} +{% load i18n staticfiles bootstrap3 %} + + +{% block content %} +
+
+
+
+
+

{% trans "Log in" %}

+ {% include 'includes/_messages.html' %} +
+ {% csrf_token %} + {% for field in form %} + {% bootstrap_field field show_label=False type='fields'%} + {% endfor %} +

{{form.non_field_errors|striptags}}

+
+ +
+ +
+ +
+
+
+
+{% endblock %} diff --git a/dal/dal/templates/loginfailed.html b/dal/templates/loginfailed.html similarity index 100% rename from dal/dal/templates/loginfailed.html rename to dal/templates/loginfailed.html diff --git a/dal/dal/templates/mustbeloggedin.html b/dal/templates/mustbeloggedin.html similarity index 100% rename from dal/dal/templates/mustbeloggedin.html rename to dal/templates/mustbeloggedin.html diff --git a/dal/dal/templates/registeruser.html b/dal/templates/registeruser.html similarity index 100% rename from dal/dal/templates/registeruser.html rename to dal/templates/registeruser.html diff --git a/dal/dal/templates/resetpassword.html b/dal/templates/resetpassword.html similarity index 100% rename from dal/dal/templates/resetpassword.html rename to dal/templates/resetpassword.html diff --git a/dal/dal/templates/resetpasswordnew.html b/dal/templates/resetpasswordnew.html similarity index 100% rename from dal/dal/templates/resetpasswordnew.html rename to dal/templates/resetpasswordnew.html diff --git a/dal/dal/templates/send_resetrequest.html b/dal/templates/send_resetrequest.html similarity index 100% rename from dal/dal/templates/send_resetrequest.html rename to dal/templates/send_resetrequest.html diff --git a/dal/dal/templates/usercreated.html b/dal/templates/usercreated.html similarity index 100% rename from dal/dal/templates/usercreated.html rename to dal/templates/usercreated.html diff --git a/dal/dal/templates/useroptions.html b/dal/templates/useroptions.html similarity index 100% rename from dal/dal/templates/useroptions.html rename to dal/templates/useroptions.html diff --git a/dal/ungleich_ldap.py b/dal/ungleich_ldap.py new file mode 100644 index 0000000..74f102f --- /dev/null +++ b/dal/ungleich_ldap.py @@ -0,0 +1,282 @@ +import base64 +import hashlib +import random + +import ldap3 +from django.conf import settings +import logging + +logger = logging.getLogger(__name__) + + +class LdapManager: + __instance = None + def __new__(cls): + if LdapManager.__instance is None: + LdapManager.__instance = object.__new__(cls) + return LdapManager.__instance + + def __init__(self): + """ + Initialize the LDAP subsystem. + """ + self.rng = random.SystemRandom() + self.server = ldap3.Server(settings.AUTH_LDAP_SERVER) + + + def get_admin_conn(self): + """ + Return a bound :class:`ldap3.Connection` instance which has write + permissions on the dn in which the user accounts reside. + """ + conn = self.get_conn(user=settings.LDAP_ADMIN_DN, + password=settings.LDAP_ADMIN_PASSWORD, + raise_exceptions=True) + conn.bind() + return conn + + + def get_conn(self, **kwargs): + """ + Return an unbound :class:`ldap3.Connection` which talks to the configured + LDAP server. + + The *kwargs* are passed to the constructor of :class:`ldap3.Connection` and + can be used to set *user*, *password* and other useful arguments. + """ + return ldap3.Connection(self.server, **kwargs) + + + def _ssha_password(self, password): + """ + Apply the SSHA password hashing scheme to the given *password*. + *password* must be a :class:`bytes` object, containing the utf-8 + encoded password. + + Return a :class:`bytes` object containing ``ascii``-compatible data + which can be used as LDAP value, e.g. after armoring it once more using + base64 or decoding it to unicode from ``ascii``. + """ + SALT_BYTES = 15 + + sha1 = hashlib.sha1() + salt = self.rng.getrandbits(SALT_BYTES * 8).to_bytes(SALT_BYTES, + "little") + sha1.update(password) + sha1.update(salt) + + digest = sha1.digest() + passwd = b"{SSHA}" + base64.b64encode(digest + salt) + return passwd + + + def create_user(self, user, password, firstname, lastname, email): + conn = self.get_admin_conn() + uidNumber = self._get_max_uid() + 1 + logger.debug("uidNumber={uidNumber}".format(uidNumber=uidNumber)) + user_exists = True + while user_exists: + user_exists, _ = self.check_user_exists( + "", + '(&(objectClass=inetOrgPerson)(objectClass=posixAccount)' + '(objectClass=top)(uidNumber={uidNumber}))'.format( + uidNumber=uidNumber + ) + ) + if user_exists: + logger.debug( + "{uid} exists. Trying next.".format(uid=uidNumber) + ) + uidNumber += 1 + logger.debug("{uid} does not exist. Using it".format(uid=uidNumber)) + self._set_max_uid(uidNumber) + try: + conn.add( + ("uid={uid}," + settings.LDAP_CUSTOMER_DN).format(uid=user), + ["inetOrgPerson", "posixAccount", "ldapPublickey"], + { + "uid": [user.encode("utf-8")], + "sn": [lastname.encode("utf-8")], + "givenName": [firstname.encode("utf-8")], + "cn": ["{} {}".format(firstname, lastname).encode("utf-8")], + "displayName": ["{} {}".format(firstname, lastname).encode("utf-8")], + "uidNumber": [str(uidNumber)], + "gidNumber": [str(settings.LDAP_CUSTOMER_GROUP_ID)], + "loginShell": ["/bin/bash"], + "homeDirectory": ["/home/{}".format(user).encode("utf-8")], + "mail": email.encode("utf-8"), + "userPassword": [self._ssha_password( + password.encode("utf-8") + )] + } + ) + logger.debug('Created user %s %s' % (user.encode('utf-8'), + uidNumber)) + except Exception as ex: + logger.debug('Could not create user %s' % user.encode('utf-8')) + logger.error("Exception: " + str(ex)) + raise Exception(ex) + finally: + conn.unbind() + + + def change_password(self, uid, new_password): + """ + Changes the password of the user identified by user_dn + + :param uid: str The uid that identifies the user + :param new_password: str The new password string + :return: True if password was changed successfully False otherwise + """ + conn = self.get_admin_conn() + + # Make sure the user exists first to change his/her details + user_exists, entries = self.check_user_exists( + uid=uid, + search_base=settings.ENTIRE_SEARCH_BASE + ) + return_val = False + if user_exists: + try: + return_val = conn.modify( + entries[0].entry_dn, + { + "userpassword": ( + ldap3.MODIFY_REPLACE, + [self._ssha_password(new_password.encode("utf-8"))] + ) + } + ) + except Exception as ex: + logger.error("Exception: " + str(ex)) + else: + logger.error("User {} not found".format(uid)) + + conn.unbind() + return return_val + + def change_user_details(self, uid, details): + """ + Updates the user details as per given values in kwargs of the user + identified by user_dn. + + Assumes that all attributes passed in kwargs are valid. + + :param uid: str The uid that identifies the user + :param details: dict A dictionary containing the new values + :return: True if user details were updated successfully False otherwise + """ + conn = self.get_admin_conn() + + # Make sure the user exists first to change his/her details + user_exists, entries = self.check_user_exists( + uid=uid, + search_base=settings.ENTIRE_SEARCH_BASE + ) + + return_val = False + if user_exists: + details_dict = {k: (ldap3.MODIFY_REPLACE, [v.encode("utf-8")]) for + k, v in details.items()} + try: + return_val = conn.modify(entries[0].entry_dn, details_dict) + msg = "success" + except Exception as ex: + msg = str(ex) + logger.error("Exception: " + msg) + finally: + conn.unbind() + else: + msg = "User {} not found".format(uid) + logger.error(msg) + conn.unbind() + return return_val, msg + + def check_user_exists(self, uid, search_filter="", attributes=None, + search_base=settings.LDAP_CUSTOMER_DN): + """ + Check if the user with the given uid exists in the customer group. + + :param uid: str representing the user + :param search_filter: str representing the filter condition to find + users. If its empty, the search finds the user with + the given uid. + :param attributes: list A list of str representing all the attributes + to be obtained in the result entries + :param search_base: str + :return: tuple (bool, [ldap3.abstract.entry.Entry ..]) + A bool indicating if the user exists + A list of all entries obtained in the search + """ + conn = self.get_admin_conn() + entries = [] + try: + result = conn.search( + search_base=search_base, + search_filter=search_filter if len(search_filter)> 0 else + '(uid={uid})'.format(uid=uid), + attributes=attributes + ) + entries = conn.entries + finally: + conn.unbind() + return result, entries + + def delete_user(self, uid): + """ + Deletes the user with the given uid from ldap + + :param uid: str representing the user + :return: True if the delete was successful False otherwise + """ + conn = self.get_admin_conn() + try: + return_val = conn.delete( + ("uid={uid}," + settings.LDAP_CUSTOMER_DN).format(uid=uid), + ) + msg = "success" + except Exception as ex: + msg = str(ex) + logger.error("Exception: " + msg) + return_val = False + finally: + conn.unbind() + return return_val, msg + + def _set_max_uid(self, max_uid): + """ + a utility function to save max_uid value to a file + + :param max_uid: an integer representing the max uid + :return: + """ + with open(settings.LDAP_MAX_UID_FILE_PATH, 'w+') as handler: + handler.write(str(max_uid)) + + def _get_max_uid(self): + """ + A utility function to read the max uid value that was previously set + + :return: An integer representing the max uid value that was previously + set + """ + try: + with open(settings.LDAP_MAX_UID_FILE_PATH, 'r+') as handler: + try: + return_value = int(handler.read()) + except ValueError as ve: + logger.error( + "Error reading int value from {}. {}" + "Returning default value {} instead".format( + settings.LDAP_MAX_UID_PATH, + str(ve), + settings.LDAP_DEFAULT_START_UID + ) + ) + return_value = settings.LDAP_DEFAULT_START_UID + return return_value + except FileNotFoundError as fnfe: + logger.error("File not found : " + str(fnfe)) + return_value = settings.LDAP_DEFAULT_START_UID + logger.error("So, returning UID={}".format(return_value)) + return return_value diff --git a/dal/dal/urls.py b/dal/urls.py similarity index 94% rename from dal/dal/urls.py rename to dal/urls.py index 10875b6..b5f4a3a 100644 --- a/dal/dal/urls.py +++ b/dal/urls.py @@ -16,5 +16,5 @@ urlpatterns = [ path('logout/', LogOut.as_view(), name="logout"), path('reset///', ResetRequest.as_view()), path('reset/', ResetRequest.as_view(), name="reset"), - path('', Index.as_view(), name="index"), -] + path('', Index.as_view(), name="login_index"), +] \ No newline at end of file diff --git a/dal/dal/views.py b/dal/views.py similarity index 62% rename from dal/dal/views.py rename to dal/views.py index 0e8cd19..5d643d2 100644 --- a/dal/dal/views.py +++ b/dal/views.py @@ -1,14 +1,16 @@ # Imports from django from django.shortcuts import render -from django.views.generic import View +from django.views.generic import View, FormView from django.contrib.auth import authenticate, login, logout -from django.contrib.auth.models import User -from django.http import HttpResponse, HttpResponseRedirect +from django.http import HttpResponse from django.core.validators import validate_email, ValidationError from django.urls import reverse_lazy from django.contrib.auth.tokens import PasswordResetTokenGenerator from django.core.mail import EmailMessage +from django.views.decorators.cache import cache_control from .models import ResetToken +from .forms import LoginForm +from .ungleich_ldap import LdapManager # Imports for the extra stuff not in django @@ -18,99 +20,31 @@ from datetime import datetime from random import choice, randint import string -import os - -# Use ldap, like django_auth_backend -import ldap -import ldap.modlist as modlist - from django.conf import settings +from django.contrib.auth.mixins import LoginRequiredMixin +class Index(FormView): + template_name = "landing.html" + form_class = LoginForm + success_url = 'useroptions.html' -class LDAP(object): - def __init__(self): - self.uri = settings.AUTH_LDAP_SERVER_URI - self.user = settings.AUTH_LDAP_BIND_DN - self.password = settings.AUTH_LDAP_BIND_PASSWORD - - # FIXME: take from settings - self.search_base = os.environ['LDAPSEARCH'] - self.search_scope = ldap.SCOPE_SUBTREE - self.search_filter = "objectClass=inetOrgPerson" - - # FIXME: hard coded - self.dn = "uid={{}},{}".format(os.environ['LDAPCREATE']) - self.gid = "10004" - - self.conn = ldap.initialize(self.uri) - if settings.AUTH_LDAP_START_TLS: - self.conn.start_tls_s() - - self.conn.bind_s(self.user, self.password) - - - def check_user_exists(self, username): - exists = False - - result = self.conn.search_s(self.search_base, - self.search_scope, - self.dn.format(username)) - if len(result) > 0: - exists = True - - return exists - - def create_user(self, user, password, firstname, lastname, email): - dn = self.dn.format(user) - attr = { - "objectClass": ["inetOrgPerson".encode("utf-8"), - "posixAccount".encode("utf-8"), - "ldapPublickey".encode("utf-8")], - "uid": [user.encode("utf-8")], - "sn": [lastname.encode("utf-8")], - "givenName": [firstname.encode("utf-8")], - "cn": ["{} {}".format(firstname, lastname).encode("utf-8")], - "displayName": ["{} {}".format(firstname, lastname).encode("utf-8")], - "uidNumber": ["{}".format(self.get_new_uid_number()).encode("utf-8")], - "gidNumber": [self.gid.encode("utf-8")], - "loginShell": ["/bin/bash".encode("utf-8")], - "homeDirectory": ["/home/{}".format(user).encode("utf-8")], - "mail": email.encode("utf-8"), - "userPassword": password.encode("utf-8") - } - - ldif = modlist.addModlist(attr) - - print("just before: {} {}".format(dn, ldif)) - return self.conn.add_s(dn, ldif) - - def get_new_uid_number(self): - uidlist = [0] - - for result in self.conn.search_s(self.search_base, - self.search_scope, - self.search_filter): - if 'uidNumber' in result[1]: - uidlist.append(int(result[1]['uidNumber'][0])) - - return sorted(uidlist)[-1] + 1 - -class Index(View): - def get(self, request): - if request.user.is_authenticated: - return render(request, 'useroptions.html', { 'user': request.user } ) - return render(request, 'landing.html') - - def post(self, request): - username = request.POST.get('username') - password = request.POST.get('password') - pwd = r'%s' % password - user = authenticate(request, username=username, password=pwd) + def form_valid(self, form): + email = form.cleaned_data.get('email') + password = form.cleaned_data.get('password') + user = authenticate(username=email, password=password) if user is not None: - login(request, user) - return render(request, 'useroptions.html', { 'user': user } ) - return render(request, 'loginfailed.html') + login(self.request, user) + return render(self.request, 'useroptions.html', { 'user': user } ) + return render(self.request, 'loginfailed.html') + + @cache_control(no_cache=True, must_revalidate=True, no_store=True) + def get(self, request, *args, **kwargs): + if self.request.user.is_authenticated: + return render(self.request, 'useroptions.html', + { 'user': self.request.user.username } ) + return super(Index, self).get(request, *args, **kwargs) + class Register(View): def get(self, request): @@ -118,8 +52,6 @@ class Register(View): # Someone filled out the register page, do some basic checks and throw it at nameko def post(self, request): - l = LDAP() - service = 'register an user' urlname = 'register' username = request.POST.get('username') @@ -127,9 +59,6 @@ class Register(View): if username == "" or not username: return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'Please supply a username.' } ) - if l.check_user_exists(username): - return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'User already exists.' } ) - password1 = request.POST.get('password1') password2 = request.POST.get('password2') if password1 != password2: @@ -156,7 +85,10 @@ class Register(View): pwd = r'%s' % password1 try: - l.create_user(username, pwd, firstname, lastname, email) + ldap_manager = LdapManager() + ldap_manager.create_user( + username, pwd, firstname, lastname, email + ) except Exception as e: return render(request, 'error.html', { 'urlname': urlname, 'service': service, @@ -164,24 +96,37 @@ class Register(View): return render(request, 'usercreated.html', { 'user': username } ) -class ChangeData(View): +class ChangeData(LoginRequiredMixin, View): + login_url = reverse_lazy('login_index') # provide the form for the change request def get(self, request): urlname = 'change_data' service = 'get default data for logged in user' - if not request.user.is_authenticated: - return render(request, 'mustbeloggedin.html') + user = request.user - login(request, user) - # get basic data (firstname, lastname, email) - with get_pool().next() as rpc: - (state, firstname, lastname, email) = rpc.getuserdata.get_data(str(request.user)) - # If it throws an error, the errormessage gets put into firstname.. not great naming, but works best this way - if state == "error": - return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': firstname } ) - # The template puts the old data as standard in the fields + ldap_manager = LdapManager() + user_exists, entries = ldap_manager.check_user_exists( + uid=user.username, + attributes=['uid', 'givenName', 'sn', 'mail'], + search_base=settings.ENTIRE_SEARCH_BASE + ) + + if user_exists: + return render( + request, + 'changeuserdata.html', + { 'user': user.username, + 'firstname': entries[0].givenName + if entries[0].givenName.value is not None else '', + 'lastname': entries[0].sn + if entries[0].sn.value is not None else '', + 'email': entries[0].mail + if entries[0].mail.value is not None else ''} + ) else: - return render(request, 'changeuserdata.html', { 'user': str(request.user), 'firstname': firstname, 'lastname': lastname, 'email': email } ) + return render(request, 'error.html', + {'urlname': urlname, 'service': service, + 'error': request.user.username}) # get the change request def post(self, request): @@ -189,11 +134,6 @@ class ChangeData(View): service = 'change user data' urlname = 'change_data' - # Only logged in users may change data - if not request.user.is_authenticated: - return render(request, 'mustbeloggedin.html') - - user = str(request.user) firstname = request.POST.get('firstname') lastname = request.POST.get('lastname') email = request.POST.get('email') @@ -209,15 +149,19 @@ class ChangeData(View): validate_email(email) except ValidationError: return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'The supplied email address is invalid.' } ) - # Trying to change the data - with get_pool().next() as rpc: - result = rpc.changeuserdata.change_data(user, firstname, lastname, email) + + ldap_manager = LdapManager() + result, msg = ldap_manager.change_user_details( + uid=request.user.username, + details={"givenName": firstname, "sn": lastname, "mail": email} + ) + # Data change worked - if result == True: - return render(request, 'changeddata.html', { 'user': user, 'firstname': firstname, 'lastname': lastname, 'email': email } ) + if result: + return render(request, 'changeddata.html', { 'user': request.user.username, 'firstname': firstname, 'lastname': lastname, 'email': email } ) # Data change did not work, display error else: - return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': result } ) + return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': msg } ) class ResetPassword(View): @@ -229,32 +173,57 @@ class ResetPassword(View): service = 'send a password reset request' user = request.POST.get('user') # First, check if the user exists - if not check_user_exists(user): - return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'The user does not exist.' } ) - # user exists, so try to get email - with get_pool().next() as rpc: - (state, tmp1, tmp2, email) = rpc.getuserdata.get_data(user) - # Either error with the datalookup or no email provided - if state == "error" or email == 'No email given' or not email: - return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'Unable to retrieve email address for user.' } ) - # Try to send the email out - emailsend = self.email(user, email) - # Email got sent out - if emailsend == True: - return render(request, 'send_resetrequest.html', { 'user': user } ) - # Error while trying to send email + ldap_manager = LdapManager() + user_exists, entries = ldap_manager.check_user_exists( + uid=user, + search_base=settings.ENTIRE_SEARCH_BASE, + attributes=['uid', 'givenName', 'sn', 'mail'] + ) + if user_exists: + # user exists, so try to get email + # with get_pool().next() as rpc: + # (state, tmp1, tmp2, email) = rpc.getuserdata.get_data(user) + # Either error with the datalookup or no email provided + email = entries[0].mail.value + if email is None: + return render( + request, 'error.html', + {'urlname': urlname, 'service': service, + 'error': 'Unable to retrieve email address for user.'} + ) + + base_url = "{0}://{1}".format(self.request.scheme, + self.request.get_host()) + # Try to send the email out + emailsend = self.email(user, email, base_url) + # Email got sent out + if emailsend == True: + return render( + request, 'send_resetrequest.html', {'user': user} + ) + # Error while trying to send email + else: + return render( + request, 'error.html', + {'urlname': urlname, 'service': service, + 'error': emailsend} + ) else: - return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': emailsend } ) + return render( + request, 'error.html', + { 'urlname': urlname, 'service': service, + 'error': 'The user does not exist.' } + ) # Sends an email to the user with the 24h active link for a password reset - def email(self, user, email): + def email(self, user, email, base_url): # getting epoch for the time now in UTC to spare us headache with timezones creationtime = int(datetime.utcnow().timestamp()) # Construct the data for the email - email_from = 'Userservice at ungleich <%s>' % config['EMAIL']['EMAILFROM'] + email_from = settings.EMAIL_FROM_ADDRESS to = ['%s <%s>' % (user, email)] subject = 'Password reset request for %s' % user - link = self.build_reset_link(user, creationtime) + link = self.build_reset_link(user, creationtime, base_url) body = 'This is an automated email which was triggered by a reset request for the user %s. Please do not reply to this email.\n' % user body += 'If you received this email in error, please disregard it. If you get multiple emails like this, please contact us to look into potential abuse.\n' body += 'To reset your password, please follow the link below:\n' @@ -275,9 +244,8 @@ class ResetPassword(View): return result # Builds the reset link for the email and puts the token into the database - def build_reset_link(self, user, epochutc): + def build_reset_link(self, user, epochutc, base_url): # set up the data - host = 'account-staging.ungleich.ch' tokengen = PasswordResetTokenGenerator() # create some noise for use in the tokengenerator pseudouser = PseudoUser() @@ -288,7 +256,7 @@ class ResetPassword(View): newdbentry = ResetToken(user=user, token=token, creation=epochutc) newdbentry.save() # set up the link - link = 'https://%s/reset/%s/%s/' % (host, userpart.decode('utf-8'), token) + link = (base_url + '/reset/%s/%s/') % (userpart.decode('utf-8'), token) return link @@ -311,6 +279,7 @@ class ResetRequest(View): user = b64decode(tmp_user) user_clean = user.decode('utf-8') # set checks_out = True if token is found in database + checks_out = False dbentries = ResetToken.objects.all().filter(user=user_clean) for entry in dbentries: if entry.token == token: @@ -334,7 +303,7 @@ class ResetRequest(View): # get the hidden value of user user = request.POST.get("user") # some checks over the supplied data - if user == "" or not user: + if user == "" or not user or user != self.request.user.username: return render(request, 'error.html', { 'service': service, 'error': 'Something went wrong. Did you use the supplied form?' } ) if password1 == "" or not password1 or password2 == "" or not password2: return render(request, 'error.html', { 'service': service, 'error': 'Please supply a password and confirm it.' } ) @@ -343,11 +312,14 @@ class ResetRequest(View): if len(password1) < 8: return render(request, 'error.html', { 'service': service, 'error': 'The password is too short, please use a longer one. At least 8 characters.' } ) # everything checks out, now change the password - with get_pool().next() as rpc: - pwd = r'%s' % password1 - result = rpc.changepassword.change_password(user, pwd) - # password change successfull - if result == True: + + ldap_manager = LdapManager() + result = ldap_manager.change_password( + user, + password1 + ) + # password change successful + if result: return render(request, 'changedpassword.html', { 'user': user } ) # Something went wrong while changing the password else: @@ -367,8 +339,8 @@ class ResetRequest(View): # The logged in user can change the password here -class ChangePassword(View): - +class ChangePassword(LoginRequiredMixin, View): + login_url = reverse_lazy('login_index') # Presents the page for a logged in user def get(self, request): if not request.user.is_authenticated: @@ -402,12 +374,15 @@ class ChangePassword(View): if len(password1) < 8: return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'The password is too short, please use a longer one. At least 8 characters.' } ) - with get_pool().next() as rpc: - # Trying to change the password - pwd = r'%s' % password1 - result = rpc.changepassword.change_password(user, pwd) + from .ungleich_ldap import LdapManager + ldap_manager = LdapManager() + result = ldap_manager.change_password( + user, + password1 + ) # Password was changed - if result == True: + if result: + logout(request) return render(request, 'changedpassword.html', { 'user': user } ) # Password not changed, instead got some kind of error else: @@ -415,7 +390,8 @@ class ChangePassword(View): # Deletes an account -class DeleteAccount(View): +class DeleteAccount(LoginRequiredMixin, View): + login_url = reverse_lazy('login_index') # Show the basic form for deleting an account def get(self, request): return render(request, 'deleteaccount.html') @@ -428,32 +404,41 @@ class DeleteAccount(View): # Does the user exist? username = request.POST.get('username') - if not check_user_exists(username): - return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'Unknown user.' } ) - - # Do user and password match? - password = request.POST.get('password') - pwd = r'%s' % password - check = authenticate(request, username=username, password=pwd) - if check is None: - return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'Wrong password for user.' } ) - - # Try to delete the user - with get_pool().next() as rpc: - result = rpc.deleteuser.delete_user(username) - # User deleted - if result == True: - logout(request) - return render(request, 'deleteduser.html', { 'user': username } ) - # User not deleted, got some kind of error + ldap_manager = LdapManager() + user_exists, user_details = ldap_manager.check_user_exists(username) + if user_exists and request.user.username == username: + # Do user and password match? + password = request.POST.get('password') + pwd = r'%s' % password + check = authenticate(request, username=username, password=pwd) + if check is None: + return render(request, 'error.html', + {'urlname': urlname, 'service': service, + 'error': 'Wrong password for user.'}) + result = ldap_manager.delete_user(username) + # User deleted + if result: + logout(request) + return render(request, 'deleteduser.html', {'user': username}) + # User not deleted, got some kind of error + else: + return render(request, 'error.html', + {'urlname': urlname, 'service': service, + 'error': result}) else: - return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': result } ) + return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'Unknown user.' } ) # Log out the session class LogOut(View): def get(self, request): logout(request) - return HttpResponse("You have been logged out.", status=200) + return HttpResponse( + "You have been logged out. You will be redirected in 2 seconds." + "", + status=200 + ) diff --git a/dal/dal/wsgi.py b/dal/wsgi.py similarity index 100% rename from dal/dal/wsgi.py rename to dal/wsgi.py diff --git a/logs/.keep b/logs/.keep new file mode 100644 index 0000000..e69de29 diff --git a/dal/manage.py b/manage.py similarity index 100% rename from dal/manage.py rename to manage.py diff --git a/requirements.txt b/requirements.txt index 0767c8c..c68b636 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,7 @@ django django-auth-ldap python-ldap -django-dotenv +django-bootstrap3 +django-filter==2.1.0 +python-decouple +ldap3