Black lint all the things
This commit is contained in:
@ -14,35 +14,41 @@ from lemur.roles import service as role_service
|
||||
from lemur.common.utils import validate_conf, get_psuedo_random_string
|
||||
|
||||
|
||||
class LdapPrincipal():
|
||||
class LdapPrincipal:
|
||||
"""
|
||||
Provides methods for authenticating against an LDAP server.
|
||||
"""
|
||||
|
||||
def __init__(self, args):
|
||||
self._ldap_validate_conf()
|
||||
# setup ldap config
|
||||
if not args['username']:
|
||||
if not args["username"]:
|
||||
raise Exception("missing ldap username")
|
||||
if not args['password']:
|
||||
if not args["password"]:
|
||||
self.error_message = "missing ldap password"
|
||||
raise Exception("missing ldap password")
|
||||
self.ldap_principal = args['username']
|
||||
self.ldap_principal = args["username"]
|
||||
self.ldap_email_domain = current_app.config.get("LDAP_EMAIL_DOMAIN", None)
|
||||
if '@' not in self.ldap_principal:
|
||||
self.ldap_principal = '%s@%s' % (self.ldap_principal, self.ldap_email_domain)
|
||||
self.ldap_username = args['username']
|
||||
if '@' in self.ldap_username:
|
||||
self.ldap_username = args['username'].split("@")[0]
|
||||
self.ldap_password = args['password']
|
||||
self.ldap_server = current_app.config.get('LDAP_BIND_URI', None)
|
||||
if "@" not in self.ldap_principal:
|
||||
self.ldap_principal = "%s@%s" % (
|
||||
self.ldap_principal,
|
||||
self.ldap_email_domain,
|
||||
)
|
||||
self.ldap_username = args["username"]
|
||||
if "@" in self.ldap_username:
|
||||
self.ldap_username = args["username"].split("@")[0]
|
||||
self.ldap_password = args["password"]
|
||||
self.ldap_server = current_app.config.get("LDAP_BIND_URI", None)
|
||||
self.ldap_base_dn = current_app.config.get("LDAP_BASE_DN", None)
|
||||
self.ldap_use_tls = current_app.config.get("LDAP_USE_TLS", False)
|
||||
self.ldap_cacert_file = current_app.config.get("LDAP_CACERT_FILE", None)
|
||||
self.ldap_default_role = current_app.config.get("LEMUR_DEFAULT_ROLE", None)
|
||||
self.ldap_required_group = current_app.config.get("LDAP_REQUIRED_GROUP", None)
|
||||
self.ldap_groups_to_roles = current_app.config.get("LDAP_GROUPS_TO_ROLES", None)
|
||||
self.ldap_is_active_directory = current_app.config.get("LDAP_IS_ACTIVE_DIRECTORY", False)
|
||||
self.ldap_attrs = ['memberOf']
|
||||
self.ldap_is_active_directory = current_app.config.get(
|
||||
"LDAP_IS_ACTIVE_DIRECTORY", False
|
||||
)
|
||||
self.ldap_attrs = ["memberOf"]
|
||||
self.ldap_client = None
|
||||
self.ldap_groups = None
|
||||
|
||||
@ -60,8 +66,8 @@ class LdapPrincipal():
|
||||
get_psuedo_random_string(),
|
||||
self.ldap_principal,
|
||||
True,
|
||||
'', # thumbnailPhotoUrl
|
||||
list(roles)
|
||||
"", # thumbnailPhotoUrl
|
||||
list(roles),
|
||||
)
|
||||
else:
|
||||
# we add 'lemur' specific roles, so they do not get marked as removed
|
||||
@ -76,7 +82,7 @@ class LdapPrincipal():
|
||||
self.ldap_principal,
|
||||
user.active,
|
||||
user.profile_picture,
|
||||
list(roles)
|
||||
list(roles),
|
||||
)
|
||||
return user
|
||||
|
||||
@ -105,9 +111,12 @@ class LdapPrincipal():
|
||||
# update their 'roles'
|
||||
role = role_service.get_by_name(self.ldap_principal)
|
||||
if not role:
|
||||
description = "auto generated role based on owner: {0}".format(self.ldap_principal)
|
||||
role = role_service.create(self.ldap_principal, description=description,
|
||||
third_party=True)
|
||||
description = "auto generated role based on owner: {0}".format(
|
||||
self.ldap_principal
|
||||
)
|
||||
role = role_service.create(
|
||||
self.ldap_principal, description=description, third_party=True
|
||||
)
|
||||
if not role.third_party:
|
||||
role = role_service.set_third_party(role.id, third_party_status=True)
|
||||
roles.add(role)
|
||||
@ -118,9 +127,15 @@ class LdapPrincipal():
|
||||
role = role_service.get_by_name(role_name)
|
||||
if role:
|
||||
if ldap_group_name in self.ldap_groups:
|
||||
current_app.logger.debug("assigning role {0} to ldap user {1}".format(self.ldap_principal, role))
|
||||
current_app.logger.debug(
|
||||
"assigning role {0} to ldap user {1}".format(
|
||||
self.ldap_principal, role
|
||||
)
|
||||
)
|
||||
if not role.third_party:
|
||||
role = role_service.set_third_party(role.id, third_party_status=True)
|
||||
role = role_service.set_third_party(
|
||||
role.id, third_party_status=True
|
||||
)
|
||||
roles.add(role)
|
||||
return roles
|
||||
|
||||
@ -132,7 +147,7 @@ class LdapPrincipal():
|
||||
self._bind()
|
||||
roles = self._authorize()
|
||||
if not roles:
|
||||
raise Exception('ldap authorization failed')
|
||||
raise Exception("ldap authorization failed")
|
||||
return self._update_user(roles)
|
||||
|
||||
def _bind(self):
|
||||
@ -141,9 +156,12 @@ class LdapPrincipal():
|
||||
list groups for a user.
|
||||
raise an exception on error.
|
||||
"""
|
||||
if '@' not in self.ldap_principal:
|
||||
self.ldap_principal = '%s@%s' % (self.ldap_principal, self.ldap_email_domain)
|
||||
ldap_filter = 'userPrincipalName=%s' % self.ldap_principal
|
||||
if "@" not in self.ldap_principal:
|
||||
self.ldap_principal = "%s@%s" % (
|
||||
self.ldap_principal,
|
||||
self.ldap_email_domain,
|
||||
)
|
||||
ldap_filter = "userPrincipalName=%s" % self.ldap_principal
|
||||
|
||||
# query ldap for auth
|
||||
try:
|
||||
@ -159,37 +177,47 @@ class LdapPrincipal():
|
||||
self.ldap_client.set_option(ldap.OPT_X_TLS_DEMAND, True)
|
||||
self.ldap_client.set_option(ldap.OPT_DEBUG_LEVEL, 255)
|
||||
if self.ldap_cacert_file:
|
||||
self.ldap_client.set_option(ldap.OPT_X_TLS_CACERTFILE, self.ldap_cacert_file)
|
||||
self.ldap_client.set_option(
|
||||
ldap.OPT_X_TLS_CACERTFILE, self.ldap_cacert_file
|
||||
)
|
||||
self.ldap_client.simple_bind_s(self.ldap_principal, self.ldap_password)
|
||||
except ldap.INVALID_CREDENTIALS:
|
||||
self.ldap_client.unbind()
|
||||
raise Exception('The supplied ldap credentials are invalid')
|
||||
raise Exception("The supplied ldap credentials are invalid")
|
||||
except ldap.SERVER_DOWN:
|
||||
raise Exception('ldap server unavailable')
|
||||
raise Exception("ldap server unavailable")
|
||||
except ldap.LDAPError as e:
|
||||
raise Exception("ldap error: {0}".format(e))
|
||||
|
||||
if self.ldap_is_active_directory:
|
||||
# Lookup user DN, needed to search for group membership
|
||||
userdn = self.ldap_client.search_s(self.ldap_base_dn,
|
||||
ldap.SCOPE_SUBTREE, ldap_filter,
|
||||
['distinguishedName'])[0][1]['distinguishedName'][0]
|
||||
userdn = userdn.decode('utf-8')
|
||||
userdn = self.ldap_client.search_s(
|
||||
self.ldap_base_dn,
|
||||
ldap.SCOPE_SUBTREE,
|
||||
ldap_filter,
|
||||
["distinguishedName"],
|
||||
)[0][1]["distinguishedName"][0]
|
||||
userdn = userdn.decode("utf-8")
|
||||
# Search all groups that have the userDN as a member
|
||||
groupfilter = '(&(objectclass=group)(member:1.2.840.113556.1.4.1941:={0}))'.format(userdn)
|
||||
lgroups = self.ldap_client.search_s(self.ldap_base_dn, ldap.SCOPE_SUBTREE, groupfilter, ['cn'])
|
||||
groupfilter = "(&(objectclass=group)(member:1.2.840.113556.1.4.1941:={0}))".format(
|
||||
userdn
|
||||
)
|
||||
lgroups = self.ldap_client.search_s(
|
||||
self.ldap_base_dn, ldap.SCOPE_SUBTREE, groupfilter, ["cn"]
|
||||
)
|
||||
|
||||
# Create a list of group CN's from the result
|
||||
self.ldap_groups = []
|
||||
for group in lgroups:
|
||||
(dn, values) = group
|
||||
self.ldap_groups.append(values['cn'][0].decode('ascii'))
|
||||
self.ldap_groups.append(values["cn"][0].decode("ascii"))
|
||||
else:
|
||||
lgroups = self.ldap_client.search_s(self.ldap_base_dn,
|
||||
ldap.SCOPE_SUBTREE, ldap_filter, self.ldap_attrs)[0][1]['memberOf']
|
||||
lgroups = self.ldap_client.search_s(
|
||||
self.ldap_base_dn, ldap.SCOPE_SUBTREE, ldap_filter, self.ldap_attrs
|
||||
)[0][1]["memberOf"]
|
||||
# lgroups is a list of utf-8 encoded strings
|
||||
# convert to a single string of groups to allow matching
|
||||
self.ldap_groups = b''.join(lgroups).decode('ascii')
|
||||
self.ldap_groups = b"".join(lgroups).decode("ascii")
|
||||
|
||||
self.ldap_client.unbind()
|
||||
|
||||
@ -197,9 +225,5 @@ class LdapPrincipal():
|
||||
"""
|
||||
Confirms required ldap config settings exist.
|
||||
"""
|
||||
required_vars = [
|
||||
'LDAP_BIND_URI',
|
||||
'LDAP_BASE_DN',
|
||||
'LDAP_EMAIL_DOMAIN',
|
||||
]
|
||||
required_vars = ["LDAP_BIND_URI", "LDAP_BASE_DN", "LDAP_EMAIL_DOMAIN"]
|
||||
validate_conf(current_app, required_vars)
|
||||
|
@ -12,21 +12,21 @@ from collections import namedtuple
|
||||
from flask_principal import Permission, RoleNeed
|
||||
|
||||
# Permissions
|
||||
operator_permission = Permission(RoleNeed('operator'))
|
||||
admin_permission = Permission(RoleNeed('admin'))
|
||||
operator_permission = Permission(RoleNeed("operator"))
|
||||
admin_permission = Permission(RoleNeed("admin"))
|
||||
|
||||
CertificateOwner = namedtuple('certificate', ['method', 'value'])
|
||||
CertificateOwnerNeed = partial(CertificateOwner, 'role')
|
||||
CertificateOwner = namedtuple("certificate", ["method", "value"])
|
||||
CertificateOwnerNeed = partial(CertificateOwner, "role")
|
||||
|
||||
|
||||
class SensitiveDomainPermission(Permission):
|
||||
def __init__(self):
|
||||
super(SensitiveDomainPermission, self).__init__(RoleNeed('admin'))
|
||||
super(SensitiveDomainPermission, self).__init__(RoleNeed("admin"))
|
||||
|
||||
|
||||
class CertificatePermission(Permission):
|
||||
def __init__(self, owner, roles):
|
||||
needs = [RoleNeed('admin'), RoleNeed(owner), RoleNeed('creator')]
|
||||
needs = [RoleNeed("admin"), RoleNeed(owner), RoleNeed("creator")]
|
||||
for r in roles:
|
||||
needs.append(CertificateOwnerNeed(str(r)))
|
||||
# Backwards compatibility with mixed-case role names
|
||||
@ -38,29 +38,29 @@ class CertificatePermission(Permission):
|
||||
|
||||
class ApiKeyCreatorPermission(Permission):
|
||||
def __init__(self):
|
||||
super(ApiKeyCreatorPermission, self).__init__(RoleNeed('admin'))
|
||||
super(ApiKeyCreatorPermission, self).__init__(RoleNeed("admin"))
|
||||
|
||||
|
||||
RoleMember = namedtuple('role', ['method', 'value'])
|
||||
RoleMemberNeed = partial(RoleMember, 'member')
|
||||
RoleMember = namedtuple("role", ["method", "value"])
|
||||
RoleMemberNeed = partial(RoleMember, "member")
|
||||
|
||||
|
||||
class RoleMemberPermission(Permission):
|
||||
def __init__(self, role_id):
|
||||
needs = [RoleNeed('admin'), RoleMemberNeed(role_id)]
|
||||
needs = [RoleNeed("admin"), RoleMemberNeed(role_id)]
|
||||
super(RoleMemberPermission, self).__init__(*needs)
|
||||
|
||||
|
||||
AuthorityCreator = namedtuple('authority', ['method', 'value'])
|
||||
AuthorityCreatorNeed = partial(AuthorityCreator, 'authorityUse')
|
||||
AuthorityCreator = namedtuple("authority", ["method", "value"])
|
||||
AuthorityCreatorNeed = partial(AuthorityCreator, "authorityUse")
|
||||
|
||||
AuthorityOwner = namedtuple('authority', ['method', 'value'])
|
||||
AuthorityOwnerNeed = partial(AuthorityOwner, 'role')
|
||||
AuthorityOwner = namedtuple("authority", ["method", "value"])
|
||||
AuthorityOwnerNeed = partial(AuthorityOwner, "role")
|
||||
|
||||
|
||||
class AuthorityPermission(Permission):
|
||||
def __init__(self, authority_id, roles):
|
||||
needs = [RoleNeed('admin'), AuthorityCreatorNeed(str(authority_id))]
|
||||
needs = [RoleNeed("admin"), AuthorityCreatorNeed(str(authority_id))]
|
||||
for r in roles:
|
||||
needs.append(AuthorityOwnerNeed(str(r)))
|
||||
|
||||
|
@ -39,13 +39,13 @@ def get_rsa_public_key(n, e):
|
||||
:param e:
|
||||
:return: a RSA Public Key in PEM format
|
||||
"""
|
||||
n = int(binascii.hexlify(jwt.utils.base64url_decode(bytes(n, 'utf-8'))), 16)
|
||||
e = int(binascii.hexlify(jwt.utils.base64url_decode(bytes(e, 'utf-8'))), 16)
|
||||
n = int(binascii.hexlify(jwt.utils.base64url_decode(bytes(n, "utf-8"))), 16)
|
||||
e = int(binascii.hexlify(jwt.utils.base64url_decode(bytes(e, "utf-8"))), 16)
|
||||
|
||||
pub = RSAPublicNumbers(e, n).public_key(default_backend())
|
||||
return pub.public_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo,
|
||||
)
|
||||
|
||||
|
||||
@ -57,28 +57,27 @@ def create_token(user, aid=None, ttl=None):
|
||||
:param user:
|
||||
:return:
|
||||
"""
|
||||
expiration_delta = timedelta(days=int(current_app.config.get('LEMUR_TOKEN_EXPIRATION', 1)))
|
||||
payload = {
|
||||
'iat': datetime.utcnow(),
|
||||
'exp': datetime.utcnow() + expiration_delta
|
||||
}
|
||||
expiration_delta = timedelta(
|
||||
days=int(current_app.config.get("LEMUR_TOKEN_EXPIRATION", 1))
|
||||
)
|
||||
payload = {"iat": datetime.utcnow(), "exp": datetime.utcnow() + expiration_delta}
|
||||
|
||||
# Handle Just a User ID & User Object.
|
||||
if isinstance(user, int):
|
||||
payload['sub'] = user
|
||||
payload["sub"] = user
|
||||
else:
|
||||
payload['sub'] = user.id
|
||||
payload["sub"] = user.id
|
||||
if aid is not None:
|
||||
payload['aid'] = aid
|
||||
payload["aid"] = aid
|
||||
# Custom TTLs are only supported on Access Keys.
|
||||
if ttl is not None and aid is not None:
|
||||
# Tokens that are forever until revoked.
|
||||
if ttl == -1:
|
||||
del payload['exp']
|
||||
del payload["exp"]
|
||||
else:
|
||||
payload['exp'] = ttl
|
||||
token = jwt.encode(payload, current_app.config['LEMUR_TOKEN_SECRET'])
|
||||
return token.decode('unicode_escape')
|
||||
payload["exp"] = ttl
|
||||
token = jwt.encode(payload, current_app.config["LEMUR_TOKEN_SECRET"])
|
||||
return token.decode("unicode_escape")
|
||||
|
||||
|
||||
def login_required(f):
|
||||
@ -88,49 +87,54 @@ def login_required(f):
|
||||
:param f:
|
||||
:return:
|
||||
"""
|
||||
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
if not request.headers.get('Authorization'):
|
||||
response = jsonify(message='Missing authorization header')
|
||||
if not request.headers.get("Authorization"):
|
||||
response = jsonify(message="Missing authorization header")
|
||||
response.status_code = 401
|
||||
return response
|
||||
|
||||
try:
|
||||
token = request.headers.get('Authorization').split()[1]
|
||||
token = request.headers.get("Authorization").split()[1]
|
||||
except Exception as e:
|
||||
return dict(message='Token is invalid'), 403
|
||||
return dict(message="Token is invalid"), 403
|
||||
|
||||
try:
|
||||
payload = jwt.decode(token, current_app.config['LEMUR_TOKEN_SECRET'])
|
||||
payload = jwt.decode(token, current_app.config["LEMUR_TOKEN_SECRET"])
|
||||
except jwt.DecodeError:
|
||||
return dict(message='Token is invalid'), 403
|
||||
return dict(message="Token is invalid"), 403
|
||||
except jwt.ExpiredSignatureError:
|
||||
return dict(message='Token has expired'), 403
|
||||
return dict(message="Token has expired"), 403
|
||||
except jwt.InvalidTokenError:
|
||||
return dict(message='Token is invalid'), 403
|
||||
return dict(message="Token is invalid"), 403
|
||||
|
||||
if 'aid' in payload:
|
||||
access_key = api_key_service.get(payload['aid'])
|
||||
if "aid" in payload:
|
||||
access_key = api_key_service.get(payload["aid"])
|
||||
if access_key.revoked:
|
||||
return dict(message='Token has been revoked'), 403
|
||||
return dict(message="Token has been revoked"), 403
|
||||
if access_key.ttl != -1:
|
||||
current_time = datetime.utcnow()
|
||||
expired_time = datetime.fromtimestamp(access_key.issued_at + access_key.ttl)
|
||||
expired_time = datetime.fromtimestamp(
|
||||
access_key.issued_at + access_key.ttl
|
||||
)
|
||||
if current_time >= expired_time:
|
||||
return dict(message='Token has expired'), 403
|
||||
return dict(message="Token has expired"), 403
|
||||
|
||||
user = user_service.get(payload['sub'])
|
||||
user = user_service.get(payload["sub"])
|
||||
|
||||
if not user.active:
|
||||
return dict(message='User is not currently active'), 403
|
||||
return dict(message="User is not currently active"), 403
|
||||
|
||||
g.current_user = user
|
||||
|
||||
if not g.current_user:
|
||||
return dict(message='You are not logged in'), 403
|
||||
return dict(message="You are not logged in"), 403
|
||||
|
||||
# Tell Flask-Principal the identity changed
|
||||
identity_changed.send(current_app._get_current_object(), identity=Identity(g.current_user.id))
|
||||
identity_changed.send(
|
||||
current_app._get_current_object(), identity=Identity(g.current_user.id)
|
||||
)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
||||
@ -144,18 +148,18 @@ def fetch_token_header(token):
|
||||
:param token:
|
||||
:return: :raise jwt.DecodeError:
|
||||
"""
|
||||
token = token.encode('utf-8')
|
||||
token = token.encode("utf-8")
|
||||
try:
|
||||
signing_input, crypto_segment = token.rsplit(b'.', 1)
|
||||
header_segment, payload_segment = signing_input.split(b'.', 1)
|
||||
signing_input, crypto_segment = token.rsplit(b".", 1)
|
||||
header_segment, payload_segment = signing_input.split(b".", 1)
|
||||
except ValueError:
|
||||
raise jwt.DecodeError('Not enough segments')
|
||||
raise jwt.DecodeError("Not enough segments")
|
||||
|
||||
try:
|
||||
return json.loads(jwt.utils.base64url_decode(header_segment).decode('utf-8'))
|
||||
return json.loads(jwt.utils.base64url_decode(header_segment).decode("utf-8"))
|
||||
except TypeError as e:
|
||||
current_app.logger.exception(e)
|
||||
raise jwt.DecodeError('Invalid header padding')
|
||||
raise jwt.DecodeError("Invalid header padding")
|
||||
|
||||
|
||||
@identity_loaded.connect
|
||||
@ -174,13 +178,13 @@ def on_identity_loaded(sender, identity):
|
||||
identity.provides.add(UserNeed(identity.id))
|
||||
|
||||
# identity with the roles that the user provides
|
||||
if hasattr(user, 'roles'):
|
||||
if hasattr(user, "roles"):
|
||||
for role in user.roles:
|
||||
identity.provides.add(RoleNeed(role.name))
|
||||
identity.provides.add(RoleMemberNeed(role.id))
|
||||
|
||||
# apply ownership for authorities
|
||||
if hasattr(user, 'authorities'):
|
||||
if hasattr(user, "authorities"):
|
||||
for authority in user.authorities:
|
||||
identity.provides.add(AuthorityCreatorNeed(authority.id))
|
||||
|
||||
@ -191,6 +195,7 @@ class AuthenticatedResource(Resource):
|
||||
"""
|
||||
Inherited by all resources that need to be protected by authentication.
|
||||
"""
|
||||
|
||||
method_decorators = [login_required]
|
||||
|
||||
def __init__(self):
|
||||
|
@ -24,11 +24,13 @@ from lemur.auth.service import create_token, fetch_token_header, get_rsa_public_
|
||||
from lemur.auth import ldap
|
||||
|
||||
|
||||
mod = Blueprint('auth', __name__)
|
||||
mod = Blueprint("auth", __name__)
|
||||
api = Api(mod)
|
||||
|
||||
|
||||
def exchange_for_access_token(code, redirect_uri, client_id, secret, access_token_url=None, verify_cert=True):
|
||||
def exchange_for_access_token(
|
||||
code, redirect_uri, client_id, secret, access_token_url=None, verify_cert=True
|
||||
):
|
||||
"""
|
||||
Exchanges authorization code for access token.
|
||||
|
||||
@ -43,28 +45,32 @@ def exchange_for_access_token(code, redirect_uri, client_id, secret, access_toke
|
||||
"""
|
||||
# take the information we have received from the provider to create a new request
|
||||
params = {
|
||||
'grant_type': 'authorization_code',
|
||||
'scope': 'openid email profile address',
|
||||
'code': code,
|
||||
'redirect_uri': redirect_uri,
|
||||
'client_id': client_id
|
||||
"grant_type": "authorization_code",
|
||||
"scope": "openid email profile address",
|
||||
"code": code,
|
||||
"redirect_uri": redirect_uri,
|
||||
"client_id": client_id,
|
||||
}
|
||||
|
||||
# the secret and cliendId will be given to you when you signup for the provider
|
||||
token = '{0}:{1}'.format(client_id, secret)
|
||||
token = "{0}:{1}".format(client_id, secret)
|
||||
|
||||
basic = base64.b64encode(bytes(token, 'utf-8'))
|
||||
basic = base64.b64encode(bytes(token, "utf-8"))
|
||||
headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'authorization': 'basic {0}'.format(basic.decode('utf-8'))
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"authorization": "basic {0}".format(basic.decode("utf-8")),
|
||||
}
|
||||
|
||||
# exchange authorization code for access token.
|
||||
r = requests.post(access_token_url, headers=headers, params=params, verify=verify_cert)
|
||||
r = requests.post(
|
||||
access_token_url, headers=headers, params=params, verify=verify_cert
|
||||
)
|
||||
if r.status_code == 400:
|
||||
r = requests.post(access_token_url, headers=headers, data=params, verify=verify_cert)
|
||||
id_token = r.json()['id_token']
|
||||
access_token = r.json()['access_token']
|
||||
r = requests.post(
|
||||
access_token_url, headers=headers, data=params, verify=verify_cert
|
||||
)
|
||||
id_token = r.json()["id_token"]
|
||||
access_token = r.json()["access_token"]
|
||||
|
||||
return id_token, access_token
|
||||
|
||||
@ -83,23 +89,25 @@ def validate_id_token(id_token, client_id, jwks_url):
|
||||
|
||||
# retrieve the key material as specified by the token header
|
||||
r = requests.get(jwks_url)
|
||||
for key in r.json()['keys']:
|
||||
if key['kid'] == header_data['kid']:
|
||||
secret = get_rsa_public_key(key['n'], key['e'])
|
||||
algo = header_data['alg']
|
||||
for key in r.json()["keys"]:
|
||||
if key["kid"] == header_data["kid"]:
|
||||
secret = get_rsa_public_key(key["n"], key["e"])
|
||||
algo = header_data["alg"]
|
||||
break
|
||||
else:
|
||||
return dict(message='Key not found'), 401
|
||||
return dict(message="Key not found"), 401
|
||||
|
||||
# validate your token based on the key it was signed with
|
||||
try:
|
||||
jwt.decode(id_token, secret.decode('utf-8'), algorithms=[algo], audience=client_id)
|
||||
jwt.decode(
|
||||
id_token, secret.decode("utf-8"), algorithms=[algo], audience=client_id
|
||||
)
|
||||
except jwt.DecodeError:
|
||||
return dict(message='Token is invalid'), 401
|
||||
return dict(message="Token is invalid"), 401
|
||||
except jwt.ExpiredSignatureError:
|
||||
return dict(message='Token has expired'), 401
|
||||
return dict(message="Token has expired"), 401
|
||||
except jwt.InvalidTokenError:
|
||||
return dict(message='Token is invalid'), 401
|
||||
return dict(message="Token is invalid"), 401
|
||||
|
||||
|
||||
def retrieve_user(user_api_url, access_token):
|
||||
@ -110,22 +118,18 @@ def retrieve_user(user_api_url, access_token):
|
||||
:param access_token:
|
||||
:return:
|
||||
"""
|
||||
user_params = dict(access_token=access_token, schema='profile')
|
||||
user_params = dict(access_token=access_token, schema="profile")
|
||||
|
||||
headers = {}
|
||||
|
||||
if current_app.config.get('PING_INCLUDE_BEARER_TOKEN'):
|
||||
headers = {'Authorization': f'Bearer {access_token}'}
|
||||
if current_app.config.get("PING_INCLUDE_BEARER_TOKEN"):
|
||||
headers = {"Authorization": f"Bearer {access_token}"}
|
||||
|
||||
# retrieve information about the current user.
|
||||
r = requests.get(
|
||||
user_api_url,
|
||||
params=user_params,
|
||||
headers=headers,
|
||||
)
|
||||
r = requests.get(user_api_url, params=user_params, headers=headers)
|
||||
profile = r.json()
|
||||
|
||||
user = user_service.get_by_email(profile['email'])
|
||||
user = user_service.get_by_email(profile["email"])
|
||||
return user, profile
|
||||
|
||||
|
||||
@ -138,31 +142,44 @@ def create_user_roles(profile):
|
||||
roles = []
|
||||
|
||||
# update their google 'roles'
|
||||
if 'googleGroups' in profile:
|
||||
for group in profile['googleGroups']:
|
||||
if "googleGroups" in profile:
|
||||
for group in profile["googleGroups"]:
|
||||
role = role_service.get_by_name(group)
|
||||
if not role:
|
||||
role = role_service.create(group, description='This is a google group based role created by Lemur', third_party=True)
|
||||
role = role_service.create(
|
||||
group,
|
||||
description="This is a google group based role created by Lemur",
|
||||
third_party=True,
|
||||
)
|
||||
if not role.third_party:
|
||||
role = role_service.set_third_party(role.id, third_party_status=True)
|
||||
roles.append(role)
|
||||
else:
|
||||
current_app.logger.warning("'googleGroups' not sent by identity provider, no specific roles will assigned to the user.")
|
||||
current_app.logger.warning(
|
||||
"'googleGroups' not sent by identity provider, no specific roles will assigned to the user."
|
||||
)
|
||||
|
||||
role = role_service.get_by_name(profile['email'])
|
||||
role = role_service.get_by_name(profile["email"])
|
||||
|
||||
if not role:
|
||||
role = role_service.create(profile['email'], description='This is a user specific role', third_party=True)
|
||||
role = role_service.create(
|
||||
profile["email"],
|
||||
description="This is a user specific role",
|
||||
third_party=True,
|
||||
)
|
||||
if not role.third_party:
|
||||
role = role_service.set_third_party(role.id, third_party_status=True)
|
||||
|
||||
roles.append(role)
|
||||
|
||||
# every user is an operator (tied to a default role)
|
||||
if current_app.config.get('LEMUR_DEFAULT_ROLE'):
|
||||
default = role_service.get_by_name(current_app.config['LEMUR_DEFAULT_ROLE'])
|
||||
if current_app.config.get("LEMUR_DEFAULT_ROLE"):
|
||||
default = role_service.get_by_name(current_app.config["LEMUR_DEFAULT_ROLE"])
|
||||
if not default:
|
||||
default = role_service.create(current_app.config['LEMUR_DEFAULT_ROLE'], description='This is the default Lemur role.')
|
||||
default = role_service.create(
|
||||
current_app.config["LEMUR_DEFAULT_ROLE"],
|
||||
description="This is the default Lemur role.",
|
||||
)
|
||||
if not default.third_party:
|
||||
role_service.set_third_party(default.id, third_party_status=True)
|
||||
roles.append(default)
|
||||
@ -181,12 +198,12 @@ def update_user(user, profile, roles):
|
||||
# if we get an sso user create them an account
|
||||
if not user:
|
||||
user = user_service.create(
|
||||
profile['email'],
|
||||
profile["email"],
|
||||
get_psuedo_random_string(),
|
||||
profile['email'],
|
||||
profile["email"],
|
||||
True,
|
||||
profile.get('thumbnailPhotoUrl'),
|
||||
roles
|
||||
profile.get("thumbnailPhotoUrl"),
|
||||
roles,
|
||||
)
|
||||
|
||||
else:
|
||||
@ -198,11 +215,11 @@ def update_user(user, profile, roles):
|
||||
# update any changes to the user
|
||||
user_service.update(
|
||||
user.id,
|
||||
profile['email'],
|
||||
profile['email'],
|
||||
profile["email"],
|
||||
profile["email"],
|
||||
True,
|
||||
profile.get('thumbnailPhotoUrl'), # profile isn't google+ enabled
|
||||
roles
|
||||
profile.get("thumbnailPhotoUrl"), # profile isn't google+ enabled
|
||||
roles,
|
||||
)
|
||||
|
||||
|
||||
@ -223,6 +240,7 @@ class Login(Resource):
|
||||
on your uses cases but. It is important to not that there is currently no build in method to revoke a users token \
|
||||
and force re-authentication.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.reqparse = reqparse.RequestParser()
|
||||
super(Login, self).__init__()
|
||||
@ -263,23 +281,26 @@ class Login(Resource):
|
||||
:statuscode 401: invalid credentials
|
||||
:statuscode 200: no error
|
||||
"""
|
||||
self.reqparse.add_argument('username', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument('password', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument("username", type=str, required=True, location="json")
|
||||
self.reqparse.add_argument("password", type=str, required=True, location="json")
|
||||
|
||||
args = self.reqparse.parse_args()
|
||||
|
||||
if '@' in args['username']:
|
||||
user = user_service.get_by_email(args['username'])
|
||||
if "@" in args["username"]:
|
||||
user = user_service.get_by_email(args["username"])
|
||||
else:
|
||||
user = user_service.get_by_username(args['username'])
|
||||
user = user_service.get_by_username(args["username"])
|
||||
|
||||
# default to local authentication
|
||||
if user and user.check_password(args['password']) and user.active:
|
||||
if user and user.check_password(args["password"]) and user.active:
|
||||
# Tell Flask-Principal the identity changed
|
||||
identity_changed.send(current_app._get_current_object(),
|
||||
identity=Identity(user.id))
|
||||
identity_changed.send(
|
||||
current_app._get_current_object(), identity=Identity(user.id)
|
||||
)
|
||||
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': SUCCESS_METRIC_STATUS})
|
||||
metrics.send(
|
||||
"login", "counter", 1, metric_tags={"status": SUCCESS_METRIC_STATUS}
|
||||
)
|
||||
return dict(token=create_token(user))
|
||||
|
||||
# try ldap login
|
||||
@ -289,19 +310,29 @@ class Login(Resource):
|
||||
user = ldap_principal.authenticate()
|
||||
if user and user.active:
|
||||
# Tell Flask-Principal the identity changed
|
||||
identity_changed.send(current_app._get_current_object(),
|
||||
identity=Identity(user.id))
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': SUCCESS_METRIC_STATUS})
|
||||
identity_changed.send(
|
||||
current_app._get_current_object(), identity=Identity(user.id)
|
||||
)
|
||||
metrics.send(
|
||||
"login",
|
||||
"counter",
|
||||
1,
|
||||
metric_tags={"status": SUCCESS_METRIC_STATUS},
|
||||
)
|
||||
return dict(token=create_token(user))
|
||||
except Exception as e:
|
||||
current_app.logger.error("ldap error: {0}".format(e))
|
||||
ldap_message = 'ldap error: %s' % e
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': FAILURE_METRIC_STATUS})
|
||||
return dict(message=ldap_message), 403
|
||||
current_app.logger.error("ldap error: {0}".format(e))
|
||||
ldap_message = "ldap error: %s" % e
|
||||
metrics.send(
|
||||
"login", "counter", 1, metric_tags={"status": FAILURE_METRIC_STATUS}
|
||||
)
|
||||
return dict(message=ldap_message), 403
|
||||
|
||||
# if not valid user - no certificates for you
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': FAILURE_METRIC_STATUS})
|
||||
return dict(message='The supplied credentials are invalid'), 403
|
||||
metrics.send(
|
||||
"login", "counter", 1, metric_tags={"status": FAILURE_METRIC_STATUS}
|
||||
)
|
||||
return dict(message="The supplied credentials are invalid"), 403
|
||||
|
||||
|
||||
class Ping(Resource):
|
||||
@ -314,36 +345,39 @@ class Ping(Resource):
|
||||
provider uses for its callbacks.
|
||||
2. Add or change the Lemur AngularJS Configuration to point to your new provider
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.reqparse = reqparse.RequestParser()
|
||||
super(Ping, self).__init__()
|
||||
|
||||
def get(self):
|
||||
return 'Redirecting...'
|
||||
return "Redirecting..."
|
||||
|
||||
def post(self):
|
||||
self.reqparse.add_argument('clientId', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument('redirectUri', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument('code', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument("clientId", type=str, required=True, location="json")
|
||||
self.reqparse.add_argument(
|
||||
"redirectUri", type=str, required=True, location="json"
|
||||
)
|
||||
self.reqparse.add_argument("code", type=str, required=True, location="json")
|
||||
|
||||
args = self.reqparse.parse_args()
|
||||
|
||||
# you can either discover these dynamically or simply configure them
|
||||
access_token_url = current_app.config.get('PING_ACCESS_TOKEN_URL')
|
||||
user_api_url = current_app.config.get('PING_USER_API_URL')
|
||||
access_token_url = current_app.config.get("PING_ACCESS_TOKEN_URL")
|
||||
user_api_url = current_app.config.get("PING_USER_API_URL")
|
||||
|
||||
secret = current_app.config.get('PING_SECRET')
|
||||
secret = current_app.config.get("PING_SECRET")
|
||||
|
||||
id_token, access_token = exchange_for_access_token(
|
||||
args['code'],
|
||||
args['redirectUri'],
|
||||
args['clientId'],
|
||||
args["code"],
|
||||
args["redirectUri"],
|
||||
args["clientId"],
|
||||
secret,
|
||||
access_token_url=access_token_url
|
||||
access_token_url=access_token_url,
|
||||
)
|
||||
|
||||
jwks_url = current_app.config.get('PING_JWKS_URL')
|
||||
error_code = validate_id_token(id_token, args['clientId'], jwks_url)
|
||||
jwks_url = current_app.config.get("PING_JWKS_URL")
|
||||
error_code = validate_id_token(id_token, args["clientId"], jwks_url)
|
||||
if error_code:
|
||||
return error_code
|
||||
user, profile = retrieve_user(user_api_url, access_token)
|
||||
@ -351,13 +385,19 @@ class Ping(Resource):
|
||||
update_user(user, profile, roles)
|
||||
|
||||
if not user or not user.active:
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': FAILURE_METRIC_STATUS})
|
||||
return dict(message='The supplied credentials are invalid'), 403
|
||||
metrics.send(
|
||||
"login", "counter", 1, metric_tags={"status": FAILURE_METRIC_STATUS}
|
||||
)
|
||||
return dict(message="The supplied credentials are invalid"), 403
|
||||
|
||||
# Tell Flask-Principal the identity changed
|
||||
identity_changed.send(current_app._get_current_object(), identity=Identity(user.id))
|
||||
identity_changed.send(
|
||||
current_app._get_current_object(), identity=Identity(user.id)
|
||||
)
|
||||
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': SUCCESS_METRIC_STATUS})
|
||||
metrics.send(
|
||||
"login", "counter", 1, metric_tags={"status": SUCCESS_METRIC_STATUS}
|
||||
)
|
||||
return dict(token=create_token(user))
|
||||
|
||||
|
||||
@ -367,33 +407,35 @@ class OAuth2(Resource):
|
||||
super(OAuth2, self).__init__()
|
||||
|
||||
def get(self):
|
||||
return 'Redirecting...'
|
||||
return "Redirecting..."
|
||||
|
||||
def post(self):
|
||||
self.reqparse.add_argument('clientId', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument('redirectUri', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument('code', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument("clientId", type=str, required=True, location="json")
|
||||
self.reqparse.add_argument(
|
||||
"redirectUri", type=str, required=True, location="json"
|
||||
)
|
||||
self.reqparse.add_argument("code", type=str, required=True, location="json")
|
||||
|
||||
args = self.reqparse.parse_args()
|
||||
|
||||
# you can either discover these dynamically or simply configure them
|
||||
access_token_url = current_app.config.get('OAUTH2_ACCESS_TOKEN_URL')
|
||||
user_api_url = current_app.config.get('OAUTH2_USER_API_URL')
|
||||
verify_cert = current_app.config.get('OAUTH2_VERIFY_CERT')
|
||||
access_token_url = current_app.config.get("OAUTH2_ACCESS_TOKEN_URL")
|
||||
user_api_url = current_app.config.get("OAUTH2_USER_API_URL")
|
||||
verify_cert = current_app.config.get("OAUTH2_VERIFY_CERT")
|
||||
|
||||
secret = current_app.config.get('OAUTH2_SECRET')
|
||||
secret = current_app.config.get("OAUTH2_SECRET")
|
||||
|
||||
id_token, access_token = exchange_for_access_token(
|
||||
args['code'],
|
||||
args['redirectUri'],
|
||||
args['clientId'],
|
||||
args["code"],
|
||||
args["redirectUri"],
|
||||
args["clientId"],
|
||||
secret,
|
||||
access_token_url=access_token_url,
|
||||
verify_cert=verify_cert
|
||||
verify_cert=verify_cert,
|
||||
)
|
||||
|
||||
jwks_url = current_app.config.get('PING_JWKS_URL')
|
||||
error_code = validate_id_token(id_token, args['clientId'], jwks_url)
|
||||
jwks_url = current_app.config.get("PING_JWKS_URL")
|
||||
error_code = validate_id_token(id_token, args["clientId"], jwks_url)
|
||||
if error_code:
|
||||
return error_code
|
||||
|
||||
@ -402,13 +444,19 @@ class OAuth2(Resource):
|
||||
update_user(user, profile, roles)
|
||||
|
||||
if not user.active:
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': FAILURE_METRIC_STATUS})
|
||||
return dict(message='The supplied credentials are invalid'), 403
|
||||
metrics.send(
|
||||
"login", "counter", 1, metric_tags={"status": FAILURE_METRIC_STATUS}
|
||||
)
|
||||
return dict(message="The supplied credentials are invalid"), 403
|
||||
|
||||
# Tell Flask-Principal the identity changed
|
||||
identity_changed.send(current_app._get_current_object(), identity=Identity(user.id))
|
||||
identity_changed.send(
|
||||
current_app._get_current_object(), identity=Identity(user.id)
|
||||
)
|
||||
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': SUCCESS_METRIC_STATUS})
|
||||
metrics.send(
|
||||
"login", "counter", 1, metric_tags={"status": SUCCESS_METRIC_STATUS}
|
||||
)
|
||||
|
||||
return dict(token=create_token(user))
|
||||
|
||||
@ -419,44 +467,52 @@ class Google(Resource):
|
||||
super(Google, self).__init__()
|
||||
|
||||
def post(self):
|
||||
access_token_url = 'https://accounts.google.com/o/oauth2/token'
|
||||
people_api_url = 'https://www.googleapis.com/plus/v1/people/me/openIdConnect'
|
||||
access_token_url = "https://accounts.google.com/o/oauth2/token"
|
||||
people_api_url = "https://www.googleapis.com/plus/v1/people/me/openIdConnect"
|
||||
|
||||
self.reqparse.add_argument('clientId', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument('redirectUri', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument('code', type=str, required=True, location='json')
|
||||
self.reqparse.add_argument("clientId", type=str, required=True, location="json")
|
||||
self.reqparse.add_argument(
|
||||
"redirectUri", type=str, required=True, location="json"
|
||||
)
|
||||
self.reqparse.add_argument("code", type=str, required=True, location="json")
|
||||
|
||||
args = self.reqparse.parse_args()
|
||||
|
||||
# Step 1. Exchange authorization code for access token
|
||||
payload = {
|
||||
'client_id': args['clientId'],
|
||||
'grant_type': 'authorization_code',
|
||||
'redirect_uri': args['redirectUri'],
|
||||
'code': args['code'],
|
||||
'client_secret': current_app.config.get('GOOGLE_SECRET')
|
||||
"client_id": args["clientId"],
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": args["redirectUri"],
|
||||
"code": args["code"],
|
||||
"client_secret": current_app.config.get("GOOGLE_SECRET"),
|
||||
}
|
||||
|
||||
r = requests.post(access_token_url, data=payload)
|
||||
token = r.json()
|
||||
|
||||
# Step 2. Retrieve information about the current user
|
||||
headers = {'Authorization': 'Bearer {0}'.format(token['access_token'])}
|
||||
headers = {"Authorization": "Bearer {0}".format(token["access_token"])}
|
||||
|
||||
r = requests.get(people_api_url, headers=headers)
|
||||
profile = r.json()
|
||||
|
||||
user = user_service.get_by_email(profile['email'])
|
||||
user = user_service.get_by_email(profile["email"])
|
||||
|
||||
if not (user and user.active):
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': FAILURE_METRIC_STATUS})
|
||||
return dict(message='The supplied credentials are invalid.'), 403
|
||||
metrics.send(
|
||||
"login", "counter", 1, metric_tags={"status": FAILURE_METRIC_STATUS}
|
||||
)
|
||||
return dict(message="The supplied credentials are invalid."), 403
|
||||
|
||||
if user:
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': SUCCESS_METRIC_STATUS})
|
||||
metrics.send(
|
||||
"login", "counter", 1, metric_tags={"status": SUCCESS_METRIC_STATUS}
|
||||
)
|
||||
return dict(token=create_token(user))
|
||||
|
||||
metrics.send('login', 'counter', 1, metric_tags={'status': FAILURE_METRIC_STATUS})
|
||||
metrics.send(
|
||||
"login", "counter", 1, metric_tags={"status": FAILURE_METRIC_STATUS}
|
||||
)
|
||||
|
||||
|
||||
class Providers(Resource):
|
||||
@ -467,47 +523,57 @@ class Providers(Resource):
|
||||
provider = provider.lower()
|
||||
|
||||
if provider == "google":
|
||||
active_providers.append({
|
||||
'name': 'google',
|
||||
'clientId': current_app.config.get("GOOGLE_CLIENT_ID"),
|
||||
'url': api.url_for(Google)
|
||||
})
|
||||
active_providers.append(
|
||||
{
|
||||
"name": "google",
|
||||
"clientId": current_app.config.get("GOOGLE_CLIENT_ID"),
|
||||
"url": api.url_for(Google),
|
||||
}
|
||||
)
|
||||
|
||||
elif provider == "ping":
|
||||
active_providers.append({
|
||||
'name': current_app.config.get("PING_NAME"),
|
||||
'url': current_app.config.get('PING_REDIRECT_URI'),
|
||||
'redirectUri': current_app.config.get("PING_REDIRECT_URI"),
|
||||
'clientId': current_app.config.get("PING_CLIENT_ID"),
|
||||
'responseType': 'code',
|
||||
'scope': ['openid', 'email', 'profile', 'address'],
|
||||
'scopeDelimiter': ' ',
|
||||
'authorizationEndpoint': current_app.config.get("PING_AUTH_ENDPOINT"),
|
||||
'requiredUrlParams': ['scope'],
|
||||
'type': '2.0'
|
||||
})
|
||||
active_providers.append(
|
||||
{
|
||||
"name": current_app.config.get("PING_NAME"),
|
||||
"url": current_app.config.get("PING_REDIRECT_URI"),
|
||||
"redirectUri": current_app.config.get("PING_REDIRECT_URI"),
|
||||
"clientId": current_app.config.get("PING_CLIENT_ID"),
|
||||
"responseType": "code",
|
||||
"scope": ["openid", "email", "profile", "address"],
|
||||
"scopeDelimiter": " ",
|
||||
"authorizationEndpoint": current_app.config.get(
|
||||
"PING_AUTH_ENDPOINT"
|
||||
),
|
||||
"requiredUrlParams": ["scope"],
|
||||
"type": "2.0",
|
||||
}
|
||||
)
|
||||
|
||||
elif provider == "oauth2":
|
||||
active_providers.append({
|
||||
'name': current_app.config.get("OAUTH2_NAME"),
|
||||
'url': current_app.config.get('OAUTH2_REDIRECT_URI'),
|
||||
'redirectUri': current_app.config.get("OAUTH2_REDIRECT_URI"),
|
||||
'clientId': current_app.config.get("OAUTH2_CLIENT_ID"),
|
||||
'responseType': 'code',
|
||||
'scope': ['openid', 'email', 'profile', 'groups'],
|
||||
'scopeDelimiter': ' ',
|
||||
'authorizationEndpoint': current_app.config.get("OAUTH2_AUTH_ENDPOINT"),
|
||||
'requiredUrlParams': ['scope', 'state', 'nonce'],
|
||||
'state': 'STATE',
|
||||
'nonce': get_psuedo_random_string(),
|
||||
'type': '2.0'
|
||||
})
|
||||
active_providers.append(
|
||||
{
|
||||
"name": current_app.config.get("OAUTH2_NAME"),
|
||||
"url": current_app.config.get("OAUTH2_REDIRECT_URI"),
|
||||
"redirectUri": current_app.config.get("OAUTH2_REDIRECT_URI"),
|
||||
"clientId": current_app.config.get("OAUTH2_CLIENT_ID"),
|
||||
"responseType": "code",
|
||||
"scope": ["openid", "email", "profile", "groups"],
|
||||
"scopeDelimiter": " ",
|
||||
"authorizationEndpoint": current_app.config.get(
|
||||
"OAUTH2_AUTH_ENDPOINT"
|
||||
),
|
||||
"requiredUrlParams": ["scope", "state", "nonce"],
|
||||
"state": "STATE",
|
||||
"nonce": get_psuedo_random_string(),
|
||||
"type": "2.0",
|
||||
}
|
||||
)
|
||||
|
||||
return active_providers
|
||||
|
||||
|
||||
api.add_resource(Login, '/auth/login', endpoint='login')
|
||||
api.add_resource(Ping, '/auth/ping', endpoint='ping')
|
||||
api.add_resource(Google, '/auth/google', endpoint='google')
|
||||
api.add_resource(OAuth2, '/auth/oauth2', endpoint='oauth2')
|
||||
api.add_resource(Providers, '/auth/providers', endpoint='providers')
|
||||
api.add_resource(Login, "/auth/login", endpoint="login")
|
||||
api.add_resource(Ping, "/auth/ping", endpoint="ping")
|
||||
api.add_resource(Google, "/auth/google", endpoint="google")
|
||||
api.add_resource(OAuth2, "/auth/oauth2", endpoint="oauth2")
|
||||
api.add_resource(Providers, "/auth/providers", endpoint="providers")
|
||||
|
Reference in New Issue
Block a user