def test_user_password(self, testapp): """ Test password hashing and checking """ admin = User('admin', 'supersafepassword') assert admin.username == 'admin' assert admin.check_password('supersafepassword')
def test_user_save(self, testapp): """ Test Saving the user model to the database """ admin = User('admin', 'supersafepassword') db.session.add(admin) db.session.commit() user = User.query.filter_by(username="******").first() assert user is not None
def get(self): redirect_uri = request.url flow = get_auth_flow(redirect_uri=redirect_uri) response = flow.step2_exchange(request.args['code']) scopes = response.token_response['scope'].split(',') if 'user:email' not in scopes: raise NotImplementedError identity_config = { 'access_token': response.access_token, 'refresh_token': response.refresh_token, 'scopes': scopes, } # fetch user details response = requests.get( 'https://api.github.com/user', params={'access_token': identity_config['access_token']} ) response.raise_for_status() user_data = response.json() with db.session.begin_nested(): existing_identity = Identity.query.filter( Identity.external_id == str(user_data['id']), Identity.provider == 'github', ).first() if not existing_identity: user = User( email=user_data['email'], ) db.session.add(user) identity = Identity( user=user, external_id=str(user_data['id']), provider='github', config=identity_config, ) db.session.add(identity) else: user = User.query.filter( Identity.external_id == str(user_data['id']), Identity.provider == 'github', Identity.user_id == User.id, ).first() Identity.query.filter( Identity.external_id == str(user_data['id']), Identity.provider == 'github', ).update({ 'config': identity_config, }) session['uid'] = user.id.hex return redirect(url_for(self.complete_url))
def get(self): redirect_uri = request.url flow = get_auth_flow(redirect_uri=redirect_uri) try: oauth_response = flow.step2_exchange(request.args['code']) except FlowExchangeError: return redirect('/?auth_error=true') scopes = oauth_response.token_response['scope'].split(',') if 'user:email' not in scopes: raise NotImplementedError # fetch user details response = requests.get( 'https://api.github.com/user', params={'access_token': oauth_response.access_token}) response.raise_for_status() user_data = response.json() identity_config = { 'access_token': oauth_response.access_token, 'refresh_token': oauth_response.refresh_token, 'scopes': scopes, 'login': user_data['login'], } try: with db.session.begin_nested(): user = User(email=user_data['email'], ) db.session.add(user) identity = Identity( user=user, external_id=str(user_data['id']), provider='github', config=identity_config, ) db.session.add(identity) user_id = user.id except IntegrityError: identity = Identity.query.filter( Identity.external_id == str(user_data['id']), Identity.provider == 'github', ).first() identity.config = identity_config db.session.add(identity) user_id = identity.user_id db.session.commit() session['uid'] = user_id return redirect(url_for(self.complete_url))
def testapp(request): app = create_app('zeus.settings.TestConfig') client = app.test_client() db.app = app db.create_all() if getattr(request.module, "create_user", True): admin = User('admin', 'supersafepassword') db.session.add(admin) db.session.commit() def teardown(): db.session.remove() db.drop_all() request.addfinalizer(teardown) return client
def get(self): redirect_uri = request.url flow = get_auth_flow(redirect_uri=redirect_uri) try: oauth_response = flow.step2_exchange(request.args['code']) except FlowExchangeError: return redirect('/?auth_error=true') scopes = oauth_response.token_response['scope'].split(',') if 'user:email' not in scopes: raise NotImplementedError # fetch user details github = GitHubClient(token=oauth_response.access_token) user_data = github.get('/user') identity_config = { 'access_token': oauth_response.access_token, 'refresh_token': oauth_response.refresh_token, 'scopes': scopes, 'login': user_data['login'], } email = user_data.get('email') # no primary/public email specified if not email: emails = github.get('/user/emails') email = next(( e['email'] for e in emails if e['verified'] and e['primary'] )) try: with db.session.begin_nested(): user = User( email=email, ) db.session.add(user) identity = Identity( user=user, external_id=str(user_data['id']), provider='github', config=identity_config, ) db.session.add(identity) user_id = user.id except IntegrityError: identity = Identity.query.filter( Identity.external_id == str(user_data['id']), Identity.provider == 'github', ).first() identity.config = identity_config db.session.add(identity) user_id = identity.user_id db.session.commit() # forcefully expire a session after permanent_session_lifetime # Note: this is enforced in zeus.auth auth.login_user(user_id) return redirect(url_for(self.complete_url))
def get(self): # TODO(dcramer): handle errors oauth = get_oauth_session(state=session.pop("oauth_state", None)) try: resp = oauth.fetch_token( GITHUB_TOKEN_URI, client_secret=current_app.config["GITHUB_CLIENT_SECRET"], authorization_response=request.url, ) except OAuth2Error: current_app.logger.exception("oauth.error") # redirect, as this is likely temporary based on server data return redirect(auth.get_redirect_target(clear=True) or "/") if resp is None or resp.get("access_token") is None: return Response("Access denied: reason=%s error=%s resp=%s" % (request.args["error"], request.args["error_description"], resp)) assert resp.get("token_type") == "bearer" scopes = resp["scope"][0].split(",") if "user:email" not in scopes: raise NotImplementedError # fetch user details client = GitHubClient(token=resp["access_token"]) user_data = client.get("/user") identity_config = { "access_token": resp["access_token"], "refresh_token": resp.get("refresh_token"), "login": user_data["login"], } email_list = client.get("/user/emails") email_list.append({ "email": "{}@users.noreply.github.com".format(user_data["login"]), "verified": True, }) primary_email = user_data.get("email") # HACK(dcramer): capture github's anonymous email addresses when they're not listed # (we haven't actually confirmed they're not listed) if not primary_email: primary_email = next((e["email"] for e in email_list if e["verified"] and e["primary"])) try: # we first attempt to create a new user + identity with db.session.begin_nested(): user = User(email=primary_email) db.session.add(user) identity = Identity( user=user, external_id=str(user_data["id"]), provider="github", scopes=scopes, config=identity_config, ) db.session.add(identity) user_id = user.id new_user = True except IntegrityError: # if that fails, assume the identity exists identity = Identity.query.filter( Identity.external_id == str(user_data["id"]), Identity.provider == "github", ).first() # and if it doesnt, attempt to find a matching user, # as it means the failure above was due to that if not identity: user = User.query.filter(User.email == primary_email).first() assert ( user ) # this should not be possible unless we've got a race condition identity = Identity( user=user, external_id=str(user_data["id"]), provider="github", scopes=scopes, config=identity_config, ) db.session.add(identity) user_id = user.id else: identity.config = identity_config identity.scopes = scopes db.session.add(identity) user_id = identity.user_id new_user = False db.session.flush() for email in email_list: try: with db.session.begin_nested(): db.session.add( Email( user_id=user_id, email=email["email"], verified=email["verified"], )) except IntegrityError: pass db.session.commit() # forcefully expire a session after permanent_session_lifetime # Note: this is enforced in zeus.auth auth.login_user(user_id) user = auth.get_current_user() if new_user: # update synchronously so the new user has a better experience sync_github_access(user_id=user.id) else: sync_github_access.delay(user_id=user.id) next_uri = auth.get_redirect_target(clear=True) or "/" if "/login" in next_uri or "/auth/github" in next_uri: next_uri = "/" return redirect(next_uri)
def get(self): redirect_uri = request.url flow = get_auth_flow(redirect_uri=redirect_uri) try: oauth_response = flow.step2_exchange(request.args['code']) except FlowExchangeError: return redirect('/?auth_error=true') scopes = oauth_response.token_response['scope'].split(',') if 'user:email' not in scopes: raise NotImplementedError # fetch user details github = GitHubClient(token=oauth_response.access_token) user_data = github.get('/user') identity_config = { 'access_token': oauth_response.access_token, 'refresh_token': oauth_response.refresh_token, 'login': user_data['login'], } email_list = github.get('/user/emails') email_list.append({ 'email': '{}@users.noreply.github.com'.format(user_data['login']), 'verified': True, }) primary_email = user_data.get('email') # HACK(dcramer): capture github's anonymous email addresses when they're not listed # (we haven't actually confirmed they're not listed) if not primary_email: primary_email = next((e['email'] for e in email_list if e['verified'] and e['primary'])) try: # we first attempt to create a new user + identity with db.session.begin_nested(): user = User(email=primary_email, ) db.session.add(user) identity = Identity( user=user, external_id=str(user_data['id']), provider='github', scopes=scopes, config=identity_config, ) db.session.add(identity) user_id = user.id except IntegrityError: # if that fails, assume the identity exists identity = Identity.query.filter( Identity.external_id == str(user_data['id']), Identity.provider == 'github', ).first() # and if it doesnt, attempt to find a matching user, # as it means the failure above was due to that if not identity: user = User.query.filter(User.email == primary_email).first() assert user # this should not be possible unless we've got a race condition identity = Identity( user=user, external_id=str(user_data['id']), provider='github', scopes=scopes, config=identity_config, ) db.session.add(identity) user_id = user.id else: identity.config = identity_config identity.scopes = scopes db.session.add(identity) user_id = identity.user_id db.session.flush() for email in email_list: try: with db.session.begin_nested(): db.session.add( Email( user_id=user_id, email=email['email'], verified=email['verified'], )) except IntegrityError: pass db.session.commit() # forcefully expire a session after permanent_session_lifetime # Note: this is enforced in zeus.auth auth.login_user(user_id) # now lets try to update the repos they have access to based on whats # enabled user = auth.get_current_user() grant_access_to_existing_repos(user) return redirect(auth.get_redirect_target(clear=True) or '/')