Add the possibility to configure the OAuth2 claim which is used for the pgAdmin username. #5468
This feature provides the possibility to configure the Oauth2 claim which should be used as a username. The key in the config.py is called 'OAUTH2_USERNAME_CLAIM'. If you don't provide a custom key, the email is used as the username, like before. So it is completely backward compatible.pull/5556/head
parent
c38face9fc
commit
6bc5808c53
|
@ -33,6 +33,8 @@ and modify the values for the following parameters:
|
||||||
"OAUTH2_SCOPE", "Oauth scope, ex: 'openid email profile'. Note that an 'email' claim is required in the resulting profile."
|
"OAUTH2_SCOPE", "Oauth scope, ex: 'openid email profile'. Note that an 'email' claim is required in the resulting profile."
|
||||||
"OAUTH2_ICON", "The Font-awesome icon to be placed on the oauth2 button, ex: fa-github"
|
"OAUTH2_ICON", "The Font-awesome icon to be placed on the oauth2 button, ex: fa-github"
|
||||||
"OAUTH2_BUTTON_COLOR", "Oauth2 button color"
|
"OAUTH2_BUTTON_COLOR", "Oauth2 button color"
|
||||||
|
"OAUTH2_USERNAME_CLAIM", "The claim which is used for the username. If the value is empty
|
||||||
|
the email is used as username, but if a value is provided, the claim has to exist. Ex: *oid* (for AzureAD)"
|
||||||
"OAUTH2_AUTO_CREATE_USER", "Set the value to *True* if you want to automatically
|
"OAUTH2_AUTO_CREATE_USER", "Set the value to *True* if you want to automatically
|
||||||
create a pgAdmin user corresponding to a successfully authenticated Oauth2 user.
|
create a pgAdmin user corresponding to a successfully authenticated Oauth2 user.
|
||||||
Please note that password is not stored in the pgAdmin database."
|
Please note that password is not stored in the pgAdmin database."
|
||||||
|
|
|
@ -16,7 +16,8 @@ New features
|
||||||
************
|
************
|
||||||
|
|
||||||
| `Issue #1832 <https://github.com/pgadmin-org/pgadmin4/issues/1832>`_ - Added support for storing configurations of pgAdmin in an external database.
|
| `Issue #1832 <https://github.com/pgadmin-org/pgadmin4/issues/1832>`_ - Added support for storing configurations of pgAdmin in an external database.
|
||||||
|
| `Issue #5468 <https://github.com/pgadmin-org/pgadmin4/issues/5468>`_ - Add the possibility to configure the Oauth2 claim which is used for the pgAdmin username.
|
||||||
|
|
||||||
Housekeeping
|
Housekeeping
|
||||||
************
|
************
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#
|
#
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
from pgadmin.utils import env, IS_WIN, fs_short_path
|
||||||
import builtins
|
import builtins
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
@ -22,7 +23,6 @@ root = os.path.dirname(os.path.realpath(__file__))
|
||||||
if sys.path[0] != root:
|
if sys.path[0] != root:
|
||||||
sys.path.insert(0, root)
|
sys.path.insert(0, root)
|
||||||
|
|
||||||
from pgadmin.utils import env, IS_WIN, fs_short_path
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# Application settings
|
# Application settings
|
||||||
|
@ -754,6 +754,10 @@ OAUTH2_CONFIG = [
|
||||||
# Oauth scope, ex: 'openid email profile'
|
# Oauth scope, ex: 'openid email profile'
|
||||||
# Note that an 'email' claim is required in the resulting profile
|
# Note that an 'email' claim is required in the resulting profile
|
||||||
'OAUTH2_SCOPE': None,
|
'OAUTH2_SCOPE': None,
|
||||||
|
# The claim which is used for the username. If the value is empty the
|
||||||
|
# email is used as username, but if a value is provided,
|
||||||
|
# the claim has to exist.
|
||||||
|
'OAUTH2_USERNAME_CLAIM': None,
|
||||||
# Font-awesome icon, ex: fa-github
|
# Font-awesome icon, ex: fa-github
|
||||||
'OAUTH2_ICON': None,
|
'OAUTH2_ICON': None,
|
||||||
# UI button colour, ex: #0000ff
|
# UI button colour, ex: #0000ff
|
||||||
|
|
|
@ -123,6 +123,23 @@ class OAuth2Authentication(BaseAuthentication):
|
||||||
[value for value in self.email_keys if value in profile.keys()]
|
[value for value in self.email_keys if value in profile.keys()]
|
||||||
email = profile[email_key[0]] if (len(email_key) > 0) else None
|
email = profile[email_key[0]] if (len(email_key) > 0) else None
|
||||||
|
|
||||||
|
username = email
|
||||||
|
username_claim = None
|
||||||
|
if 'OAUTH2_USERNAME_CLAIM' in self.oauth2_config[
|
||||||
|
self.oauth2_current_client]:
|
||||||
|
username_claim = self.oauth2_config[
|
||||||
|
self.oauth2_current_client
|
||||||
|
]['OAUTH2_USERNAME_CLAIM']
|
||||||
|
if username_claim is not None:
|
||||||
|
if username_claim in profile:
|
||||||
|
username = profile[username_claim]
|
||||||
|
else:
|
||||||
|
error_msg = "The claim '%s' is required to login into " \
|
||||||
|
"pgAdmin. Please update your Oauth2 profile." % (
|
||||||
|
username_claim)
|
||||||
|
current_app.logger.exception(error_msg)
|
||||||
|
return False, gettext(error_msg)
|
||||||
|
|
||||||
if not email or email == '':
|
if not email or email == '':
|
||||||
current_app.logger.exception(
|
current_app.logger.exception(
|
||||||
"An email id is required to login into pgAdmin. "
|
"An email id is required to login into pgAdmin. "
|
||||||
|
@ -132,10 +149,10 @@ class OAuth2Authentication(BaseAuthentication):
|
||||||
"An email id is required to login into pgAdmin. "
|
"An email id is required to login into pgAdmin. "
|
||||||
"Please update your Oauth2 profile.")
|
"Please update your Oauth2 profile.")
|
||||||
|
|
||||||
user, msg = self.__auto_create_user(email)
|
user, msg = self.__auto_create_user(username, email)
|
||||||
if user:
|
if user:
|
||||||
user = db.session.query(User).filter_by(
|
user = db.session.query(User).filter_by(
|
||||||
username=email, auth_source=OAUTH2).first()
|
username=username, auth_source=OAUTH2).first()
|
||||||
current_app.login_manager.logout_view = \
|
current_app.login_manager.logout_view = \
|
||||||
OAuth2Authentication.LOGOUT_VIEW
|
OAuth2Authentication.LOGOUT_VIEW
|
||||||
return login_user(user), None
|
return login_user(user), None
|
||||||
|
@ -165,17 +182,17 @@ class OAuth2Authentication(BaseAuthentication):
|
||||||
return False, self.oauth2_clients[
|
return False, self.oauth2_clients[
|
||||||
self.oauth2_current_client].authorize_redirect(redirect_url)
|
self.oauth2_current_client].authorize_redirect(redirect_url)
|
||||||
|
|
||||||
def __auto_create_user(self, email):
|
def __auto_create_user(self, username, email):
|
||||||
if config.OAUTH2_AUTO_CREATE_USER:
|
if config.OAUTH2_AUTO_CREATE_USER:
|
||||||
user = User.query.filter_by(username=email,
|
user = User.query.filter_by(username=username,
|
||||||
auth_source=OAUTH2).first()
|
auth_source=OAUTH2).first()
|
||||||
if not user:
|
if not user:
|
||||||
return create_user({
|
return create_user({
|
||||||
'username': email,
|
'username': username,
|
||||||
'email': email,
|
'email': email,
|
||||||
'role': 2,
|
'role': 2,
|
||||||
'active': True,
|
'active': True,
|
||||||
'auth_source': OAUTH2
|
'auth_source': OAUTH2
|
||||||
})
|
})
|
||||||
|
|
||||||
return True, {'username': email}
|
return True, {'username': username}
|
||||||
|
|
Loading…
Reference in New Issue