OIDC list accounts (#994)

Added the function to use lists instead of a single string in account autoprovision.
This commit is contained in:
benshalev849 2021-11-19 17:53:17 +02:00 committed by GitHub
parent bfaf5655ae
commit b3f9b4a2b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 8 deletions

View File

@ -17,4 +17,60 @@ Now you can enable the OAuth in PowerDNS-Admin.
* Replace the [tenantID] in the default URLs for authorize and token with your Tenant ID. * Replace the [tenantID] in the default URLs for authorize and token with your Tenant ID.
* Restart PowerDNS-Admin * Restart PowerDNS-Admin
This should allow you to log in using OAuth. This should allow you to log in using OAuth.
#### OpenID Connect OAuth
To link to oidc service for authenticationregister your PowerDNS-Admin in the OIDC Provider. This requires your PowerDNS-Admin web interface to use an HTTPS URL.
Enable OpenID Connect OAuth option.
* Client key, The client ID
* Scope, The scope of the data.
* API URL, <oidc_provider_link>/auth (The ending can be different with each provider)
* Token URL, <oidc_provider_link>/token
* Authorize URL, <oidc_provider_link>/auth
* Logout URL, <oidc_provider_link>/logout
* Username, This will be the claim that will be used as the username. (Usually preferred_username)
* First Name, This will be the firstname of the user. (Usually given_name)
* Last Name, This will be the lastname of the user. (Usually family_name)
* Email, This will be the email of the user. (Usually email)
#### To create accounts on oidc login use the following properties:
* Autoprovision Account Name Property, This property will set the name of the created account.
This property can be a string or a list.
* Autoprovision Account Description Property, This property will set the description of the created account.
This property can be a string or a list.
If we get a variable named "groups" and "groups_description" from our IdP.
This variable contains groups that the user is a part of.
We will put the variable name "groups" in the "Name Property" and "groups_description" in the "Description Property".
This will result in the following account being created:
Input we get from the Idp:
```
{
"preferred_username": "example_username",
"given_name": "example_firstame",
"family_name": "example_lastname",
"email": "example_email",
"groups": ["github", "gitlab"]
"groups_description": ["github.com", "gitlab.com"]
}
```
The user properties will be:
```
Username: customer_username
First Name: customer_firstame
Last Name: customer_lastname
Email: customer_email
Role: User
```
The groups properties will be:
```
Name: github Description: github.com Members: example_username
Name: gitlab Description: gitlab.com Members: example_username
```
If the option "delete_sso_accounts" is turned on the user will only be apart of groups the IdP provided and removed from all other accoubnts.

View File

@ -28,6 +28,7 @@ class Setting(db.Model):
'allow_user_create_domain': False, 'allow_user_create_domain': False,
'allow_user_remove_domain': False, 'allow_user_remove_domain': False,
'allow_user_view_history': False, 'allow_user_view_history': False,
'delete_sso_accounts': False,
'bg_domain_updates': False, 'bg_domain_updates': False,
'enable_api_rr_history': True, 'enable_api_rr_history': True,
'site_name': 'PowerDNS-Admin', 'site_name': 'PowerDNS-Admin',

View File

@ -644,7 +644,9 @@ def setting_basic():
'pretty_ipv6_ptr', 'dnssec_admins_only', 'pretty_ipv6_ptr', 'dnssec_admins_only',
'allow_user_create_domain', 'allow_user_remove_domain', 'allow_user_view_history', 'bg_domain_updates', 'site_name', 'allow_user_create_domain', 'allow_user_remove_domain', 'allow_user_view_history', 'bg_domain_updates', 'site_name',
'session_timeout', 'warn_session_timeout', 'ttl_options', 'session_timeout', 'warn_session_timeout', 'ttl_options',
'pdns_api_timeout', 'verify_ssl_connections', 'verify_user_email', 'otp_field_enabled', 'custom_css', 'enable_api_rr_history'
'pdns_api_timeout', 'verify_ssl_connections', 'verify_user_email',
'delete_sso_accounts', 'otp_field_enabled', 'custom_css', 'enable_api_rr_history'
] ]
return render_template('admin_setting_basic.html', settings=settings) return render_template('admin_setting_basic.html', settings=settings)

View File

@ -43,7 +43,6 @@ index_bp = Blueprint('index',
template_folder='templates', template_folder='templates',
url_prefix='/') url_prefix='/')
@index_bp.before_app_first_request @index_bp.before_app_first_request
def register_modules(): def register_modules():
global google global google
@ -398,16 +397,39 @@ def login():
session.pop('oidc_token', None) session.pop('oidc_token', None)
return redirect(url_for('index.login')) return redirect(url_for('index.login'))
#This checks if the account_name_property and account_description property were included in settings.
if Setting().get('oidc_oauth_account_name_property') and Setting().get('oidc_oauth_account_description_property'): if Setting().get('oidc_oauth_account_name_property') and Setting().get('oidc_oauth_account_description_property'):
#Gets the name_property and description_property.
name_prop = Setting().get('oidc_oauth_account_name_property') name_prop = Setting().get('oidc_oauth_account_name_property')
desc_prop = Setting().get('oidc_oauth_account_description_property') desc_prop = Setting().get('oidc_oauth_account_description_property')
account_to_add = []
#If the name_property and desc_property exist in me (A variable that contains all the userinfo from the IdP).
if name_prop in me and desc_prop in me: if name_prop in me and desc_prop in me:
account = handle_account(me[name_prop], me[desc_prop]) accounts_name_prop = [me[name_prop]] if type(me[name_prop]) is not list else me[name_prop]
account.add_user(user) accounts_desc_prop = [me[desc_prop]] if type(me[desc_prop]) is not list else me[desc_prop]
#Run on all groups the user is in by the index num.
for i in range(len(accounts_name_prop)):
description = ''
if i < len(accounts_desc_prop):
description = accounts_desc_prop[i]
account = handle_account(accounts_name_prop[i], description)
account_to_add.append(account)
user_accounts = user.get_accounts() user_accounts = user.get_accounts()
for ua in user_accounts:
if ua.name != account.name: # Add accounts
ua.remove_user(user) for account in account_to_add:
if account not in user_accounts:
account.add_user(user)
# Remove accounts if the setting is enabled
if Setting().get('delete_sso_accounts'):
for account in user_accounts:
if account not in account_to_add:
account.remove_user(user)
session['user_id'] = user.id session['user_id'] = user.id
session['authentication_type'] = 'OAuth' session['authentication_type'] = 'OAuth'