def login() -> Any: """Login user""" # Handle already authenticated if current_user.is_authenticated: return redirect("/app") # Render template as default provider = request.args.get("provider", None) if provider is None: return render_template("login.html") # Handle login info: Dict = {} if provider == "azure": if not azure.authorized: return redirect(url_for("azure.login")) else: info = azure.get("/v1.0/me").json() else: pass if info: email = info["userPrincipalName"] user = User.query.filter_by(email=email).first() if user is None: user = User(email) user.authenticated = True db.session.add(user) db.session.commit() login_user(user, True) return redirect("/app") return redirect("/login")
def authorized_azure(): if azure.authorized: resp = azure.get("/v1.0/me").json() name = resp["displayName"] email = resp["userPrincipalName"] user = get_user_by_email(email) if user is None: user = create_user(name, email) login_user(user) return redirect(url_for("catalog"))
def index(): if not azure.authorized: return redirect(url_for("azure.login")) resp = azure.get("/v1.0/me") assert resp.ok staff = twoaday.listStaff() date = datetime.datetime.now() agentcount = twoaday.agentcol.count() return render_template("index.html", staff=staff, date=date, agentcount=agentcount)
def validate_token(_token: str) -> bool: """ Tests if the current token is still valid. Cached to avoid spamming /v1.0/me too often. The `_token` param is only used to distinguish cache entries. """ log.debug("Validating azure auth token.") try: resp = azure.get("/v1.0/me") resp.raise_for_status() return True except TokenExpiredError: return False
def azure_login(): if not azure.authorized: flash('Access denied to Azure', 'danger') return redirect(url_for("auth.login", local=1)) resp = azure.get("https://graph.microsoft.com/v1.0/me/") if not resp.ok: flash('Unable to access Azure data', 'danger') return redirect(url_for("auth.login", local=1)) resp_user = resp.json() if 'mail' not in resp_user: flash('Invalid Azure data format', 'danger') # print(resp_user) return redirect(url_for("auth.login", local=1)) return get_or_create_sso_user( resp_user['id'], resp_user['displayName'], resp_user['mail'], )
def authenticate_azure(): if not azure.authorized: return redirect(url_for("azure.login")) try: resp = azure.get("/v1.0/me") assert resp.ok except (InvalidGrantError, TokenExpiredError): return redirect(url_for("azure.login")) # Todo: Investigate more on https://github.com/singingwolfboy/flask-dance/issues/35 resp_json = resp.json() # print(f'Logged User Response:\n{resp_json}') user = { 'id': resp_json["id"], 'name': resp_json["displayName"], 'email': resp_json["mail"], 'given_name': resp_json["givenName"], 'surname': resp_json["surname"], 'job_title': resp_json["jobTitle"], 'office': resp_json["officeLocation"], 'language': resp_json["preferredLanguage"], 'principal_name': resp_json["userPrincipalName"], 'business_phones': resp_json["businessPhones"], 'mobile_phone': resp_json["mobilePhone"], 'odata_context': resp_json["@odata.context"] } if not user['email'] or user['email'].rsplit('@', 1)[1] != 'tlma.online': return redirect(url_for("azure.login")) authenticated_user = User(user) login_user(authenticated_user) flash("Successfully signed in with Azure.") session[user['id']] = user next_url = request.args.get('next') if next_url: print(f'OAuth finished, now going back to {next_url}') return redirect(next_url) return redirect(url_for("default.logged"))
def test_context_local(): responses.add(responses.GET, "https://google.com") # set up two apps with two different set of auth tokens app1 = Flask(__name__) ghbp1 = make_azure_blueprint( "foo1", "bar1", redirect_to="url1", backend=MemoryBackend({"access_token": "app1"}), ) app1.register_blueprint(ghbp1) app2 = Flask(__name__) ghbp2 = make_azure_blueprint( "foo2", "bar2", redirect_to="url2", backend=MemoryBackend({"access_token": "app2"}), ) app2.register_blueprint(ghbp2) # outside of a request context, referencing functions on the `azure` object # will raise an exception with pytest.raises(RuntimeError): azure.get("https://google.com") # inside of a request context, `azure` should be a proxy to the correct # blueprint session with app1.test_request_context("/"): app1.preprocess_request() azure.get("https://google.com") request = responses.calls[0].request assert request.headers["Authorization"] == "Bearer app1" with app2.test_request_context("/"): app2.preprocess_request() azure.get("https://google.com") request = responses.calls[1].request assert request.headers["Authorization"] == "Bearer app2"
def test_context_local(make_app): responses.add(responses.GET, "https://google.com") # set up two apps with two different set of auth tokens app1 = make_app( "foo1", "bar1", redirect_to="url1", storage=MemoryStorage({"access_token": "app1"}), ) app2 = make_app( "foo2", "bar2", redirect_to="url2", storage=MemoryStorage({"access_token": "app2"}), ) # outside of a request context, referencing functions on the `azure` object # will raise an exception with pytest.raises(RuntimeError): azure.get("https://google.com") # inside of a request context, `azure` should be a proxy to the correct # blueprint session with app1.test_request_context("/"): app1.preprocess_request() azure.get("https://google.com") request = responses.calls[0].request assert request.headers["Authorization"] == "Bearer app1" with app2.test_request_context("/"): app2.preprocess_request() azure.get("https://google.com") request = responses.calls[1].request assert request.headers["Authorization"] == "Bearer app2"