LDAP integration

master
q3k 2015-01-04 17:21:31 +01:00
parent d87af22d53
commit 7c01d4ae0d
4 changed files with 83 additions and 5 deletions

55
webapp/directory.py Normal file
View File

@ -0,0 +1,55 @@
"""An API to retrieve and set data in the Warsaw Hackerspce LDAP tree."""
import ldap
from flask import g
from webapp import mc, cache_enabled, app
def connect():
c = ldap.initialize(app.config['LDAP_URI'])
c.start_tls_s()
c.simple_bind_s(app.config['LDAP_BIND_DN'],
app.config['LDAP_BIND_PASSWORD'])
return c
@app.before_request
def _setup_ldap():
g.ldap = connect()
@app.teardown_request
def _destroy_ldap(exception=None):
g.ldap.unbind_s()
def get_member_fields(c, member, fields):
if isinstance(fields, str):
fields = [fields,]
fields_needed = set(fields)
fields_out = {}
if cache_enabled:
for field in fields:
field_cache = mc.get('kasownik-ldap-member-{}/{}'
.format(member, field))
if field_cache is not None:
fields_out[field] = field_cache
fields_needed.remove(field)
member = member.replace('(', '').replace(')', '')
lfilter = '(&(uid={}){})'.format(member, app.config['LDAP_USER_FILTER'])
data = c.search_s(app.config['LDAP_USER_BASE'], ldap.SCOPE_SUBTREE,
lfilter, tuple(fields))
for dn, obj in data:
for k, v in obj.iteritems():
v = v[0].decode('utf-8')
if k in fields_needed:
fields_out[k] = v
if cache_enabled:
mc.set('kasownik-ldap-member-{}/{}'
.format(member, field), v)
for k in fields_needed - set(fields_out.keys()):
fields_out[k] = None
return fields_out

View File

@ -7,8 +7,11 @@ import json
import re
from sqlalchemy.orm import subqueryload_all
from flask import g
from webapp import app, db, mc, cache_enabled
import directory
class APIKey(db.Model):
@ -177,6 +180,22 @@ class Member(db.Model):
self._apply_judgement(status)
return status
def get_list_email(self):
if self.preferred_email:
return self.preferred_email
return '{}@hackerspace.pl'.format(self.ldap_username)
def get_contact_email(self):
if self.preferred_email:
return self.preferred_email
mra = directory.get_member_fields(g.ldap, self.ldap_username,
'mailRoutingAddress')
mra = mra['mailRoutingAddress']
if mra:
return mra
else:
return '{}@hackerspace.pl'.format(self.ldap_username)
def get_status(self):
"""It's better to call this after doing a full select of data."""

View File

@ -4,8 +4,9 @@
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-4">
<h1>{{member.ldap_username}}</h1>
<div class="col-md-3">
<h1>{{member.ldap_username}}{%if cn %}<br /><small>{{cn}}</small>{% endif%}</h1>
<h5>{{member.get_contact_email()}}</h5>
<p>
{% if status.judgement %}
<span class="label label-success">Active</span><br/><br/>
@ -18,7 +19,7 @@
<h4>Membership Type</h4>
{% include "button_membership_type.html" %}
</div>
<div class="col-md-8">
<div class="col-md-9">
<h3>Judgement Engine™</h3>
<p>
{%if status.last_paid[0] == None %}

View File

@ -9,9 +9,10 @@ from subprocess import Popen, PIPE
from webapp import app, forms, User, db, models, mc, cache_enabled
from flask.ext.login import login_user, login_required, logout_user
from flask import request, redirect, flash, render_template, url_for, abort
from flask import request, redirect, flash, render_template, url_for, abort, g
import banking
import logic
import directory
@app.route('/')
@ -156,7 +157,9 @@ def admin_member(username):
if not member:
abort(404)
status = member.get_status()
return render_template("admin_member.html", member=member, status=status)
cn = directory.get_member_fields(g.ldap, member.ldap_username, 'cn')['cn']
return render_template("admin_member.html", member=member, status=status,
cn=cn)
@app.route("/add/<type>/<username>")
@login_required