Merge pull request #773 from terbolous/azure-oauth

Add Account creation/permission handling based on Azure oAuth group membership
This commit is contained in:
Khanh Ngo 2020-10-10 14:20:26 +02:00 committed by GitHub
commit a679073928
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 135 additions and 0 deletions

View File

@ -83,6 +83,11 @@ class Setting(db.Model):
'azure_admin_group': '', 'azure_admin_group': '',
'azure_operator_group': '', 'azure_operator_group': '',
'azure_user_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_enabled': False,
'oidc_oauth_key': '', 'oidc_oauth_key': '',
'oidc_oauth_secret': '', 'oidc_oauth_secret': '',

View File

@ -903,6 +903,17 @@ def setting_authentication():
request.form.get('azure_operator_group')) request.form.get('azure_operator_group'))
Setting().set('azure_user_group', Setting().set('azure_user_group',
request.form.get('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 = { result = {
'status': True, 'status': True,
'msg': 'msg':

View File

@ -279,6 +279,89 @@ def login():
error=('User ' + azure_username + error=('User ' + azure_username +
' is not in any authorised groups.')) ' 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 for group description
description_pattern = Setting().get('azure_group_accounts_description_re')
if description_pattern != '':
current_app.logger.info('Matching group description {} against regex {}'.format(group_description, description_pattern))
matches = re.match(description_pattern,group_description)
if matches:
current_app.logger.info('Group {} matched regexp'.format(group_description))
group_description = matches.group(1)
else:
# Regexp didn't match, continue to next iteration
next
# Do regex search if enabled for group name
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(1)
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) login_user(user, remember=False)
signin_history(user.username, 'Azure OAuth', True) signin_history(user.username, 'Azure OAuth', True)
return redirect(url_for('index.index')) return redirect(url_for('index.index'))

View File

@ -456,6 +456,41 @@
<span class="help-block with-errors"></span> <span class="help-block with-errors"></span>
</div> </div>
</fieldset> </fieldset>
<fieldset>
<legend>AZURE GROUP ACCOUNT SYNC/CREATION</legend>
<div class="form-group">
<label for="azure_group_accounts_enabled">Status</label>
<div class="radio">
<label>
<input type="radio" name="azure_group_accounts_enabled" id="azure_group_accounts_off" value="OFF" {% if not SETTING.get('azure_group_accounts_enabled') %}checked{% endif %}> OFF
</label>
&nbsp;&nbsp;&nbsp;
<label>
<input type="radio" name="azure_group_accounts_enabled" id="azure_group_accounts_on" value="ON" {% if SETTING.get('azure_group_accounts_enabled') %}checked{% endif %}> ON
</label>
</div>
</div>
<div class="form-group">
<label for="azure_group_accounts_name">Azure group name claim</label>
<input type="text" class="form-control" name="azure_group_accounts_name" id="azure_group_accounts_name" placeholder="e.g. displayName" data-error="Please input the Claim for Azure group name" value="{{ SETTING.get('azure_group_accounts_name') }}">
<span class="help-block with-errors"></span>
</div>
<div class="form-group">
<label for="azure_group_accounts_name_re">Azure group name claim regex</label>
<input type="text" class="form-control" name="azure_group_accounts_name_re" id="azure_group_accounts_name_re" placeholder="e.g. (.*)" data-error="Please input the regex for Azure group name" value="{{ SETTING.get('azure_group_accounts_name_re') }}">
<span class="help-block with-errors"></span>
</div>
<div class="form-group">
<label for="azure_group_accounts_description">Azure group description claim</label>
<input type="text" class="form-control" name="azure_group_accounts_description" id="azure_group_accounts_description" placeholder="e.g. description. If empty uses whole string" data-error="Please input the Claim for Azure group description" value="{{ SETTING.get('azure_group_accounts_description') }}">
<span class="help-block with-errors"></span>
</div>
<div class="form-group">
<label for="azure_group_accounts_name_re">Azure group name description regex</label>
<input type="text" class="form-control" name="azure_group_accounts_description_re" id="azure_group_accounts_description_re" placeholder="e.g. (.*). If empty uses whole string" data-error="Please input the regex for Azure group description" value="{{ SETTING.get('azure_group_accounts_description_re') }}">
<span class="help-block with-errors"></span>
</div>
</fieldset>
<div class="form-group"> <div class="form-group">
<button type="submit" class="btn btn-flat btn-primary">Save</button> <button type="submit" class="btn btn-flat btn-primary">Save</button>
</div> </div>
@ -476,6 +511,7 @@
<li>For the Scope, use <b>User.Read openid mail profile</b></li> <li>For the Scope, use <b>User.Read openid mail profile</b></li>
<li>Replace the [tenantID] in the default URLs for authorize and token with your Tenant ID.</li> <li>Replace the [tenantID] in the default URLs for authorize and token with your Tenant ID.</li>
</ul></p> </ul></p>
<p>If <b>AZURE GROUP ACCOUNT SYNC/CREATION</b> 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</p>
</div> </div>
</div> </div>