def common_login(user_uuid, permanent_session=True): """ Performs login of the given user, with optional non-permanence on the session. Returns a tuple with (success, headers to set on success). """ user = model.get_user(user_uuid) if user is None: return (False, None) if login_user(LoginWrappedDBUser(user_uuid)): logger.debug("Successfully signed in as user %s with uuid %s", user.username, user_uuid) new_identity = QuayDeferredPermissionUser.for_id(user_uuid) identity_changed.send(app, identity=new_identity) session["login_time"] = datetime.datetime.now() if permanent_session and features.PERMANENT_SESSIONS: session_timeout_str = app.config.get("SESSION_TIMEOUT", "31d") session.permanent = True session.permanent_session_lifetime = convert_to_timedelta( session_timeout_str) # Force a new CSRF token. headers = {} headers[QUAY_CSRF_UPDATED_HEADER_NAME] = generate_csrf_token( force=True) return (True, headers) logger.debug("User could not be logged in, inactive?") return (False, None)
def request_authorization_code(): provider = FlaskAuthorizationProvider() response_type = request.args.get("response_type", "code") client_id = request.args.get("client_id", None) redirect_uri = request.args.get("redirect_uri", None) scope = request.args.get("scope", None) if not current_user.is_authenticated or not provider.validate_has_scopes( client_id, current_user.db_user().username, scope ): if not provider.validate_redirect_uri(client_id, redirect_uri): current_app = provider.get_application_for_client_id(client_id) if not current_app: abort(404) return provider._make_redirect_error_response( current_app.redirect_uri, "redirect_uri_mismatch" ) # Load the scope information. scope_info = scopes.get_scope_information(scope) if not scope_info: abort(404) return # Load the application information. oauth_app = provider.get_application_for_client_id(client_id) app_email = oauth_app.avatar_email or oauth_app.organization.email oauth_app_view = { "name": oauth_app.name, "description": oauth_app.description, "url": oauth_app.application_uri, "avatar": json.dumps(avatar.get_data(oauth_app.name, app_email, "app")), "organization": { "name": oauth_app.organization.username, "avatar": json.dumps(avatar.get_data_for_org(oauth_app.organization)), }, } # Show the authorization page. has_dangerous_scopes = any([check_scope["dangerous"] for check_scope in scope_info]) return render_page_template_with_routedata( "oauthorize.html", scopes=scope_info, has_dangerous_scopes=has_dangerous_scopes, application=oauth_app_view, enumerate=enumerate, client_id=client_id, redirect_uri=redirect_uri, scope=scope, csrf_token_val=generate_csrf_token(), ) if response_type == "token": return provider.get_token_response(response_type, client_id, redirect_uri, scope=scope) else: return provider.get_authorization_code(response_type, client_id, redirect_uri, scope=scope)
def request_authorization_code(): provider = FlaskAuthorizationProvider() response_type = request.args.get('response_type', 'code') client_id = request.args.get('client_id', None) redirect_uri = request.args.get('redirect_uri', None) scope = request.args.get('scope', None) if (not current_user.is_authenticated or not provider.validate_has_scopes(client_id, current_user.db_user().username, scope)): if not provider.validate_redirect_uri(client_id, redirect_uri): current_app = provider.get_application_for_client_id(client_id) if not current_app: abort(404) return provider._make_redirect_error_response(current_app.redirect_uri, 'redirect_uri_mismatch') # Load the scope information. scope_info = scopes.get_scope_information(scope) if not scope_info: abort(404) return # Load the application information. oauth_app = provider.get_application_for_client_id(client_id) app_email = oauth_app.avatar_email or oauth_app.organization.email oauth_app_view = { 'name': oauth_app.name, 'description': oauth_app.description, 'url': oauth_app.application_uri, 'avatar': json.dumps(avatar.get_data(oauth_app.name, app_email, 'app')), 'organization': { 'name': oauth_app.organization.username, 'avatar': json.dumps(avatar.get_data_for_org(oauth_app.organization)) } } # Show the authorization page. has_dangerous_scopes = any([check_scope['dangerous'] for check_scope in scope_info]) return render_page_template_with_routedata('oauthorize.html', scopes=scope_info, has_dangerous_scopes=has_dangerous_scopes, application=oauth_app_view, enumerate=enumerate, client_id=client_id, redirect_uri=redirect_uri, scope=scope, csrf_token_val=generate_csrf_token()) if response_type == 'token': return provider.get_token_response(response_type, client_id, redirect_uri, scope=scope) else: return provider.get_authorization_code(response_type, client_id, redirect_uri, scope=scope)
def captcha_func(): recaptcha_response = request.values.get("recaptcha_response", "") result = recaptcha2.verify(app.config["RECAPTCHA_SECRET_KEY"], recaptcha_response, get_request_ip()) if not result["success"]: abort(400) # Save that the captcha was verified. session["captcha_verified"] = int(time.time()) # Redirect to the normal OAuth flow again, so that the user can now create an account. csrf_token = generate_csrf_token(OAUTH_CSRF_TOKEN_NAME) login_scopes = login_service.get_login_scopes() auth_url = login_service.get_auth_url(url_scheme_and_hostname, "", csrf_token, login_scopes) return redirect(auth_url)
def post(self, service_id): """ Generates the auth URL and CSRF token explicitly for OIDC/OAuth-associated login. """ login_service = oauth_login.get_service(service_id) if login_service is None: raise InvalidRequest() csrf_token = generate_csrf_token(OAUTH_CSRF_TOKEN_NAME) kind = request.get_json()['kind'] redirect_suffix = '' if kind == 'login' else '/' + kind try: login_scopes = login_service.get_login_scopes() auth_url = login_service.get_auth_url(url_scheme_and_hostname, redirect_suffix, csrf_token, login_scopes) return {'auth_url': auth_url} except DiscoveryFailureException as dfe: logger.exception('Could not discovery OAuth endpoint information') raise DownstreamIssue(dfe.message)
def common_login(user_uuid, permanent_session=True): """ Performs login of the given user, with optional non-permanence on the session. Returns a tuple with (success, headers to set on success). """ user = model.get_user(user_uuid) if user is None: return (False, None) if login_user(LoginWrappedDBUser(user_uuid)): logger.debug('Successfully signed in as user %s with uuid %s', user.username, user_uuid) new_identity = QuayDeferredPermissionUser.for_id(user_uuid) identity_changed.send(app, identity=new_identity) session['login_time'] = datetime.datetime.now() if permanent_session and features.PERMANENT_SESSIONS: session_timeout_str = app.config.get('SESSION_TIMEOUT', '31d') session.permanent = True session.permanent_session_lifetime = convert_to_timedelta( session_timeout_str) # Inform our user analytics that we have a new "lead" create_lead_future = user_analytics.create_lead( user.email, user.username, user.given_name, user.family_name, user.company, user.location, ) create_lead_future.add_done_callback( build_error_callback('Create lead failed')) # Force a new CSRF token. headers = {} headers[QUAY_CSRF_UPDATED_HEADER_NAME] = generate_csrf_token( force=True) return (True, headers) logger.debug('User could not be logged in, inactive?') return (False, None)
def generate_csrf(): return generate_csrf_token()
def test_generate_csrf_token(): with app.test_request_context(): token = generate_csrf_token() assert isinstance(token, str)