*: port to python3, update deps, fix cn mod
parent
934e4ed67d
commit
50dbd3087a
|
@ -7,7 +7,7 @@ RUN set -e -x ;\
|
|||
export DEBIAN_FRONTEND=noninteractive ;\
|
||||
apt-get -y update ;\
|
||||
apt-get -y upgrade ;\
|
||||
apt-get -y install python-dev python-virtualenv build-essential libkrb5-dev libsasl2-dev libldap2-dev libssl-dev krb5-user ;\
|
||||
apt-get -y install python3-dev python3-virtualenv build-essential libkrb5-dev libsasl2-dev libldap2-dev libssl-dev krb5-user ;\
|
||||
rm -rf /var/lib/apt/lists
|
||||
|
||||
COPY krb5.conf /etc/krb5.conf
|
||||
|
@ -21,7 +21,7 @@ USER app
|
|||
COPY requirements.txt /app/requirements.txt
|
||||
|
||||
RUN set -e -x ;\
|
||||
virtualenv /app/venv ;\
|
||||
python3 -m venv /app/venv ;\
|
||||
/app/venv/bin/pip install -r /app/requirements.txt
|
||||
|
||||
COPY --chown=app runserver.py /app/
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
Babel==2.3.4
|
||||
click==6.6
|
||||
Flask==0.11.1
|
||||
Flask-Babel==0.11.1
|
||||
Flask-WTF==0.13.1
|
||||
itsdangerous==0.24
|
||||
Jinja2==2.8
|
||||
MarkupSafe==0.23
|
||||
Babel==2.7.0
|
||||
Click==7.0
|
||||
Flask==1.1.1
|
||||
Flask-Babel==0.12.2
|
||||
Flask-WTF==0.14.2
|
||||
itsdangerous==1.1.0
|
||||
Jinja2==2.10.3
|
||||
kerberos==1.3.0
|
||||
python-ldap==2.4.28
|
||||
pytz==2016.10
|
||||
Werkzeug==0.11.11
|
||||
WTForms==2.1
|
||||
MarkupSafe==1.1.1
|
||||
pyasn1==0.4.7
|
||||
pyasn1-modules==0.2.7
|
||||
python-ldap==3.2.0
|
||||
pytz==2019.3
|
||||
Werkzeug==0.16.0
|
||||
WTForms==2.2.1
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import flask
|
||||
import flask_wtf
|
||||
import wtforms
|
||||
from functools import reduce
|
||||
|
||||
from flask_babel import gettext
|
||||
|
||||
|
@ -35,11 +36,10 @@ def initialize_forms():
|
|||
forms = {}
|
||||
for f in reduce(lambda a,b: a | b, config.can.values()):
|
||||
cls, attrs = config.fields.get(f, config.default_field)
|
||||
class AddForm(flask_wtf.Form):
|
||||
class AddForm(flask_wtf.FlaskForm):
|
||||
value = cls(label=config.readable_names.get(f), **attrs)
|
||||
AddForm.__name__ == 'Add' + f
|
||||
forms[f] = AddForm
|
||||
print f, forms[f]
|
||||
return forms
|
||||
|
||||
@app.before_first_request
|
||||
|
|
|
@ -13,8 +13,8 @@ class Attr(object):
|
|||
self.name = name
|
||||
self.readable_name = config.readable_names.get(name, name)
|
||||
self.value = value
|
||||
self.uid = hashlib.sha1(name + value).hexdigest()
|
||||
def __unicode__(self):
|
||||
self.uid = hashlib.sha1(name.encode('utf-8') + value).hexdigest()
|
||||
def __str__(self):
|
||||
return self.value.decode('utf-8')
|
||||
|
||||
def get_dn():
|
||||
|
@ -41,7 +41,7 @@ def refresh_profile(dn=None):
|
|||
res = conn.search_s(dn, ldap.SCOPE_SUBTREE)
|
||||
assert(len(res) == 1)
|
||||
profile = {}
|
||||
for attr, vs in res[0][1].iteritems():
|
||||
for attr, vs in res[0][1].items():
|
||||
for v in vs:
|
||||
a = Attr(attr, v)
|
||||
profile[a.uid] = a
|
||||
|
|
|
@ -35,10 +35,14 @@ class LRUPool(threading.Thread):
|
|||
time.sleep(self.timeout / 2)
|
||||
self.lock.acquire()
|
||||
now = time.time()
|
||||
drop = set()
|
||||
for k, [c, atime] in self.pool.items():
|
||||
if now - atime > self.timeout:
|
||||
log.info("Pool {} dropping {}.", self, k)
|
||||
self._drop(k)
|
||||
drop.add(k)
|
||||
|
||||
for k in list(drop):
|
||||
self._drop(k)
|
||||
self.lock.release()
|
||||
def register_callback(self, action, cb):
|
||||
self.callbacks.setdefault(action, []).append(cb)
|
||||
|
|
|
@ -18,10 +18,10 @@ def validate(predicate, arg, error='Error!', redirect='/'):
|
|||
return decorator
|
||||
|
||||
def sanitize_perms():
|
||||
config.can = { k: set(map(sanitize_ldap, v)) for k,v in config.can.iteritems() }
|
||||
config.can = { k: set(map(sanitize_ldap, v)) for k,v in config.can.items() }
|
||||
|
||||
def sanitize_readable():
|
||||
config.readable_names = { sanitize_ldap(k): v for k, v in config.readable_names.iteritems() }
|
||||
config.readable_names = { sanitize_ldap(k): v for k, v in config.readable_names.items() }
|
||||
|
||||
def sanitize_ldap(k):
|
||||
k = k.lower()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import urllib
|
||||
|
@ -26,7 +26,7 @@ def login_required(f):
|
|||
if not conn:
|
||||
flask.session.clear()
|
||||
flask.flash('You must log in to continue', category='warning')
|
||||
return flask.redirect('/login?' + urllib.urlencode({'goto': flask.request.path}))
|
||||
return flask.redirect('/login?' + urllib.parse.urlencode({'goto': flask.request.path}))
|
||||
return f(*a, **kw)
|
||||
return func
|
||||
|
||||
|
@ -40,7 +40,7 @@ def api_access(f):
|
|||
return func
|
||||
|
||||
def req_to_ctx():
|
||||
return dict(flask.request.form.iteritems())
|
||||
return dict(flask.request.form.items())
|
||||
|
||||
def str_to_ldap(s):
|
||||
return s.encode('utf-8')
|
||||
|
@ -52,7 +52,7 @@ def attr_op(op, attrName, uid = None, templates=config.std_templates, success_re
|
|||
if uid:
|
||||
attr = context.get_profile()[uid]
|
||||
attrName = attr.name
|
||||
old_value = attr.value
|
||||
old_value = str(attr)
|
||||
form = DelForm() if op == 'del' else app.forms[attrName](value=old_value)
|
||||
form.attr_data = attr
|
||||
if attrName not in config.can[op]:
|
||||
|
@ -64,16 +64,25 @@ def attr_op(op, attrName, uid = None, templates=config.std_templates, success_re
|
|||
admin = attrName in config.admin_required
|
||||
conn = context.get_admin_connection() if admin else context.get_connection()
|
||||
dn = context.get_dn()
|
||||
if op in ['del', 'mod']:
|
||||
|
||||
# Most fields should be modified by remove/add.
|
||||
if op == 'mod' and attrName not in ['commonname']:
|
||||
op = 'modreadd'
|
||||
|
||||
if op in ['del', 'modreadd']:
|
||||
conn.modify_s(dn, [(ldap.MOD_DELETE, attrName, str_to_ldap(old_value))])
|
||||
if op in ['add', 'mod']:
|
||||
if op in ['add', 'modreadd']:
|
||||
conn.modify_s(dn, [(ldap.MOD_ADD, attrName, str_to_ldap(new_value))])
|
||||
|
||||
if op in ['mod']:
|
||||
conn.modify_s(dn, [(ldap.MOD_REPLACE, attrName, str_to_ldap(new_value))])
|
||||
|
||||
context.refresh_profile()
|
||||
return flask.redirect(success_redirect)
|
||||
if form.is_submitted():
|
||||
for field, errors in form.errors.items():
|
||||
for error in errors:
|
||||
flask.flash(u"Error in the %s field - %s" % (
|
||||
flask.flash(u"Error in the {} field - {}".format(
|
||||
getattr(form, field).label.text,
|
||||
error
|
||||
), 'danger')
|
||||
|
@ -82,18 +91,18 @@ def attr_op(op, attrName, uid = None, templates=config.std_templates, success_re
|
|||
return flask.make_response(flask.render_template(templates[op], fatal_redirect=fatal_redirect,
|
||||
attr_op=op, form=form, attr_name=attrName, uid=uid), status)
|
||||
except ldap.LDAPError as e:
|
||||
print e
|
||||
print('LDAP error:', e)
|
||||
flask.flash('Could not modify profile', 'danger')
|
||||
return flask.redirect(fatal_redirect)
|
||||
|
||||
def connect_to_ldap(dn, password):
|
||||
try:
|
||||
return app.connections.bind(dn, password)
|
||||
except ldap.LDAPError, error_message:
|
||||
print "Could not connect to server: %s" % error_message
|
||||
except ldap.LDAPError as error_message:
|
||||
print("Could not connect to server:", error_message)
|
||||
return None
|
||||
|
||||
class DelForm(flask_wtf.Form):
|
||||
class DelForm(flask_wtf.FlaskForm):
|
||||
pass
|
||||
|
||||
@app.route('/login', methods=["GET"])
|
||||
|
@ -135,7 +144,7 @@ def _passwd_ldap(current, new):
|
|||
conn.passwd_s(dn, current. new)
|
||||
return True
|
||||
except ldap.LDAPError as e:
|
||||
print e
|
||||
print('LDAP error:', e)
|
||||
return False
|
||||
|
||||
def _passwd_kadmin(current, new):
|
||||
|
@ -144,7 +153,7 @@ def _passwd_kadmin(current, new):
|
|||
principal_name = config.kadmin_principal_map.format(username)
|
||||
return kerberos.changePassword(principal_name, current, new)
|
||||
except Exception as e:
|
||||
print e
|
||||
print('Kerberos error:', e)
|
||||
logging.exception('kpasswd failed')
|
||||
return False
|
||||
|
||||
|
@ -211,13 +220,13 @@ def claim_nick():
|
|||
try:
|
||||
conn.modify_s(owner, [(ldap.MOD_ADD, config.irc_attr, str_to_ldap(nick))])
|
||||
app.tokens.drop(owner)
|
||||
print 'Token claimed for %s (nick %s, token %s)' % (owner, nick, token)
|
||||
print('Token claimed for {} (nick {}, token {})'.format(owner, nick, token))
|
||||
status = 200
|
||||
error = 'Success'
|
||||
context.refresh_profile(owner)
|
||||
except ldap.LDAPError as e:
|
||||
error = 'Could not claim irc nick, contact an admin'
|
||||
print e
|
||||
print('LDAP Error:', e)
|
||||
res = flask.make_response(error, status)
|
||||
res.mimetype = 'text/plain'
|
||||
return res
|
||||
|
|
Loading…
Reference in New Issue