From 25db119d02f2a0073d41b6cb451b416948e16cfa Mon Sep 17 00:00:00 2001 From: Erik Weber Date: Fri, 3 Jul 2020 08:55:31 +0200 Subject: [PATCH] Add Account creation/permission handling based on Azure oAuth group membership --- powerdnsadmin/models/setting.py | 5 ++ powerdnsadmin/routes/admin.py | 11 +++ powerdnsadmin/routes/index.py | 70 +++++++++++++++++++ .../admin_setting_authentication.html | 36 ++++++++++ 4 files changed, 122 insertions(+) diff --git a/powerdnsadmin/models/setting.py b/powerdnsadmin/models/setting.py index b225787..bd1066e 100644 --- a/powerdnsadmin/models/setting.py +++ b/powerdnsadmin/models/setting.py @@ -81,6 +81,11 @@ class Setting(db.Model): 'azure_admin_group': '', 'azure_operator_group': '', 'azure_user_group': '', + 'azure_group_accounts_enabled': False, + 'azure_group_accounts_name': 'displayName', + 'azure_group_accounts_name_re': '', + 'azure_group_accounts_description': 'description', + 'azure_group_accounts_description_re': '', 'oidc_oauth_enabled': False, 'oidc_oauth_key': '', 'oidc_oauth_secret': '', diff --git a/powerdnsadmin/routes/admin.py b/powerdnsadmin/routes/admin.py index 4ee8b58..d5557a1 100644 --- a/powerdnsadmin/routes/admin.py +++ b/powerdnsadmin/routes/admin.py @@ -780,6 +780,17 @@ def setting_authentication(): request.form.get('azure_operator_group')) Setting().set('azure_user_group', request.form.get('azure_user_group')) + Setting().set( + 'azure_group_accounts_enabled', True + if request.form.get('azure_group_accounts_enabled') == 'ON' else False) + Setting().set('azure_group_accounts_name', + request.form.get('azure_group_accounts_name')) + Setting().set('azure_group_accounts_name_re', + request.form.get('azure_group_accounts_name_re')) + Setting().set('azure_group_accounts_description', + request.form.get('azure_group_accounts_description')) + Setting().set('azure_group_accounts_description_re', + request.form.get('azure_group_accounts_description_re')) result = { 'status': True, 'msg': diff --git a/powerdnsadmin/routes/index.py b/powerdnsadmin/routes/index.py index 4df19e8..7013c01 100644 --- a/powerdnsadmin/routes/index.py +++ b/powerdnsadmin/routes/index.py @@ -279,6 +279,76 @@ def login(): error=('User ' + azure_username + ' is not in any authorised groups.')) + # Handle account/group creation, if enabled + if Setting().get('azure_group_accounts_enabled') and mygroups: + current_app.logger.info('Azure group account sync enabled') + for azure_group in mygroups: + + name_value = Setting().get('azure_group_accounts_name') + description_value = Setting().get('azure_group_accounts_description') + + select_values = name_value + if description_value != '': + select_values += ',' + description_value + azure_group_info = azure.get('groups/{}?$select={}'.format(azure_group, select_values)).text + current_app.logger.info('Group name for {}: {}'.format(azure_group, azure_group_info)) + group_info = json.loads(azure_group_info) + if name_value in group_info: + group_name = group_info[name_value] + group_description = '' + if description_value in group_info: + group_description = group_info[description_value] + + # Do regex search if enabled + pattern = Setting().get('azure_group_accounts_name_re') + if pattern != '': + current_app.logger.info('Matching group name {} against regex {}'.format(group_name, pattern)) + matches = re.match(pattern,group_name) + if matches: + current_app.logger.info('Group {} matched regexp'.format(group_name)) + group_name = matches.group(0) + else: + # Regexp didn't match, continue to next iteration + next + account = Account() + account_id = account.get_id_by_name(account_name=group_name) + + if account_id: + account = Account.query.get(account_id) + # check if user has permissions + account_users = account.get_user() + current_app.logger.info('Group: {} Users: {}'.format( + group_name, + account_users)) + if user.id in account_users: + current_app.logger.info('User id {} is already in account {}'.format( + user.id, group_name)) + else: + account.add_user(user) + history = History(msg='Update account {0}'.format( + account.name), + created_by='System') + history.add() + current_app.logger.info('User {} added to Account {}'.format( + user.username, account.name)) + else: + account.name = group_name + account.description = group_description + account.contact = '' + account.mail = '' + account.create_account() + history = History(msg='Create account {0}'.format( + account.name), + created_by='System') + history.add() + + account.add_user(user) + history = History(msg='Update account {0}'.format(account.name), + created_by='System') + history.add() + current_app.logger.warning('group info: {} '.format(account_id)) + + login_user(user, remember=False) signin_history(user.username, 'Azure OAuth', True) return redirect(url_for('index.index')) diff --git a/powerdnsadmin/templates/admin_setting_authentication.html b/powerdnsadmin/templates/admin_setting_authentication.html index 50c00ef..0bfeae9 100644 --- a/powerdnsadmin/templates/admin_setting_authentication.html +++ b/powerdnsadmin/templates/admin_setting_authentication.html @@ -456,6 +456,41 @@ +
+ AZURE GROUP ACCOUNT SYNC/CREATION +
+ +
+ +     + +
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
@@ -476,6 +511,7 @@
  • For the Scope, use User.Read openid mail profile
  • Replace the [tenantID] in the default URLs for authorize and token with your Tenant ID.
  • +

    If AZURE GROUP ACCOUNT SYNC/CREATION is enabled, Accounts will be created automatically based on group membership. If an Account exists, an authenticated user with group membership is added to the Account