From fd30e3ff497f6bd6984ef329e0e62592da085af8 Mon Sep 17 00:00:00 2001 From: Matt Scott Date: Sat, 11 Mar 2023 14:46:58 -0500 Subject: [PATCH 1/4] Added new JWKS URL setting for each OAuth provider and updated the associated authorization service to use the setting during the initialization of the authlib. --- powerdnsadmin/models/setting.py | 18 ++++--- powerdnsadmin/routes/admin.py | 8 +++ powerdnsadmin/services/azure.py | 1 + powerdnsadmin/services/github.py | 1 + powerdnsadmin/services/google.py | 1 + powerdnsadmin/services/oidc.py | 1 + .../admin_setting_authentication.html | 52 +++++++++++++++++-- 7 files changed, 71 insertions(+), 11 deletions(-) diff --git a/powerdnsadmin/models/setting.py b/powerdnsadmin/models/setting.py index e820af9..331898a 100644 --- a/powerdnsadmin/models/setting.py +++ b/powerdnsadmin/models/setting.py @@ -28,7 +28,7 @@ class Setting(db.Model): 'allow_user_create_domain': False, 'allow_user_remove_domain': False, 'allow_user_view_history': False, - 'delete_sso_accounts': False, + 'delete_sso_accounts': False, 'bg_domain_updates': False, 'enable_api_rr_history': True, 'preserve_history': False, @@ -44,7 +44,7 @@ class Setting(db.Model): 'local_db_enabled': True, 'signup_enabled': True, 'autoprovisioning': False, - 'urn_value':'', + 'urn_value': '', 'autoprovisioning_attribute': '', 'purge': False, 'verify_user_email': False, @@ -69,15 +69,17 @@ class Setting(db.Model): 'github_oauth_scope': 'email', 'github_oauth_api_url': 'https://api.github.com/user', 'github_oauth_token_url': - 'https://github.com/login/oauth/access_token', + 'https://github.com/login/oauth/access_token', 'github_oauth_authorize_url': - 'https://github.com/login/oauth/authorize', + 'https://github.com/login/oauth/authorize', + 'github_oauth_jwks_url': '', 'google_oauth_enabled': False, 'google_oauth_client_id': '', 'google_oauth_client_secret': '', 'google_token_url': 'https://oauth2.googleapis.com/token', 'google_oauth_scope': 'openid email profile', 'google_authorize_url': 'https://accounts.google.com/o/oauth2/v2/auth', + 'google_oauth_jwks_url': '', 'google_base_url': 'https://www.googleapis.com/oauth2/v3/', 'azure_oauth_enabled': False, 'azure_oauth_key': '', @@ -85,9 +87,10 @@ class Setting(db.Model): 'azure_oauth_scope': 'User.Read openid email profile', 'azure_oauth_api_url': 'https://graph.microsoft.com/v1.0/', 'azure_oauth_token_url': - 'https://login.microsoftonline.com/[tenancy]/oauth2/v2.0/token', + 'https://login.microsoftonline.com/[tenancy]/oauth2/v2.0/token', 'azure_oauth_authorize_url': - 'https://login.microsoftonline.com/[tenancy]/oauth2/v2.0/authorize', + 'https://login.microsoftonline.com/[tenancy]/oauth2/v2.0/authorize', + 'azure_oauth_jwks_url': '', 'azure_sg_enabled': False, 'azure_admin_group': '', 'azure_operator_group': '', @@ -104,6 +107,7 @@ class Setting(db.Model): 'oidc_oauth_api_url': '', 'oidc_oauth_token_url': '', 'oidc_oauth_authorize_url': '', + 'oidc_oauth_jwks_url': '', 'oidc_oauth_metadata_url': '', 'oidc_oauth_logout_url': '', 'oidc_oauth_username': 'preferred_username', @@ -284,7 +288,7 @@ class Setting(db.Model): result = self.query.filter(Setting.name == setting).first() if result is not None: - if hasattr(result,'value'): + if hasattr(result, 'value'): result = result.value return strtobool(result) if result in [ 'True', 'False' diff --git a/powerdnsadmin/routes/admin.py b/powerdnsadmin/routes/admin.py index 0d85d29..5aea1d2 100644 --- a/powerdnsadmin/routes/admin.py +++ b/powerdnsadmin/routes/admin.py @@ -1642,6 +1642,8 @@ def setting_authentication(): request.form.get('google_oauth_scope')) Setting().set('google_authorize_url', request.form.get('google_authorize_url')) + Setting().set('google_oauth_jwks_url', + request.form.get('google_oauth_jwks_url')) Setting().set('google_base_url', request.form.get('google_base_url')) result = { @@ -1673,6 +1675,8 @@ def setting_authentication(): request.form.get('github_oauth_token_url')) Setting().set('github_oauth_authorize_url', request.form.get('github_oauth_authorize_url')) + Setting().set('github_oauth_jwks_url', + request.form.get('github_oauth_jwks_url')) result = { 'status': True, 'msg': @@ -1702,6 +1706,8 @@ def setting_authentication(): request.form.get('azure_oauth_token_url')) Setting().set('azure_oauth_authorize_url', request.form.get('azure_oauth_authorize_url')) + Setting().set('azure_oauth_jwks_url', + request.form.get('azure_oauth_jwks_url')) Setting().set( 'azure_sg_enabled', True if request.form.get('azure_sg_enabled') == 'ON' else False) @@ -1753,6 +1759,8 @@ def setting_authentication(): request.form.get('oidc_oauth_token_url')) Setting().set('oidc_oauth_authorize_url', request.form.get('oidc_oauth_authorize_url')) + Setting().set('oidc_oauth_jwks_url', + request.form.get('oidc_oauth_jwks_url')) Setting().set('oidc_oauth_metadata_url', request.form.get('oidc_oauth_metadata_url')) Setting().set('oidc_oauth_logout_url', diff --git a/powerdnsadmin/services/azure.py b/powerdnsadmin/services/azure.py index 46fb1af..691b153 100644 --- a/powerdnsadmin/services/azure.py +++ b/powerdnsadmin/services/azure.py @@ -23,6 +23,7 @@ def azure_oauth(): request_token_url=None, access_token_url=Setting().get('azure_oauth_token_url'), authorize_url=Setting().get('azure_oauth_authorize_url'), + jwks_url=Setting().get('azure_oauth_jwks_url'), client_kwargs={'scope': Setting().get('azure_oauth_scope')}, fetch_token=fetch_azure_token, ) diff --git a/powerdnsadmin/services/github.py b/powerdnsadmin/services/github.py index cf615e8..8bcbe87 100644 --- a/powerdnsadmin/services/github.py +++ b/powerdnsadmin/services/github.py @@ -24,6 +24,7 @@ def github_oauth(): request_token_url=None, access_token_url=Setting().get('github_oauth_token_url'), authorize_url=Setting().get('github_oauth_authorize_url'), + jwks_url=Setting().get('github_oauth_jwks_url'), client_kwargs={'scope': Setting().get('github_oauth_scope')}, fetch_token=fetch_github_token, update_token=update_token) diff --git a/powerdnsadmin/services/google.py b/powerdnsadmin/services/google.py index 68775a2..0a62463 100644 --- a/powerdnsadmin/services/google.py +++ b/powerdnsadmin/services/google.py @@ -23,6 +23,7 @@ def google_oauth(): request_token_url=None, access_token_url=Setting().get('google_token_url'), authorize_url=Setting().get('google_authorize_url'), + jwks_url=Setting().get('google_oauth_jwks_url'), client_kwargs={'scope': Setting().get('google_oauth_scope')}, fetch_token=fetch_google_token, update_token=update_token) diff --git a/powerdnsadmin/services/oidc.py b/powerdnsadmin/services/oidc.py index b5da89e..432457f 100644 --- a/powerdnsadmin/services/oidc.py +++ b/powerdnsadmin/services/oidc.py @@ -23,6 +23,7 @@ def oidc_oauth(): request_token_url=None, access_token_url=Setting().get('oidc_oauth_token_url'), authorize_url=Setting().get('oidc_oauth_authorize_url'), + jwks_url=Setting().get('oidc_oauth_jwks_url'), server_metadata_url=Setting().get('oidc_oauth_metadata_url'), client_kwargs={'scope': Setting().get('oidc_oauth_scope')}, fetch_token=fetch_oidc_token, diff --git a/powerdnsadmin/templates/admin_setting_authentication.html b/powerdnsadmin/templates/admin_setting_authentication.html index 26d9a72..5750d89 100644 --- a/powerdnsadmin/templates/admin_setting_authentication.html +++ b/powerdnsadmin/templates/admin_setting_authentication.html @@ -663,6 +663,17 @@ value="{{ SETTING.get('google_authorize_url') }}"> +
+ + + +
+
+ + + +
@@ -915,6 +937,17 @@ value="{{ SETTING.get('azure_oauth_authorize_url') }}"> +
+ + + +
GROUP SECURITY @@ -1206,10 +1239,21 @@ name="oidc_oauth_authorize_url" id="oidc_oauth_authorize_url" placeholder="e.g. https://oidc.com/login/oauth/authorize" - data-error="Plesae input Authorize URL" + data-error="Please input Authorize URL" value="{{ SETTING.get('oidc_oauth_authorize_url') }}"> +
+ + + +
@@ -1217,7 +1261,7 @@ name="oidc_oauth_metadata_url" id="oidc_oauth_metadata_url" placeholder="e.g. https://oidc.com/login/oauth/.well-known/openid-configuration" - data-error="Plesae input Metadata URL" + data-error="Please input Metadata URL" value="{{ SETTING.get('oidc_oauth_metadata_url') }}">
@@ -1270,7 +1314,7 @@ From 369188e80e95a8896b6e61326ece8acc706fb1dc Mon Sep 17 00:00:00 2001 From: Matt Scott Date: Sat, 11 Mar 2023 14:50:02 -0500 Subject: [PATCH 2/4] Disabled MegaLinter workflow for all branches currently. --- .github/workflows/mega-linter.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index 4c005da..943d3a3 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -6,6 +6,7 @@ name: MegaLinter on: push: branches-ignore: + - "*" - "dev" - "main" - "master" From 1afe9b490866f8afb951acddecbc53b0fbdefb8e Mon Sep 17 00:00:00 2001 From: Matt Scott Date: Sun, 12 Mar 2023 09:13:54 -0400 Subject: [PATCH 3/4] Finished adding new OAuth Server Metadata URL setting to Google, GitHub, and Microsoft OAuth service configuration features. --- powerdnsadmin/models/setting.py | 3 + powerdnsadmin/routes/admin.py | 10 ++- powerdnsadmin/services/azure.py | 1 + powerdnsadmin/services/github.py | 1 + powerdnsadmin/services/google.py | 1 + .../admin_setting_authentication.html | 65 ++++++++++++------- 6 files changed, 57 insertions(+), 24 deletions(-) diff --git a/powerdnsadmin/models/setting.py b/powerdnsadmin/models/setting.py index 331898a..bef6897 100644 --- a/powerdnsadmin/models/setting.py +++ b/powerdnsadmin/models/setting.py @@ -73,6 +73,7 @@ class Setting(db.Model): 'github_oauth_authorize_url': 'https://github.com/login/oauth/authorize', 'github_oauth_jwks_url': '', + 'github_oauth_metadata_url': '', 'google_oauth_enabled': False, 'google_oauth_client_id': '', 'google_oauth_client_secret': '', @@ -80,6 +81,7 @@ class Setting(db.Model): 'google_oauth_scope': 'openid email profile', 'google_authorize_url': 'https://accounts.google.com/o/oauth2/v2/auth', 'google_oauth_jwks_url': '', + 'google_oauth_metadata_url': '', 'google_base_url': 'https://www.googleapis.com/oauth2/v3/', 'azure_oauth_enabled': False, 'azure_oauth_key': '', @@ -91,6 +93,7 @@ class Setting(db.Model): 'azure_oauth_authorize_url': 'https://login.microsoftonline.com/[tenancy]/oauth2/v2.0/authorize', 'azure_oauth_jwks_url': '', + 'azure_oauth_metadata_url': '', 'azure_sg_enabled': False, 'azure_admin_group': '', 'azure_operator_group': '', diff --git a/powerdnsadmin/routes/admin.py b/powerdnsadmin/routes/admin.py index 5aea1d2..900e70c 100644 --- a/powerdnsadmin/routes/admin.py +++ b/powerdnsadmin/routes/admin.py @@ -1636,6 +1636,8 @@ def setting_authentication(): request.form.get('google_oauth_client_id')) Setting().set('google_oauth_client_secret', request.form.get('google_oauth_client_secret')) + Setting().set('google_oauth_metadata_url', + request.form.get('google_oauth_metadata_url')) Setting().set('google_token_url', request.form.get('google_token_url')) Setting().set('google_oauth_scope', @@ -1671,6 +1673,8 @@ def setting_authentication(): request.form.get('github_oauth_scope')) Setting().set('github_oauth_api_url', request.form.get('github_oauth_api_url')) + Setting().set('github_oauth_metadata_url', + request.form.get('github_oauth_metadata_url')) Setting().set('github_oauth_token_url', request.form.get('github_oauth_token_url')) Setting().set('github_oauth_authorize_url', @@ -1702,6 +1706,8 @@ def setting_authentication(): request.form.get('azure_oauth_scope')) Setting().set('azure_oauth_api_url', request.form.get('azure_oauth_api_url')) + Setting().set('azure_oauth_metadata_url', + request.form.get('azure_oauth_metadata_url')) Setting().set('azure_oauth_token_url', request.form.get('azure_oauth_token_url')) Setting().set('azure_oauth_authorize_url', @@ -1755,14 +1761,14 @@ def setting_authentication(): request.form.get('oidc_oauth_scope')) Setting().set('oidc_oauth_api_url', request.form.get('oidc_oauth_api_url')) + Setting().set('oidc_oauth_metadata_url', + request.form.get('oidc_oauth_metadata_url')) Setting().set('oidc_oauth_token_url', request.form.get('oidc_oauth_token_url')) Setting().set('oidc_oauth_authorize_url', request.form.get('oidc_oauth_authorize_url')) Setting().set('oidc_oauth_jwks_url', request.form.get('oidc_oauth_jwks_url')) - Setting().set('oidc_oauth_metadata_url', - request.form.get('oidc_oauth_metadata_url')) Setting().set('oidc_oauth_logout_url', request.form.get('oidc_oauth_logout_url')) Setting().set('oidc_oauth_username', diff --git a/powerdnsadmin/services/azure.py b/powerdnsadmin/services/azure.py index 691b153..c1fb626 100644 --- a/powerdnsadmin/services/azure.py +++ b/powerdnsadmin/services/azure.py @@ -24,6 +24,7 @@ def azure_oauth(): access_token_url=Setting().get('azure_oauth_token_url'), authorize_url=Setting().get('azure_oauth_authorize_url'), jwks_url=Setting().get('azure_oauth_jwks_url'), + server_metadata_url=Setting().get('azure_oauth_metadata_url'), client_kwargs={'scope': Setting().get('azure_oauth_scope')}, fetch_token=fetch_azure_token, ) diff --git a/powerdnsadmin/services/github.py b/powerdnsadmin/services/github.py index 8bcbe87..13c2f00 100644 --- a/powerdnsadmin/services/github.py +++ b/powerdnsadmin/services/github.py @@ -25,6 +25,7 @@ def github_oauth(): access_token_url=Setting().get('github_oauth_token_url'), authorize_url=Setting().get('github_oauth_authorize_url'), jwks_url=Setting().get('github_oauth_jwks_url'), + server_metadata_url=Setting().get('github_oauth_metadata_url'), client_kwargs={'scope': Setting().get('github_oauth_scope')}, fetch_token=fetch_github_token, update_token=update_token) diff --git a/powerdnsadmin/services/google.py b/powerdnsadmin/services/google.py index 0a62463..fc9af12 100644 --- a/powerdnsadmin/services/google.py +++ b/powerdnsadmin/services/google.py @@ -24,6 +24,7 @@ def google_oauth(): access_token_url=Setting().get('google_token_url'), authorize_url=Setting().get('google_authorize_url'), jwks_url=Setting().get('google_oauth_jwks_url'), + server_metadata_url=Setting().get('google_oauth_metadata_url'), client_kwargs={'scope': Setting().get('google_oauth_scope')}, fetch_token=fetch_google_token, update_token=update_token) diff --git a/powerdnsadmin/templates/admin_setting_authentication.html b/powerdnsadmin/templates/admin_setting_authentication.html index 5750d89..7675797 100644 --- a/powerdnsadmin/templates/admin_setting_authentication.html +++ b/powerdnsadmin/templates/admin_setting_authentication.html @@ -630,9 +630,16 @@ value="{{ SETTING.get('google_oauth_client_secret') }}"> -
-
- ADVANCE +
+ + + +
-
-
- ADVANCE
+
+ + + +
@@ -893,9 +907,6 @@ value="{{ SETTING.get('azure_oauth_secret') }}">
-
-
- ADVANCED
+
+ + + +
+
+ + + +
-
- - - -
@@ -1278,7 +1299,7 @@
- CLAIMS + Claims
- ADVANCE + Advanced
From 84cfd165b4d3e34d15b024b9cbcc651b66aa8d8e Mon Sep 17 00:00:00 2001 From: Matt Scott Date: Sun, 12 Mar 2023 10:27:04 -0400 Subject: [PATCH 4/4] Re-arranged side navigation to include the "Global Search" feature regardless of user role as the global search feature is now accessible to all users. Also moved the "Activity" feature link higher in the menu to remove duplicate code from the navigation code base. --- powerdnsadmin/templates/base.html | 34 +++++++++++++------------------ 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/powerdnsadmin/templates/base.html b/powerdnsadmin/templates/base.html index 5a47bd2..408f4be 100644 --- a/powerdnsadmin/templates/base.html +++ b/powerdnsadmin/templates/base.html @@ -101,14 +101,22 @@ {% endif %} - {% if current_user.role.name in ['Administrator', 'Operator'] %} - -
  • - - -

    Global Search

    +
  • +
  • + + +

    Global Search

    +
    +
  • + {% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %} +
  • + + +

    Activity

  • + {% endif %} + {% if current_user.role.name in ['Administrator', 'Operator'] %}
  • @@ -121,12 +129,6 @@

    Server Configuration

  • -
  • - - -

    Activity

    -
    -
  • @@ -189,14 +191,6 @@ {% endif %}
  • - {% elif SETTING.get('allow_user_view_history') %} - -
  • - - -

    History

    -
    -
  • {% endif %} {% endif %}