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" 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"), } 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"])} r = requests.get(people_api_url, headers=headers) profile = r.json() user = user_service.get_by_email(profile["email"]) if user: metrics.send("successful_login", "counter", 1) return dict(token=create_token(user))
def test_role_put_with_data_and_user(client, session): from lemur.auth.service import create_token user = UserFactory() role = RoleFactory(users=[user]) role1 = RoleFactory() user1 = UserFactory() session.commit() headers = { 'Authorization': 'Basic ' + create_token(user), 'Content-Type': 'application/json' } data = { 'users': [{ 'id': user1.id }, { 'id': user.id }], 'id': role.id, 'name': role.name } assert client.put(api.url_for(Roles, role_id=role.id), data=json.dumps(data), headers=headers).status_code == 200 assert client.get(api.url_for(RolesList), data={}, headers=headers).json['total'] == 1
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' 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') } 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'])} r = requests.get(people_api_url, headers=headers) profile = r.json() user = user_service.get_by_email(profile['email']) if user: metrics.send('successful_login', 'counter', 1) return dict(token=create_token(user))
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' 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') } 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'])} r = requests.get(people_api_url, headers=headers) profile = r.json() user = user_service.get_by_email(profile['email']) if user: return dict(token=create_token(user))
def test_role_put_with_data_and_user(client, session): from lemur.auth.service import create_token user = UserFactory() role = RoleFactory(users=[user]) role1 = RoleFactory() user1 = UserFactory() session.commit() headers = { "Authorization": "Basic " + create_token(user), "Content-Type": "application/json", } data = { "users": [{"id": user1.id}, {"id": user.id}], "id": role.id, "name": role.name, } assert ( client.put( api.url_for(Roles, role_id=role.id), data=json.dumps(data), headers=headers ).status_code == 200 ) assert ( client.get(api.url_for(RolesList), data={}, headers=headers).json["total"] > 1 )
def post(self): """ .. http:post:: /auth/login Login with username:password **Example request**: .. sourcecode:: http POST /auth/login HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "username": "******", "password": "******" } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "token": "12343243243" } :arg username: username :arg password: password :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') args = self.reqparse.parse_args() if '@' in args['username']: user = user_service.get_by_email(args['username']) else: user = user_service.get_by_username(args['username']) if user and user.check_password(args['password']): # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) return dict(token=create_token(user)) return dict(message='The supplied credentials are invalid'), 401
def admin_user(session): u = UserFactory() admin_role = RoleFactory(name='admin') u.roles.append(admin_role) session.commit() user_token = create_token(u) token = {'Authorization': 'Basic ' + user_token} return {'user': u, 'token': token}
def admin_user(session): u = UserFactory() admin_role = RoleFactory(name="admin") u.roles.append(admin_role) session.commit() user_token = create_token(u) token = {"Authorization": "Basic " + user_token} return {"user": u, "token": token}
def post(self): access_token_url = "https://accounts.google.com/o/oauth2/token" user_info_url = "https://www.googleapis.com/oauth2/v1/userinfo" 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"), "scope": "email", } 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"])} r = requests.get(user_info_url, headers=headers) profile = r.json() 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 if user: 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})
def post(self, data=None): """ .. http:post:: /keys Creates an API Key. **Example request**: .. sourcecode:: http POST /keys HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "name": "my custom name", "user_id": 1, "ttl": -1 } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "jwt": "" } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ if not ApiKeyCreatorPermission().can(): if data["user"]["id"] != g.current_user.id: return ( dict( message="You are not authorized to create tokens for: {0}".format( data["user"]["username"] ) ), 403, ) access_token = service.create( name=data["name"], user_id=data["user"]["id"], ttl=data["ttl"], revoked=False, issued_at=int(datetime.utcnow().timestamp()), ) return dict( jwt=create_token(access_token.user_id, access_token.id, access_token.ttl) )
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") 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") secret = current_app.config.get("OAUTH2_SECRET") id_token, access_token = exchange_for_access_token( args["code"], args["redirectUri"], args["clientId"], secret, access_token_url=access_token_url, verify_cert=verify_cert, ) jwks_url = current_app.config.get("OAUTH2_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) roles = create_user_roles(profile) 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 # 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}) return dict(token=create_token(user))
def put(self, uid, aid, data=None): """ .. http:put:: /users/1/keys/1 update one api key **Example request**: .. sourcecode:: http PUT /users/1/keys/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript Content-Type: application/json;charset=UTF-8 { "name": "new_name", "revoked": false, "ttl": -1 } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "jwt": "" } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ if uid != g.current_user.id: if not ApiKeyCreatorPermission().can(): return dict( message="You are not authorized to view this token!"), 403 access_key = service.get(aid) if access_key is None: return dict(message="This token does not exist!"), 404 if access_key.user_id != uid: return dict( message="You are not authorized to update this token!"), 403 service.update(access_key, name=data["name"], revoked=data["revoked"], ttl=data["ttl"]) return dict(jwt=create_token(access_key.user_id, access_key.id, access_key.ttl))
def post(self): """ .. http:post:: /auth/login Login with username:password **Example request**: .. sourcecode:: http POST /auth/login HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "username": "******", "password": "******" } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "token": "12343243243" } :arg username: username :arg password: password :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') args = self.reqparse.parse_args() if '@' in args['username']: user = user_service.get_by_email(args['username']) else: user = user_service.get_by_username(args['username']) if user and user.check_password(args['password']): # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) metrics.send('successful_login', 'counter', 1) return dict(token=create_token(user)) metrics.send('invalid_login', 'counter', 1) return dict(message='The supplied credentials are invalid'), 401
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') 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') secret = current_app.config.get('OAUTH2_SECRET') id_token, access_token = exchange_for_access_token( args['code'], args['redirectUri'], args['clientId'], secret, access_token_url=access_token_url, verify_cert=verify_cert) jwks_url = current_app.config.get('PING_JWKS_URL') validate_id_token(id_token, args['clientId'], jwks_url) user, profile = retrieve_user(user_api_url, access_token) roles = create_user_roles(profile) 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 # 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}) return dict(token=create_token(user))
def create(uid, name, ttl): """ Create a new api key for a user. :return: """ print("[+] Creating a new api key.") key = api_key_service.create(user_id=uid, name=name, ttl=ttl, issued_at=int(datetime.utcnow().timestamp()), revoked=False) print("[+] Successfully created a new api key. Generating a JWT...") jwt = create_token(uid, key.id, key.ttl) print("[+] Your JWT is: {jwt}".format(jwt=jwt))
def put(self, uid, aid, data=None): """ .. http:put:: /users/1/keys/1 update one api key **Example request**: .. sourcecode:: http PUT /users/1/keys/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "name": "new_name", "revoked": false, "ttl": -1 } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "jwt": "" } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ if uid != g.current_user.id: if not ApiKeyCreatorPermission().can(): return dict(message="You are not authorized to view this token!"), 403 access_key = service.get(aid) if access_key is None: return dict(message="This token does not exist!"), 404 if access_key.user_id != uid: return dict(message="You are not authorized to update this token!"), 403 service.update(access_key, name=data['name'], revoked=data['revoked'], ttl=data['ttl']) return dict(jwt=create_token(access_key.user_id, access_key.id, access_key.ttl))
def get(self, uid, aid): """ .. http:get:: /users/1/keys/1 Fetch one api key **Example request**: .. sourcecode:: http GET /users/1/api_keys/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "jwt": "" } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ if uid != g.current_user.id: if not ApiKeyCreatorPermission().can(): return dict( message="You are not authorized to view this token!"), 403 access_key = service.get(aid) if access_key is None: return dict(message="This token does not exist!"), 404 if access_key.user_id != uid: return dict( message="You are not authorized to view this token!"), 403 return dict(jwt=create_token(access_key.user_id, access_key.id, access_key.ttl))
def post(self, data=None): """ .. http:post:: /keys Creates an API Key. **Example request**: .. sourcecode:: http POST /keys HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "name": "my custom name", "user_id": 1, "ttl": -1 } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "jwt": "" } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ if not ApiKeyCreatorPermission().can(): if data['user']['id'] != g.current_user.id: return dict(message="You are not authorized to create tokens for: {0}".format(data['user']['username'])), 403 access_token = service.create(name=data['name'], user_id=data['user']['id'], ttl=data['ttl'], revoked=False, issued_at=int(datetime.utcnow().timestamp())) return dict(jwt=create_token(access_token.user_id, access_token.id, access_token.ttl))
def get(self, uid, aid): """ .. http:get:: /users/1/keys/1 Fetch one api key **Example request**: .. sourcecode:: http GET /users/1/api_keys/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "jwt": "" } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ if uid != g.current_user.id: if not ApiKeyCreatorPermission().can(): return dict(message="You are not authorized to view this token!"), 403 access_key = service.get(aid) if access_key is None: return dict(message="This token does not exist!"), 404 if access_key.user_id != uid: return dict(message="You are not authorized to view this token!"), 403 return dict(jwt=create_token(access_key.user_id, access_key.id, access_key.ttl))
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') 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') secret = current_app.config.get('OAUTH2_SECRET') id_token, access_token = exchange_for_access_token( args['code'], args['redirectUri'], args['clientId'], secret, access_token_url=access_token_url, verify_cert=verify_cert ) jwks_url = current_app.config.get('PING_JWKS_URL') validate_id_token(id_token, args['clientId'], jwks_url) user, profile = retrieve_user(user_api_url, access_token) roles = create_user_roles(profile) 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 # 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}) return dict(token=create_token(user))
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' 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') } 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'])} r = requests.get(people_api_url, headers=headers) profile = r.json() 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 if user: 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})
def test_role_put_with_data_and_user(client, session): from lemur.auth.service import create_token user = UserFactory() role = RoleFactory(users=[user]) role1 = RoleFactory() user1 = UserFactory() session.commit() headers = { 'Authorization': 'Basic ' + create_token(user), 'Content-Type': 'application/json' } data = { 'users': [ {'id': user1.id}, {'id': user.id} ], 'id': role.id, 'name': role.name } assert client.put(api.url_for(Roles, role_id=role.id), data=json.dumps(data), headers=headers).status_code == 200 assert client.get(api.url_for(RolesList), data={}, headers=headers).json['total'] > 1
def user(session): u = UserFactory() session.commit() user_token = create_token(u) token = {'Authorization': 'Basic ' + user_token} return {'user': u, 'token': token}
def post(self): """ .. http:post:: /auth/login Login with username:password **Example request**: .. sourcecode:: http POST /auth/login HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "username": "******", "password": "******" } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "token": "12343243243" } :arg username: username :arg password: password :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') args = self.reqparse.parse_args() if '@' in args['username']: user = user_service.get_by_email(args['username']) else: user = user_service.get_by_username(args['username']) # default to local authentication 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)) metrics.send('login', 'counter', 1, metric_tags={'status': SUCCESS_METRIC_STATUS}) return dict(token=create_token(user)) # try ldap login if current_app.config.get("LDAP_AUTH"): try: ldap_principal = ldap.LdapPrincipal(args) 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}) 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 # 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
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') args = self.reqparse.parse_args() # take the information we have received from the provider to create a new request params = { 'client_id': args['clientId'], 'grant_type': 'authorization_code', 'scope': 'openid email profile address', 'redirect_uri': args['redirectUri'], 'code': args['code'] } # 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') # the secret and cliendId will be given to you when you signup for the provider basic = base64.b64encode('{0}:{1}'.format( args['clientId'], current_app.config.get("PING_SECRET"))) headers = {'Authorization': 'Basic {0}'.format(basic)} # exchange authorization code for access token. r = requests.post(access_token_url, headers=headers, params=params) id_token = r.json()['id_token'] access_token = r.json()['access_token'] # fetch token public key header_data = fetch_token_header(id_token) jwks_url = current_app.config.get('PING_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'] break else: return dict(message='Key not found'), 403 # validate your token based on the key it was signed with try: jwt.decode(id_token, secret, algorithms=[algo], audience=args['clientId']) except jwt.DecodeError: return dict(message='Token is invalid'), 403 except jwt.ExpiredSignatureError: return dict(message='Token has expired'), 403 except jwt.InvalidTokenError: return dict(message='Token is invalid'), 403 user_params = dict(access_token=access_token, schema='profile') # retrieve information about the current user. r = requests.get(user_api_url, params=user_params) profile = r.json() user = user_service.get_by_email(profile['email']) # update their google 'roles' roles = [] 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') roles.append(role) # if we get an sso user create them an account # we still pick a random password in case sso is down if not user: # every user is an operator (tied to a default role) if current_app.config.get('LEMUR_DEFAULT_ROLE'): v = role_service.get_by_name( current_app.config.get('LEMUR_DEFAULT_ROLE')) if v: roles.append(v) user = user_service.create(profile['email'], get_psuedo_random_string(), profile['email'], True, profile.get('thumbnailPhotoUrl'), roles) else: # we add 'lemur' specific roles, so they do not get marked as removed for ur in user.roles: if ur.authority_id: roles.append(ur) # update any changes to the user user_service.update( user.id, profile['email'], profile['email'], True, profile.get('thumbnailPhotoUrl' ), # incase profile isn't google+ enabled roles) # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) return dict(token=create_token(user))
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') args = self.reqparse.parse_args() # take the information we have received from the provider to create a new request params = { 'client_id': args['clientId'], 'grant_type': 'authorization_code', 'scope': 'openid email profile address', 'redirect_uri': args['redirectUri'], 'code': args['code'] } # 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') # the secret and cliendId will be given to you when you signup for the provider basic = base64.b64encode('{0}:{1}'.format(args['clientId'], current_app.config.get("PING_SECRET"))) headers = {'Authorization': 'Basic {0}'.format(basic)} # exchange authorization code for access token. r = requests.post(access_token_url, headers=headers, params=params) id_token = r.json()['id_token'] access_token = r.json()['access_token'] # fetch token public key header_data = fetch_token_header(id_token) jwks_url = current_app.config.get('PING_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'] break else: return dict(message='Key not found'), 403 # validate your token based on the key it was signed with try: jwt.decode(id_token, secret, algorithms=[algo], audience=args['clientId']) except jwt.DecodeError: return dict(message='Token is invalid'), 403 except jwt.ExpiredSignatureError: return dict(message='Token has expired'), 403 except jwt.InvalidTokenError: return dict(message='Token is invalid'), 403 user_params = dict(access_token=access_token, schema='profile') # retrieve information about the current user. r = requests.get(user_api_url, params=user_params) profile = r.json() user = user_service.get_by_email(profile['email']) # update their google 'roles' roles = [] 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') roles.append(role) # if we get an sso user create them an account # we still pick a random password in case sso is down if not user: # every user is an operator (tied to a default role) if current_app.config.get('LEMUR_DEFAULT_ROLE'): v = role_service.get_by_name(current_app.config.get('LEMUR_DEFAULT_ROLE')) if v: roles.append(v) user = user_service.create( profile['email'], get_psuedo_random_string(), profile['email'], True, profile.get('thumbnailPhotoUrl'), roles ) else: # we add 'lemur' specific roles, so they do not get marked as removed for ur in user.roles: if ur.authority_id: roles.append(ur) # update any changes to the user user_service.update( user.id, profile['email'], profile['email'], True, profile.get('thumbnailPhotoUrl'), # incase profile isn't google+ enabled roles ) # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) return dict(token=create_token(user))
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') args = self.reqparse.parse_args() # take the information we have received from the provider to create a new request params = { 'grant_type': 'authorization_code', 'scope': 'openid email profile groups', 'redirect_uri': args['redirectUri'], 'code': args['code'], } # 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', True) # the secret and cliendId will be given to you when you signup for the provider token = '{0}:{1}'.format(args['clientId'], current_app.config.get("OAUTH2_SECRET")) basic = base64.b64encode(bytes(token, 'utf-8')) headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'authorization': 'basic {0}'.format(basic.decode('utf-8')) } # exchange authorization code for access token. # Try Params first 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'] # fetch token public key header_data = fetch_token_header(id_token) jwks_url = current_app.config.get('OAUTH2_JWKS_URL') # retrieve the key material as specified by the token header r = requests.get(jwks_url, verify=verify_cert) 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 # validate your token based on the key it was signed with try: if sys.version_info >= (3, 0): jwt.decode(id_token, secret.decode('utf-8'), algorithms=[algo], audience=args['clientId']) else: jwt.decode(id_token, secret, algorithms=[algo], audience=args['clientId']) except jwt.DecodeError: return dict(message='Token is invalid'), 401 except jwt.ExpiredSignatureError: return dict(message='Token has expired'), 401 except jwt.InvalidTokenError: return dict(message='Token is invalid'), 401 headers = {'authorization': 'Bearer {0}'.format(access_token)} # retrieve information about the current user. r = requests.get(user_api_url, headers=headers, verify=verify_cert) profile = r.json() user = user_service.get_by_email(profile['email']) metrics.send('successful_login', 'counter', 1) # update with roles sent by identity provider roles = [] if 'roles' in profile: for group in profile['roles']: role = role_service.get_by_name(group) if not role: role = role_service.create( group, description= 'This is a group configured by identity provider', third_party=True) if not role.third_party: role = role_service.set_third_party( role.id, third_party_status=True) roles.append(role) 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) if not role.third_party: role = role_service.set_third_party(role.id, third_party_status=True) roles.append(role) # if we get an sso user create them an account if not user: # every user is an operator (tied to a default role) if current_app.config.get('LEMUR_DEFAULT_ROLE'): v = role_service.get_by_name( current_app.config.get('LEMUR_DEFAULT_ROLE')) if not v.third_party: v = role_service.set_third_party(v.id, third_party_status=True) if v: roles.append(v) user = user_service.create(profile['name'], get_psuedo_random_string(), profile['email'], True, profile.get('thumbnailPhotoUrl'), roles) else: # we add 'lemur' specific roles, so they do not get marked as removed for ur in user.roles: if not ur.third_party: roles.append(ur) # update any changes to the user user_service.update( user.id, profile['name'], profile['email'], True, profile.get('thumbnailPhotoUrl' ), # incase profile isn't google+ enabled roles) # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) return dict(token=create_token(user))
def user(session): u = UserFactory() session.commit() user_token = create_token(u) token = {"Authorization": "Basic " + user_token} return {"user": u, "token": token}
def post(self): """ .. http:post:: /auth/login Login with username:password **Example request**: .. sourcecode:: http POST /auth/login HTTP/1.1 Host: example.com Accept: application/json, text/javascript Content-Type: application/json;charset=UTF-8 { "username": "******", "password": "******" } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "token": "12343243243" } :arg username: username :arg password: password :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") args = self.reqparse.parse_args() if "@" in args["username"]: user = user_service.get_by_email(args["username"]) else: user = user_service.get_by_username(args["username"]) # default to local authentication 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)) metrics.send("login", "counter", 1, metric_tags={"status": SUCCESS_METRIC_STATUS}) return dict(token=create_token(user)) # try ldap login if current_app.config.get("LDAP_AUTH"): try: ldap_principal = ldap.LdapPrincipal(args) 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}, ) 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 # 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
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") args = self.reqparse.parse_args() # take the information we have received from the provider to create a new request params = { "client_id": args["clientId"], "grant_type": "authorization_code", "scope": "openid email profile address", "redirect_uri": args["redirectUri"], "code": args["code"], } # 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") # the secret and cliendId will be given to you when you signup for the provider token = "{0}:{1}".format(args["clientId"], current_app.config.get("PING_SECRET")) if sys.version_info >= (3, 0): basic = base64.b64encode(bytes(token, "utf-8")) headers = {"authorization": "basic {0}".format(basic.decode("utf-8"))} else: basic = base64.b64encode(token, "utf-8") headers = {"authorization": "basic {0}".format(basic)} # exchange authorization code for access token. r = requests.post(access_token_url, headers=headers, params=params) id_token = r.json()["id_token"] access_token = r.json()["access_token"] # fetch token public key header_data = fetch_token_header(id_token) jwks_url = current_app.config.get("PING_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"] break else: return dict(message="Key not found"), 403 # validate your token based on the key it was signed with try: if sys.version_info >= (3, 0): jwt.decode(id_token, secret.decode("utf-8"), algorithms=[algo], audience=args["clientId"]) else: jwt.decode(id_token, secret, algorithms=[algo], audience=args["clientId"]) except jwt.DecodeError: return dict(message="Token is invalid"), 403 except jwt.ExpiredSignatureError: return dict(message="Token has expired"), 403 except jwt.InvalidTokenError: return dict(message="Token is invalid"), 403 user_params = dict(access_token=access_token, schema="profile") # retrieve information about the current user. r = requests.get(user_api_url, params=user_params) profile = r.json() user = user_service.get_by_email(profile["email"]) metrics.send("successful_login", "counter", 1) # update their google 'roles' roles = [] 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") roles.append(role) role = role_service.get_by_name(profile["email"]) if not role: role = role_service.create(profile["email"], description="This is a user specific role") roles.append(role) # if we get an sso user create them an account if not user: # every user is an operator (tied to a default role) if current_app.config.get("LEMUR_DEFAULT_ROLE"): v = role_service.get_by_name(current_app.config.get("LEMUR_DEFAULT_ROLE")) if v: roles.append(v) user = user_service.create( profile["email"], get_psuedo_random_string(), profile["email"], True, profile.get("thumbnailPhotoUrl"), roles, ) else: # we add 'lemur' specific roles, so they do not get marked as removed for ur in user.roles: if ur.authority_id: roles.append(ur) # update any changes to the user user_service.update( user.id, profile["email"], profile["email"], True, profile.get("thumbnailPhotoUrl"), # incase profile isn't google+ enabled roles, ) # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) return dict(token=create_token(user))