From f661e9837c1afe78ac8608796d0abee3fe4a5994 Mon Sep 17 00:00:00 2001 From: David Dahl Date: Thu, 26 Oct 2006 19:42:14 +0000 Subject: LDAP auth backend added, more environ/settings/cfg changes git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@2456 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Server/Hostbase/backends.py | 36 ++++ src/lib/Server/Hostbase/hostbase/views.py | 34 +++- .../Hostbase/hostbase/webtemplates/base.html | 7 +- .../Hostbase/hostbase/webtemplates/login.html | 28 ++++ src/lib/Server/Hostbase/ldapauth.py | 21 ++- src/lib/Server/Hostbase/media/base.css | 5 + src/lib/Server/Hostbase/media/boxypastel.css | 184 +++++++++++++++++++++ src/lib/Server/Hostbase/settings.py | 21 ++- src/lib/Server/Hostbase/test/test_ldapauth.py | 10 ++ src/lib/Server/Hostbase/urls.py | 53 +++--- 10 files changed, 360 insertions(+), 39 deletions(-) create mode 100644 src/lib/Server/Hostbase/backends.py create mode 100644 src/lib/Server/Hostbase/hostbase/webtemplates/login.html create mode 100644 src/lib/Server/Hostbase/media/base.css create mode 100644 src/lib/Server/Hostbase/media/boxypastel.css create mode 100644 src/lib/Server/Hostbase/test/test_ldapauth.py (limited to 'src') diff --git a/src/lib/Server/Hostbase/backends.py b/src/lib/Server/Hostbase/backends.py new file mode 100644 index 000000000..36d896a9c --- /dev/null +++ b/src/lib/Server/Hostbase/backends.py @@ -0,0 +1,36 @@ +from django.contrib.auth.models import User +from ldapauth import * + +class LDAPBackend(object): + + def authenticate(self,username=None,password=None): + try: + + l = ldapauth(username,password) + temp_pass = User.objects.make_random_password(100) + ldap_user = dict(username=l.sAMAccountName, + ) + user_session_obj = dict( + email=l.email, + first_name=l.name_f, + last_name=l.name_l, + uid=l.badge_no + ) + #fixme: need to add this user session obj to session + #print str(ldap_user) + user,created = User.objects.get_or_create(username=username) + #print user + #print "created " + str(created) + return user + + except LDAPAUTHError,e: + #print str(e) + return None + + def get_user(self,user_id): + try: + return User.objects.get(pk=user_id) + except User.DoesNotExist, e: + print str(e) + return None + diff --git a/src/lib/Server/Hostbase/hostbase/views.py b/src/lib/Server/Hostbase/hostbase/views.py index b37d5df83..1822e2823 100644 --- a/src/lib/Server/Hostbase/hostbase/views.py +++ b/src/lib/Server/Hostbase/hostbase/views.py @@ -5,13 +5,16 @@ Also has does form validation """ from django.http import HttpResponse, HttpResponseRedirect + +from django.contrib.auth.decorators import login_required + from Hostbase.hostbase.models import * from datetime import date from django.db import connection from django.shortcuts import render_to_response from Hostbase import settings, regex import re - + attribs = ['hostname', 'whatami', 'netgroup', 'security_class', 'support', 'csi', 'printq', 'primary_user', 'administrator', 'location', 'status'] @@ -52,7 +55,11 @@ dispatch = {'mac_addr':'i.mac_addr LIKE \'%%%%%s%%%%\'', def login(request): - return render_to_response('login.html', {}) + return render_to_response('login.html', {'next':'/hostbase'}) + + + + def search(request): """Search for hosts in the database @@ -100,6 +107,7 @@ def search(request): 'DNS_CHOICES': Name.DNS_CHOICES, 'yesno': [(1, 'yes'), (0, 'no')]}) + def look(request, host_id): """Displays general host information""" host = Host.objects.get(id=host_id) @@ -852,3 +860,25 @@ def zonenew(request): 'mxs': range(0,2), 'addresses': range(0,2) }) + +if settings.CFG_TYPE == 'environ': + #login required stuff + search = login_required(search) + look = login_required(look) + dns = login_required(dns) + gethostdata = login_required(gethostdata) + fill = login_required(fill) + edit = login_required(edit) + confirm = login_required(confirm) + dnsedit = login_required(dnsedit) + new = login_required(new) + remove = login_required(remove) + validate = login_required(validate) + zones = login_required(zones) + zoneview = login_required(zoneview) + zoneedit = login_required(zoneedit) + zonenew = login_required(zonenew) + +else: + pass + diff --git a/src/lib/Server/Hostbase/hostbase/webtemplates/base.html b/src/lib/Server/Hostbase/hostbase/webtemplates/base.html index 04c519717..0c556bd77 100644 --- a/src/lib/Server/Hostbase/hostbase/webtemplates/base.html +++ b/src/lib/Server/Hostbase/hostbase/webtemplates/base.html @@ -3,9 +3,10 @@ {% block title %}BCFG2 - Hostbase{% endblock %} - - - {% block extra_header_info %}{% endblock %} diff --git a/src/lib/Server/Hostbase/hostbase/webtemplates/login.html b/src/lib/Server/Hostbase/hostbase/webtemplates/login.html new file mode 100644 index 000000000..d66e1f229 --- /dev/null +++ b/src/lib/Server/Hostbase/hostbase/webtemplates/login.html @@ -0,0 +1,28 @@ +{% extends "base.html" %} +{% block pagebanner %} +
+

