def fake_ras_login(username, subject, email=None, db_session=None): """ Mock a login by creating a sub/iss mapping in the db and logging them into a session. Args: username (str): Username from IdP subject (str): sub id in tokens from IdP email (None, optional): email if provided db_session (None, optional): db session to use """ ras_client = RASOauth2Client( config["OPENID_CONNECT"]["ras"], HTTP_PROXY=config["HTTP_PROXY"], logger=logger, ) actual_username = ras_client.map_iss_sub_pair_to_user( issuer="https://stsstg.nih.gov", subject_id=subject, username=username, email=email, db_session=db_session, ) logger.debug( f"subject: {subject}, username: {username}, actual_username: {actual_username}" ) login_user(actual_username, provider="ras", email=None, id_from_idp=subject)
def get(self): """Handle ``GET /login/fence/login``.""" # Check that the state passed back from IDP fence is the same as the # one stored previously. mismatched_state = ( 'state' not in flask.request.args or 'state' not in flask.session or flask.request.args['state'] != flask.session.pop('state')) if mismatched_state: raise Unauthorized('authorization request failed; state mismatch') # Get the token response and log in the user. redirect_uri = flask.current_app.fence_client.session.redirect_uri tokens = flask.current_app.fence_client.fetch_access_token( redirect_uri, **flask.request.args.to_dict()) id_token_claims = validate_jwt(tokens['id_token'], aud={'openid'}, purpose='id', attempt_refresh=True) username = id_token_claims['context']['user']['name'] flask.session['username'] = username flask.session['provider'] = IdentityProvider.fence login_user(flask.request, username, IdentityProvider.fence) if 'redirect' in flask.session: return flask.redirect(flask.session.get('redirect')) return flask.jsonify({'username': username})
def get(self): """Handle ``GET /login/fence/login``.""" # Check that the state passed back from IDP fence is the same as the # one stored previously. mismatched_state = ( "state" not in flask.request.args or "state" not in flask.session or flask.request.args["state"] != flask.session.pop("state", "")) if mismatched_state and not config.get("MOCK_AUTH"): raise Unauthorized( "Login flow was interrupted (state mismatch). Please go back to the" " login page for the original application to continue.") # Get the token response and log in the user. redirect_uri = flask.current_app.fence_client._get_session( ).redirect_uri tokens = flask.current_app.fence_client.fetch_access_token( redirect_uri, **flask.request.args.to_dict()) id_token_claims = validate_jwt(tokens["id_token"], aud={"openid"}, purpose="id", attempt_refresh=True) username = id_token_claims["context"]["user"]["name"] login_user( username, IdentityProvider.fence, fence_idp=flask.session.get("fence_idp"), shib_idp=flask.session.get("shib_idp"), ) self.post_login() if "redirect" in flask.session: return flask.redirect(flask.session.get("redirect")) return flask.jsonify({"username": username})
def test_login_user_already_in_db(db_session): """ Test that if a user is already in the database and logs in, the session will contain the user's information (including additional information that may have been provided during the login like email and id_from_idp) """ email = "*****@*****.**" provider = "Test Provider" id_from_idp = "Provider_ID_0001" test_user = User(username=email, is_admin=False) db_session.add(test_user) db_session.commit() user_id = str(test_user.id) assert not test_user.email assert not test_user.id_from_idp login_user(email, provider, email=email, id_from_idp=id_from_idp) assert test_user.identity_provider.name == provider assert test_user.id_from_idp == id_from_idp assert test_user.email == email assert flask.session["username"] == email assert flask.session["provider"] == provider assert flask.session["user_id"] == user_id assert flask.g.user == test_user
def test_login_user_with_idp_already_in_db(db_session): """ Test that if a user is already in the database, has identity_provider configured, and logs in, the session will contain the user's information. """ email = "*****@*****.**" provider = "Test Provider" id_from_idp = "Provider_ID_0001" test_user = User(username=email, email=email, id_from_idp=id_from_idp, is_admin=False) test_idp = IdentityProvider(name=provider) test_user.identity_provider = test_idp db_session.add(test_user) db_session.commit() user_id = str(test_user.id) login_user(email, provider, email=email, id_from_idp=id_from_idp) assert test_user.identity_provider.name == provider assert test_user.id_from_idp == id_from_idp assert test_user.email == email assert flask.session["username"] == email assert flask.session["provider"] == provider assert flask.session["user_id"] == user_id assert flask.g.user == test_user
def get(self): """ Complete the shibboleth login. """ shib_header = config.get("SHIBBOLETH_HEADER") if not shib_header: raise InternalError("Missing shibboleth header configuration") # eppn stands for eduPersonPrincipalName username = flask.request.headers.get("eppn") entityID = flask.session.get("entityID") # if eppn not available or logging in through NIH if not username or not entityID or entityID == "urn:mace:incommon:nih.gov": persistent_id = flask.request.headers.get(shib_header) username = persistent_id.split("!")[-1] if persistent_id else None if not username: # some inCommon providers are not returning eppn # or persistent_id. See PXP-4309 # print("shib_header", shib_header) # print("flask.request.headers", flask.request.headers) raise Unauthorized("Unable to retrieve username") idp = IdentityProvider.itrust if entityID: idp = entityID login_user(flask.request, username, idp) if flask.session.get("redirect"): return flask.redirect(flask.session.get("redirect")) return "logged in"
def _login(email): """ Login user with given email from Microsoft, then redirect if session has a saved redirect. """ login_user(flask.request, email, IdentityProvider.microsoft) if flask.session.get("redirect"): return flask.redirect(flask.session.get("redirect")) return flask.jsonify({"username": email})
def _login(username, idp_name): """ Login user with given username, then redirect if session has a saved redirect. """ login_user(flask.request, username, idp_name) if flask.session.get("redirect"): return flask.redirect(flask.session.get("redirect")) return flask.jsonify({"username": username})
def _login(orcid): """ Login user with given email from ORCID, then redirect if session has a saved redirect. """ login_user(flask.request, orcid, IdentityProvider.orcid) if flask.session.get("redirect"): return flask.redirect(flask.session.get("redirect")) return flask.jsonify({"username": orcid})
def get(self): """Handle ``GET /login/fence/login``.""" # Check that the state passed back from IDP fence is the same as the # one stored previously. mismatched_state = ( "state" not in flask.request.args or "state" not in flask.session or flask.request.args["state"] != flask.session.pop("state", "")) if mismatched_state and not config.get("MOCK_AUTH"): raise Unauthorized( "Login flow was interrupted (state mismatch). Please go back to the" " login page for the original application to continue.") # Get the token response and log in the user. redirect_uri = flask.current_app.fence_client._get_session( ).redirect_uri tokens = flask.current_app.fence_client.fetch_access_token( redirect_uri, **flask.request.args.to_dict()) try: # For multi-Fence setup with two Fences >=5.0.0 id_token_claims = validate_jwt( tokens["id_token"], aud=self.client.client_id, scope={"openid"}, purpose="id", attempt_refresh=True, ) except JWTError: # Since fenceshib cannot be updated to issue "new-style" ID tokens # (where scopes are in the scope claim and aud is in the aud claim), # allow also "old-style" Fence ID tokens. id_token_claims = validate_jwt( tokens["id_token"], aud="openid", scope=None, purpose="id", attempt_refresh=True, ) username = id_token_claims["context"]["user"]["name"] email = id_token_claims["context"]["user"].get("email") login_user( username, IdentityProvider.fence, fence_idp=flask.session.get("fence_idp"), shib_idp=flask.session.get("shib_idp"), email=email, ) self.post_login() if config["REGISTER_USERS_ON"]: if not flask.g.user.additional_info.get("registration_info"): return flask.redirect(config["BASE_URL"] + flask.url_for("register.register_user")) if "redirect" in flask.session: return flask.redirect(flask.session.get("redirect")) return flask.jsonify({"username": username})
def get(self): code = flask.request.args.get('code') result = flask.current_app.google_client.get_user_id(code) email = result.get('email') if email: flask.session['username'] = email flask.session['provider'] = IdentityProvider.google login_user(flask.request, email, IdentityProvider.google) if flask.session.get('redirect'): return flask.redirect(flask.session.get('redirect')) return flask.jsonify({'username': email}) raise UserError(result)
def _login(username, idp_name, email=None): """ Login user with given username, then redirect if session has a saved redirect. """ login_user(username, idp_name, email=email) if config["REGISTER_USERS_ON"]: if not flask.g.user.additional_info.get("registration_info"): return flask.redirect( config["BASE_URL"] + flask.url_for("register.register_user") ) if flask.session.get("redirect"): return flask.redirect(flask.session.get("redirect")) return flask.jsonify({"username": username})
def test_login_new_user(db_session): """ Test that if a user is not in the database and logs in, the user is added to the database and the session will contain the user's information. """ email = "*****@*****.**" provider = "Test Provider" login_user(flask.request, email, provider) test_user = db_session.query(User).filter( User.username == email.lower()).first() assert flask.session["username"] == email assert flask.session["provider"] == provider assert flask.session["user_id"] == str(test_user.id) assert flask.g.user == test_user
def get(self): # Check if this is a request to link account vs. actually log in if flask.session.get("google_link"): return flask.redirect( flask.current_app.config.get("BASE_URL", "") + "/link/google/callback?code={}".format( flask.request.args.get("code"))) else: code = flask.request.args.get("code") result = flask.current_app.google_client.get_user_id(code) email = result.get("email") if email: login_user(flask.request, email, IdentityProvider.google) if flask.session.get("redirect"): return flask.redirect(flask.session.get("redirect")) return flask.jsonify({"username": email}) raise UserError(result)
def get(self): """ Complete the shibboleth login. """ if "SHIBBOLETH_HEADER" in config: eppn = flask.request.headers.get(config["SHIBBOLETH_HEADER"]) else: raise InternalError("Missing shibboleth header configuration") username = eppn.split("!")[-1] if eppn else None if username: login_user(flask.request, username, IdentityProvider.itrust) if flask.session.get("redirect"): return flask.redirect(flask.session.get("redirect")) return "logged in" else: raise Unauthorized("Please login")
def test_login_user_already_in_db(db_session): """ Test that if a user is already in the database and logs in, the session will contain the user's information. """ email = "*****@*****.**" provider = "Test Provider" test_user = User(username=email, is_admin=False) db_session.add(test_user) db_session.commit() user_id = str(test_user.id) login_user(flask.request, email, provider) assert flask.session["username"] == email assert flask.session["provider"] == provider assert flask.session["user_id"] == user_id assert flask.g.user == test_user
def test_login_new_user(db_session): """ Test that if a user is not in the database and logs in, the user is added to the database and the session will contain the user's information. """ email = "*****@*****.**" provider = "Test Provider" id_from_idp = "Provider_ID_0001" login_user(email, provider, email=email, id_from_idp=id_from_idp) test_user = db_session.query(User).filter( User.username == email.lower()).first() assert test_user.identity_provider.name == provider assert test_user.id_from_idp == id_from_idp assert test_user.email == email assert flask.session["username"] == email assert flask.session["provider"] == provider assert flask.session["user_id"] == str(test_user.id) assert flask.g.user == test_user
def get(self): """ Complete the shibboleth login. """ if 'SHIBBOLETH_HEADER' in flask.current_app.config: eppn = flask.request.headers.get( flask.current_app.config['SHIBBOLETH_HEADER']) else: raise InternalError("Missing shibboleth header configuration") username = eppn.split('!')[-1] if eppn else None if username: flask.session['username'] = username flask.session['provider'] = IdentityProvider.itrust login_user(flask.request, username, flask.session['provider']) if flask.session.get('redirect'): return flask.redirect(flask.session.get('redirect')) return "logged in" else: raise Unauthorized("Please login")