| |
@@ -1,6 +1,8 @@
|
| |
import os
|
| |
import base64
|
| |
+ import configparser
|
| |
import copy
|
| |
+ import sys
|
| |
|
| |
from cryptography.fernet import Fernet
|
| |
from cryptography.hazmat.backends import default_backend
|
| |
@@ -12,26 +14,36 @@
|
| |
from lib389 import DirSrv
|
| |
from lib389.idm.account import Accounts
|
| |
from lib389.idm.user import nsUserAccounts
|
| |
+ from lib389._mapped_object import _gen_or, _gen_filter, _term_gen
|
| |
|
| |
app = Flask(__name__)
|
| |
|
| |
- # Set the secret key to some random bytes. Keep this really secret!
|
| |
- app.secret_key = os.urandom(16)
|
| |
- # app.secret_key = b'\xb5\x97\x93~!t\x97\r\x1e\xfd\xea\xf8\xe9\xd5\x91\xb0'
|
| |
+ config = configparser.ConfigParser()
|
| |
+ config.read('config.ini')
|
| |
|
| |
- # url_for('static', filename='css/bootstrap.min.css')
|
| |
- # url_for('static', filename='js/bootstrap.min.js')
|
| |
- # url_for('static', filename='js/jquery-3.3.1.slim.min.js')
|
| |
- # url_for('static', filename='js/popper.min.js')
|
| |
+ # Validate we have all our needed keys here ...
|
| |
+ if not config.has_option('dsportal', 'ldapurl'):
|
| |
+ app.logger.error("Missing config.ini option dsportal:ldapurl\n")
|
| |
+ raise Exception("Missing config.ini option dsportal:ldapurl")
|
| |
+ if not config.has_option('dsportal', 'basedn'):
|
| |
+ app.logger.error("Missing config.ini option dsportal:basedn\n")
|
| |
+ raise Exception("Missing config.ini option dsportal:basedn")
|
| |
+ if not config.has_option('dsportal', 'fernet_cookie_key'):
|
| |
+ app.logger.error("Missing config.ini option dsportal:fernet_cookie_key\n")
|
| |
+ raise Exception("Missing config.ini option dsportal:fernet_cookie_key")
|
| |
+ if not config.has_option('dsportal', 'cookie_signing_key'):
|
| |
+ app.logger.error("Missing config.ini option dsportal:cookie_signing_key\n")
|
| |
+ raise Exception("Missing config.ini option dsportal:cookie_signing_key")
|
| |
+
|
| |
+
|
| |
+ app.secret_key = base64.b64decode(config['dsportal']['cookie_signing_key'])
|
| |
|
| |
CONFIG = {
|
| |
- 'ldapurl': 'ldapi://%2fdata%2frun%2fslapd-localhost.socket',
|
| |
- 'basedn': 'ou=People,dc=example,dc=com',
|
| |
- # Find a way to load this from env better so it can be shared correctly.
|
| |
- 'cookie_key': os.urandom(64),
|
| |
+ 'ldapurl': config['dsportal']['ldapurl'],
|
| |
+ 'basedn': config['dsportal']['basedn'],
|
| |
+ 'cookie_key': base64.b64decode(config['dsportal']['fernet_cookie_key'])
|
| |
}
|
| |
|
| |
-
|
| |
KDF = PBKDF2HMAC(
|
| |
algorithm=hashes.SHA256(),
|
| |
length=32,
|
| |
@@ -42,55 +54,24 @@
|
| |
COOKIE_KEY = base64.urlsafe_b64encode(KDF.derive(CONFIG['cookie_key']))
|
| |
FERNET = Fernet(COOKIE_KEY)
|
| |
|
| |
+ ACCOUNT = {
|
| |
+ 'class': config['account']['class'],
|
| |
+ 'name_attr': config['account']['name_attr'],
|
| |
+ 'attributes': config['account']['attributes'].split(),
|
| |
+ }
|
| |
+
|
| |
DISPLAY_ATTRS = [
|
| |
{
|
| |
- "a": "uid",
|
| |
- "multi": "true",
|
| |
- "edit": "false",
|
| |
- },
|
| |
- {
|
| |
- "a": "uidNumber",
|
| |
- "multi": "false",
|
| |
- "edit": "false",
|
| |
- },
|
| |
- {
|
| |
- "a": "gidNumber",
|
| |
- "multi": "false",
|
| |
- "edit": "false",
|
| |
- },
|
| |
- {
|
| |
- "a": "homeDirectory",
|
| |
- "multi": "false",
|
| |
- "edit": "false",
|
| |
- },
|
| |
- {
|
| |
- "a": "mail",
|
| |
- "multi": "true",
|
| |
- "edit": "false",
|
| |
- },
|
| |
- {
|
| |
- "a": "displayName",
|
| |
- "multi": "false",
|
| |
- "edit": "true",
|
| |
- },
|
| |
- {
|
| |
- "a": "legalName",
|
| |
- "multi": "false",
|
| |
- "edit": "true",
|
| |
- },
|
| |
- {
|
| |
- "a": "loginShell",
|
| |
- "multi": "false",
|
| |
- "edit": "false",
|
| |
- },
|
| |
- {
|
| |
- "a": "nsSshPublicKey",
|
| |
- "multi": "true",
|
| |
- "edit": "true",
|
| |
- },
|
| |
+ # Split attr.name to name.
|
| |
+ "a": sect.split('.', 1)[1],
|
| |
+ "multi": config[sect].getboolean("multivalue"),
|
| |
+ "edit": config[sect].getboolean("editable"),
|
| |
+ }
|
| |
+ for sect in config.sections()
|
| |
+ if sect.startswith('attr.') and sect.split('.', 1)[1] in ACCOUNT['attributes']
|
| |
]
|
| |
|
| |
- GET_DISPLAY_ATTRS = [ x["a"] for x in DISPLAY_ATTRS ]
|
| |
+ GET_DISPLAY_ATTRS = ACCOUNT['attributes']
|
| |
|
| |
def _get_ds_instance(ldapurl, binddn, password):
|
| |
inst = DirSrv(verbose=True)
|
| |
@@ -103,7 +84,10 @@
|
| |
# Use the idm account module.
|
| |
accounts = Accounts(inst, basedn)
|
| |
# Use the filter type
|
| |
- cands = accounts.filter(f'(|(cn={name})(uid={name}))')
|
| |
+ filt = _gen_or(
|
| |
+ _gen_filter(ACCOUNT['attributes'], _term_gen(name))
|
| |
+ )
|
| |
+ cands = accounts.filter(filt)
|
| |
# Check there is only one?
|
| |
if len(cands) == 0:
|
| |
raise
|
| |
@@ -142,7 +126,7 @@
|
| |
# TODO: Put a session invalid message here.
|
| |
return redirect(url_for('login'))
|
| |
|
| |
- print("Got: %s" % request.json)
|
| |
+ app.logger.debug("Got: %s" % request.json)
|
| |
|
| |
# Transform the request to the state dict expected by lib389
|
| |
state = {}
|
| |
@@ -280,6 +264,7 @@
|
| |
try:
|
| |
inst.open()
|
| |
except Exception as e:
|
| |
+ app.logger.debug('open()')
|
| |
app.logger.debug(e)
|
| |
return redirect(url_for('error'))
|
| |
|
| |
@@ -293,6 +278,7 @@
|
| |
vs = avas[x["a"]]
|
| |
x.update({"v": vs})
|
| |
except Exception as e:
|
| |
+ app.logger.debug("Error during update of details")
|
| |
app.logger.debug(e)
|
| |
return redirect(url_for('error'))
|
| |
|
| |
@@ -324,6 +310,7 @@
|
| |
session['token'] = token
|
| |
return redirect(url_for('index'))
|
| |
except Exception as e:
|
| |
+ app.logger.debug('login')
|
| |
app.logger.debug(e)
|
| |
return redirect(url_for('error'))
|
| |
return render_template('login.html')
|
| |
Bug Description: Many sites will want to allow customising
their portal experience by changing what attributes "can" and
"can not" be edited, what is displayed, and of course the
basedn of the site.
Fix Description: Allow limited configuration of the instance
via a config.ini file.
https://pagure.io/389-ds-portal/issue/2
Author: William Brown william@blackhats.net.au
Review by: ???