Login to Hostbase!

+

You must login to manage hosts

+
+
+{% endblock %} +{% block content %} + {% if form.has_errors %} + {{ form.username.errors|join:", " }} +

Login Failed.

+ {% endif %} + {% if user.is_authenticated %} +

Welcome, {{ user.username }}. Thanks for logging in.

+ {% else %} +

Welcome, user. Please log in.

+
+ +
+ +
+ + + +
+ {% endif %} +{% endblock %} diff --git a/src/lib/Server/Hostbase/ldapauth.py b/src/lib/Server/Hostbase/ldapauth.py index 904e2919e..1dc563368 100644 --- a/src/lib/Server/Hostbase/ldapauth.py +++ b/src/lib/Server/Hostbase/ldapauth.py @@ -114,13 +114,20 @@ class ldapauth(object): try: raw_obj = user_obj[0][1] self.memberOf = raw_obj['memberOf'] - self.sAMAccountName = raw_obj['sAMAccountName'] - self.distinguishedName = raw_obj['distinguishedName'] - self.telephoneNumber = raw_obj['telephoneNumber'] - self.title = raw_obj['title'] - self.department = raw_obj['department'] - self.mail = raw_obj['mail'] - self.badge_no = raw_obj['extensionAttribute1'] + self.sAMAccountName = raw_obj['sAMAccountName'][0] + self.distinguishedName = raw_obj['distinguishedName'][0] + self.telephoneNumber = raw_obj['telephoneNumber'][0] + self.title = raw_obj['title'][0] + self.department = raw_obj['department'][0] + self.mail = raw_obj['mail'][0] + self.badge_no = raw_obj['extensionAttribute1'][0] + self.email = raw_obj['extensionAttribute2'][0] + display_name = raw_obj['displayName'][0].split(",") + self.name_f = raw_obj['givenName'][0] + self.name_l = display_name[0] + self.is_staff = False + self.is_superuser = False + return except KeyError, e: raise LDAPAUTHError("Portions of the LDAP User profile not present") diff --git a/src/lib/Server/Hostbase/media/base.css b/src/lib/Server/Hostbase/media/base.css new file mode 100644 index 000000000..25b00cc62 --- /dev/null +++ b/src/lib/Server/Hostbase/media/base.css @@ -0,0 +1,5 @@ + +/* Import other styles */ +@import url('global.css'); +@import url('layout.css'); +@import url('boxypastel.css); \ No newline at end of file diff --git a/src/lib/Server/Hostbase/media/boxypastel.css b/src/lib/Server/Hostbase/media/boxypastel.css new file mode 100644 index 000000000..73362c29a --- /dev/null +++ b/src/lib/Server/Hostbase/media/boxypastel.css @@ -0,0 +1,184 @@ +body { + background-color: #fff; + color: #000; + font: 12px 'Lucida Grande', Arial, Helvetica, sans-serif; + margin-left:25px; + margin-right:100px; +} +/* links */ +a:link { + color: #00f; + text-decoration: none; +} +a:visited { + color: #00a; + text-decoration: none; +} +a:hover { + color: #00a; + text-decoration: underline; +} +a:active { + color: #00a; + + text-decoration: underline; +} +/* divs*/ +div.bad { + border: 1px solid #660000; + background: #FF6A6A; + margin: 10px 0; + padding: 8px; + text-align: left; + margin-left:50px; + margin-right:50px; +} +div.modified { + border: 1px solid #CC9900; + background: #FFEC8B; + margin: 10px 0; + padding: 8px; + text-align: left; + margin-left:50px; + margin-right:50px; +} +div.clean { + + border: 1px solid #006600; + background: #9AFF9A; + margin: 10px 0; + padding: 8px; + text-align: left; + margin-left:50px; + margin-right:50px; +} +div.extra { + border: 1px solid #006600; + background: #6699CC; + margin: 10px 0; + padding: 8px; + text-align: left; + margin-left:50px; + margin-right:50px; +} +div.warning { + border: 1px + solid #CC3300; + background: #FF9933; + margin: 10px 0; + padding: 8px; + text-align: left; + margin-left:50px; + margin-right:50px; +} +div.all-warning { + border: 1px solid #DD5544; + background: #FFD9A2; + margin: 10px 0; + padding: 8px; + text-align: left; + margin-left:50px; + margin-right:50px; +} +div.down { + border: 1px + solid #999; + background-color: #DDD; + margin: 10px 0; + padding: 8px; + text-align: left; + margin-left:50px; + margin-right:50px; +} +div.items{ + display: none; +} +div.nodebox { + border: 1px solid #c7cfd5; + background: #f1f5f9; + margin: 20px 0; + padding: 8px 8px 16px 8px; + text-align: left; + position:relative; +} +div.header { + + background-color: #DDD; + padding: 8px; + text-indent:50px; + position:relative; +} + +/*Spans*/ +.nodename { + font-style: italic; +} +.nodelisttitle { + font-size: 14px; +} + +h2{ + font-size: 16px; + color: #000; +} + +ul.plain { + list-style-type:none; + text-align: left; +} + +.notebox { + position: absolute; + top: 0px; + + right: 0px; + padding: 1px; + text-indent:0px; + border: 1px solid #FFF; + background: #999; + color: #FFF; +} + +.configbox { + position: absolute; + bottom: 0px; + right: 0px; + padding: 1px; + text-indent:0px; + border: 1px solid #999; + background: #FFF; + color: #999; +} + +p.indented{ + text-indent: 50px +} + +/* + Sortable tables */ +table.sortable a.sortheader { + background-color:#dfd; + font-weight: bold; + text-decoration: none; + display: block; + +} +table.sortable { + padding: 2px 4px 2px 4px; + border: 1px solid #000000; + border-spacing: 0px +} +td.sortable{ + padding: 2px 8px 2px 8px; +} + +th.sortable{ + background-color:#F3DD91; + border: 1px solid #FFFFFF; +} +tr.tablelist { + background-color:#EDF3FE; +} +tr.tablelist-alt{ + background-color:#FFFFFF; +} diff --git a/src/lib/Server/Hostbase/settings.py b/src/lib/Server/Hostbase/settings.py index da8f625ca..bdde3619a 100644 --- a/src/lib/Server/Hostbase/settings.py +++ b/src/lib/Server/Hostbase/settings.py @@ -5,7 +5,7 @@ ADMINS = ( # ('Your Name', 'your_email@domain.com'), ) MANAGERS = ADMINS -CFG_TYPE = 'mcs' +CFG_TYPE = 'environ' if CFG_TYPE == 'mcs': # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. @@ -23,11 +23,14 @@ if CFG_TYPE == 'mcs': # Local time zone for this installation. All choices can be found here: # http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE TIME_ZONE = 'America/Chicago' + # Absolute path to the directory that holds media. + # Example: "/home/media/media.lawrence.com/" + MEDIA_ROOT = '' if CFG_TYPE == 'environ': import os # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. - DATABASE_ENGINE = os.envoiron['bcfg_db_engine'] + DATABASE_ENGINE = os.environ['bcfg_db_engine'] # Or path to database file if using sqlite3. DATABASE_NAME = os.environ['bcfg_db_name'] # Not used with sqlite3. @@ -41,15 +44,21 @@ if CFG_TYPE == 'environ': # Local time zone for this installation. All choices can be found here: # http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE TIME_ZONE = os.environ['bcfg_time_zone'] - + # Absolute path to the directory that holds media. + # Example: "/home/media/media.lawrence.com/" + MEDIA_ROOT = os.environ['bcfg_media_root'] + #add non-default AUTH Backends: + AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', + 'Hostbase.backends.LDAPBackend',) + #create login url area: + import django.contrib.auth + django.contrib.auth.LOGIN_URL = '/login' + # Language code for this installation. All choices can be found here: # http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes # http://blogs.law.harvard.edu/tech/stories/storyReader$15 LANGUAGE_CODE = 'en-us' SITE_ID = 1 -# Absolute path to the directory that holds media. -# Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = '' # URL that handles the media served from MEDIA_ROOT. # Example: "http://media.lawrence.com" MEDIA_URL = '' diff --git a/src/lib/Server/Hostbase/test/test_ldapauth.py b/src/lib/Server/Hostbase/test/test_ldapauth.py new file mode 100644 index 000000000..7fc009ad2 --- /dev/null +++ b/src/lib/Server/Hostbase/test/test_ldapauth.py @@ -0,0 +1,10 @@ +import os,sys +import harness + +from Hostbase.ldapauth import * + +def test_it(): + l = ldapauth(os.environ['LDAP_SVC_ACCT_NAME'], + os.environ['LDAP_SVC_ACCT_PASS']) + + assert l.department == 'foo' diff --git a/src/lib/Server/Hostbase/urls.py b/src/lib/Server/Hostbase/urls.py index 6ff12c631..67ff1a308 100644 --- a/src/lib/Server/Hostbase/urls.py +++ b/src/lib/Server/Hostbase/urls.py @@ -1,24 +1,35 @@ +import os from django.conf.urls.defaults import * urlpatterns = patterns('Hostbase.hostbase.views', - # Example: - # (r'^djangobase/', include('djangobase.apps.foo.urls.foo')), - - # Uncomment this for admin: - (r'^admin/', include('django.contrib.admin.urls')), - (r'^hostbase/$', 'search'), - (r'^hostbase/(?P\d+)/$', 'look'), - (r'^hostbase/(?P\d+)/edit', 'edit'), - (r'^hostbase/(?P\d+)/remove', 'remove'), - (r'^hostbase/(?P\d+)/(?P\D+)/(?P\d+)/confirm', 'confirm'), - (r'^hostbase/(?P\d+)/(?P\D+)/(?P\d+)/(?P\d+)/confirm', 'confirm'), - (r'^hostbase/(?P\d+)/dns/edit', 'dnsedit'), - (r'^hostbase/(?P\d+)/dns', 'dns'), - (r'^hostbase/new', 'new'), - (r'^hostbase/hostinfo', 'hostinfo'), - (r'^hostbase/zones/$', 'zones'), - (r'^hostbase/zones/(?P\d+)/$', 'zoneview'), - (r'^hostbase/zones/(?P\d+)/edit', 'zoneedit'), - (r'^hostbase/zones/new/$', 'zonenew'), - (r'^hostbase/zones/(?P\d+)/(?P\D+)/(?P\d+)/confirm', 'confirm'), - ) + + (r'^admin/', include('django.contrib.admin.urls')), + (r'^hostbase/$', 'search'), + (r'^hostbase/(?P\d+)/$', 'look'), + (r'^hostbase/(?P\d+)/edit', 'edit'), + (r'^hostbase/(?P\d+)/remove', 'remove'), + (r'^hostbase/(?P\d+)/(?P\D+)/(?P\d+)/confirm', 'confirm'), + (r'^hostbase/(?P\d+)/(?P\D+)/(?P\d+)/(?P\d+)/confirm', 'confirm'), + (r'^hostbase/(?P\d+)/dns/edit', 'dnsedit'), + (r'^hostbase/(?P\d+)/dns', 'dns'), + (r'^hostbase/new', 'new'), + (r'^hostbase/hostinfo', 'hostinfo'), + (r'^hostbase/zones/$', 'zones'), + (r'^hostbase/zones/(?P\d+)/$', 'zoneview'), + (r'^hostbase/zones/(?P\d+)/edit', 'zoneedit'), + (r'^hostbase/zones/new/$', 'zonenew'), + (r'^hostbase/zones/(?P\d+)/(?P\D+)/(?P\d+)/confirm', 'confirm')) + #(r'^login/$', 'login'), +#fixme: this is a temp. kludge to handle static serving of css, img, js etc... +#a better solution is to use mod_python/apache directives for the static serving +urlpatterns += patterns('', + (r'^site_media/(.*)$', + 'django.views.static.serve', + {'document_root': os.environ['bcfg_media_root'], + 'show_indexes': True}), + ) +urlpatterns += patterns('', + (r'^login/$', 'django.contrib.auth.views.login', + {'template_name': 'login.html'}), + ) + -- cgit v1.2.3-1-g7c22