def login_facebook(): """Attempt to login a user with FB credentials encoded in the POST body. Expects the following form data: fb_access_token: Facebook user access token. This is used to verify that the user did authenticate with Facebook and is authenticated to our app. The user's FB ID is also obtained from this token. Responds with the session cookie via the `set-cookie` header on success. Send the associated cookie for all subsequent API requests that accept user authentication. """ req = flask.request fb_access_token = req.form.get('fb_access_token') # We perform a check to confirm the fb_access_token is indeed the person # identified by fbid, and that it was our app that generated the token. token_info = facebook.get_access_token_info(fb_access_token) if not token_info['is_valid'] or not token_info.get('user_id'): raise api_util.ApiForbiddenError( 'The given FB credentials are invalid.') fbid = str(token_info['user_id']) user = m.User.objects(fbid=fbid).first() if not user: raise api_util.ApiForbiddenError('No user with fbid %s exists. ' 'Create an account at uwflow.com.' % fbid) view_helpers.login_as_user(user) return api_util.jsonify({'message': 'Logged in user %s' % user.name})
def signup_email(): """Create a new account using data encoded in the POST body. Expects the following form data: first_name: E.g. 'Taylor' last_name: E.g. 'Swift' email: E.g. '*****@*****.**' password: E.g. 'iknewyouweretrouble' Responds with the session cookie via the `set-cookie` header on success. Send the associated cookie for all subsequent API requests that accept user authentication. """ # Prevent a CSRF attack from replacing a logged-in user's account with # a new account with known credentials current_user = view_helpers.get_current_user() if current_user: return api_util.jsonify({'message': 'A user is already logged in.'}) params = flask.request.form.copy() # Don't log the password password = params.pop('password', None) rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_SIGNUP, { 'params': params, 'type': rmclogger.LOGIN_TYPE_STRING_EMAIL, }, ) first_name = params.get('first_name') last_name = params.get('last_name') email = params.get('email') if not first_name: raise api_util.ApiBadRequestError('Must provide first name.') if not last_name: raise api_util.ApiBadRequestError('Must provide last name.') if not email: raise api_util.ApiBadRequestError('Must provide email.') if not password: raise api_util.ApiBadRequestError('Must provide password.') try: user = m.User.create_new_user_from_email( first_name, last_name, email, password) except m.User.UserCreationError as e: raise api_util.ApiBadRequestError(e.message) view_helpers.login_as_user(user) return api_util.jsonify({ 'message': 'Created and logged in user %s' % user.name })
def signup_email(): """Create a new account using data encoded in the POST body. Expects the following form data: first_name: E.g. 'Taylor' last_name: E.g. 'Swift' email: E.g. '*****@*****.**' password: E.g. 'iknewyouweretrouble' Responds with the session cookie via the `set-cookie` header on success. Send the associated cookie for all subsequent API requests that accept user authentication. """ # Prevent a CSRF attack from replacing a logged-in user's account with # a new account with known credentials current_user = view_helpers.get_current_user() if current_user: return api_util.jsonify({'message': 'A user is already logged in.'}) params = flask.request.form.copy() # Don't log the password password = params.pop('password', None) rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_SIGNUP, { 'params': params, 'type': rmclogger.LOGIN_TYPE_STRING_EMAIL, }, ) first_name = params.get('first_name') last_name = params.get('last_name') email = params.get('email') if not first_name: raise api_util.ApiBadRequestError('Must provide first name.') if not last_name: raise api_util.ApiBadRequestError('Must provide last name.') if not email: raise api_util.ApiBadRequestError('Must provide email.') if not password: raise api_util.ApiBadRequestError('Must provide password.') try: user = m.User.create_new_user_from_email(first_name, last_name, email, password) except m.User.UserCreationError as e: raise api_util.ApiBadRequestError(e.message) view_helpers.login_as_user(user) return api_util.jsonify( {'message': 'Created and logged in user %s' % user.name})
def login_facebook(): """Attempt to login a user with FB credentials encoded in the POST body. Expects the following form data: fb_access_token: Facebook user access token. This is used to verify that the user did authenticate with Facebook and is authenticated to our app. The user's FB ID is also obtained from this token. Responds with the session cookie via the `set-cookie` header on success. Send the associated cookie for all subsequent API requests that accept user authentication. Also returns the CSRF token, which must be sent as the value of the "X-CSRF-Token" header for all non-GET requests. """ # Prevent a CSRF attack from replacing a logged-in user's account with the # attacker's. current_user = view_helpers.get_current_user() if current_user: return api_util.jsonify({'message': 'A user is already logged in.'}) rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_SIGNUP, { 'type': rmclogger.LOGIN_TYPE_STRING_FACEBOOK, }, ) req = flask.request fb_access_token = req.form.get('fb_access_token') # We perform a check to confirm the fb_access_token is indeed the person # identified by fbid, and that it was our app that generated the token. token_info = facebook.get_access_token_info(fb_access_token) if not token_info['is_valid'] or not token_info.get('user_id'): raise api_util.ApiForbiddenError( 'The given FB credentials are invalid.') fbid = str(token_info['user_id']) user = m.User.objects(fbid=fbid).first() if not user: raise api_util.ApiForbiddenError('No user with fbid %s exists. ' 'Create an account at uwflow.com.' % fbid) view_helpers.login_as_user(user) # TODO(sandy): We don't need to do this anymore, just use the endpoint csrf_token = view_helpers.generate_csrf_token() return api_util.jsonify({ 'message': 'Logged in user %s' % user.name, 'csrf_token': csrf_token, })
def login_as_demo_user(): fbid = c.DEMO_ACCOUNT_FBID user = m.User.objects(fbid=fbid).first() # To catch errors on dev. We may not all have the test account in our mongo if user is None: logging.error("Accessed non-existant test/demo account %s" % fbid) return flask.redirect('/profile') view_helpers.login_as_user(user) return flask.redirect('/profile/%s' % user.id, 302)
def login_email(): """Attempt to log in a user with the credentials encoded in the POST body. Expects the following form data: email: E.g. '*****@*****.**' password: E.g. 'iknewyouweretrouble' Responds with the session cookie via the `set-cookie` header on success. Send the associated cookie for all subsequent API requests that accept user authentication. """ # Prevent a CSRF attack from replacing a logged-in user's account with the # attacker's. current_user = view_helpers.get_current_user() if current_user: return api_util.jsonify({'message': 'A user is already logged in.'}) params = flask.request.form.copy() # Don't log the password password = params.pop('password', None) rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_LOGIN, { 'params': params, 'type': rmclogger.LOGIN_TYPE_STRING_EMAIL, }, ) email = params.get('email') if not email: raise api_util.ApiBadRequestError('Must provide email.') if not password: raise api_util.ApiBadRequestError('Must provide password.') user = m.User.auth_user(email, password) if not user: raise api_util.ApiNotFoundError('Incorrect email or password.') view_helpers.login_as_user(user) return api_util.jsonify({'message': 'Logged in user %s' % user.name})
def login_with_facebook(): """Login or create an account using Facebook connect Upon successful login or account creation, returns a 'secure cookie' (provided by Flask) containing the session data. Takes a Facebook signed request in the form of: { 'fb_signed_request': obj } """ req = flask.request fbsr = req.form.get('fb_signed_request') rmclogger.log_event( rmclogger.LOG_CATEGORY_GENERIC, rmclogger.LOG_EVENT_LOGIN, { 'fbsr': fbsr, 'request_form': req.form, 'type': rmclogger.LOGIN_TYPE_STRING_FACEBOOK, }, ) if (fbsr is None): raise exceptions.ImATeapot('No fbsr set') fb_data = facebook.get_fb_data(fbsr, app.config) fbid = fb_data['fbid'] fb_access_token = fb_data['access_token'] fb_access_token_expiry_date = fb_data['expires_on'] is_invalid = fb_data['is_invalid'] user = m.User.objects(fbid=fbid).first() if user: # Existing user. Update with their latest Facebook info user.fb_access_token = fb_access_token user.fb_access_token_expiry_date = fb_access_token_expiry_date user.fb_access_token_invalid = is_invalid user.save() # Authenticate view_helpers.login_as_user(user) rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_LOGIN, { 'new_user': False, 'user_id': user.id, 'type': rmclogger.LOGIN_TYPE_STRING_FACEBOOK, }, ) else: # New user. Sign up with their Facebook info now = datetime.now() user_obj = { 'email': req.form.get('email'), 'fb_access_token': fb_access_token, 'fb_access_token_expiry_date': fb_access_token_expiry_date, 'fbid': fbid, 'first_name': req.form.get('first_name'), 'friend_fbids': flask.json.loads(req.form.get('friend_fbids')), 'gender': req.form.get('gender'), 'join_date': now, 'join_source': m.User.JoinSource.FACEBOOK, 'last_name': req.form.get('last_name'), 'last_visited': now, 'middle_name': req.form.get('middle_name'), } referrer_id = req.form.get('referrer_id') if referrer_id: try: user_obj['referrer_id'] = bson.ObjectId(referrer_id) except bson.errors.InvalidId: pass # Create the user user = m.User(**user_obj) user.save() # Authenticate view_helpers.login_as_user(user) rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_LOGIN, { 'new_user': True, 'user_id': user.id, 'referrer_id': referrer_id, 'type': rmclogger.LOGIN_TYPE_STRING_FACEBOOK, }, ) return ''
def login(): req = flask.request fbsr = req.form.get('fb_signed_request') # TODO(Sandy): Change log category because this isn't API? rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_LOGIN, { 'fbsr': fbsr, 'request_form': req.form, }, ) if (fbsr is None): raise exceptions.ImATeapot('No fbsr set') fb_data = facebook.get_fb_data(fbsr, app.config) fbid = fb_data['fbid'] fb_access_token = fb_data['access_token'] fb_access_token_expiry_date = fb_data['expires_on'] is_invalid = fb_data['is_invalid'] user = m.User.objects(fbid=fbid).first() if user: # Existing user. Update with latest FB info user.fb_access_token = fb_access_token user.fb_access_token_expiry_date = fb_access_token_expiry_date user.fb_access_token_invalid = is_invalid user.save() view_helpers.login_as_user(user) rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_LOGIN, { 'new_user': False, 'user_id': user.id, }, ) return '' # Sign up the new user friend_fbids = flask.json.loads(req.form.get('friend_fbids')) gender = req.form.get('gender') first_name = req.form.get('first_name') middle_name = req.form.get('middle_name') last_name = req.form.get('last_name') email = req.form.get('email') now = datetime.now() user_obj = { 'fbid': fbid, 'first_name': first_name, 'middle_name': middle_name, 'last_name': last_name, 'email': email, 'gender': gender, 'fb_access_token': fb_access_token, 'fb_access_token_expiry_date': fb_access_token_expiry_date, # TODO(Sandy): Count visits properly 'join_date': now, 'join_source': m.User.JoinSource.FACEBOOK, 'num_visits': 1, 'last_visited': now, 'friend_fbids': friend_fbids, # TODO(Sandy): Fetch from client side and pass here: name, email, # school, program, faculty } referrer_id = req.form.get('referrer_id') if referrer_id: try: user_obj['referrer_id'] = bson.ObjectId(referrer_id) except: pass user = m.User(**user_obj) user.save() view_helpers.login_as_user(user) rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_LOGIN, { 'new_user': True, 'user_id': user.id, 'referrer_id': referrer_id, }, ) return ''
def login_with_facebook(): """Login or create an account using Facebook connect Upon successful login or account creation, returns a 'secure cookie' (provided by Flask) containing the session data. Takes a Facebook signed request in the form of: { 'fb_signed_request': obj } """ req = flask.request fbsr = req.form.get('fb_signed_request') rmclogger.log_event( rmclogger.LOG_CATEGORY_GENERIC, rmclogger.LOG_EVENT_LOGIN, { 'fbsr': fbsr, 'request_form': req.form, 'type': rmclogger.LOGIN_TYPE_STRING_FACEBOOK, }, ) if (fbsr is None): raise exceptions.ImATeapot('No fbsr set') fb_data = facebook.get_fb_data(fbsr, app.config) fbid = fb_data['fbid'] fb_access_token = fb_data['access_token'] fb_access_token_expiry_date = fb_data['expires_on'] is_invalid = fb_data['is_invalid'] user = m.User.objects(fbid=fbid).first() if user: # Existing user. Update with their latest Facebook info user.fb_access_token = fb_access_token user.fb_access_token_expiry_date = fb_access_token_expiry_date user.fb_access_token_invalid = is_invalid user.save() # Authenticate view_helpers.login_as_user(user) rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_LOGIN, { 'new_user': False, 'user_id': user.id, 'type': rmclogger.LOGIN_TYPE_STRING_FACEBOOK, }, ) else: # New user, or existing email logins user. now = datetime.now() email = req.form.get('email') user_data = { 'fb_access_token': fb_access_token, 'fb_access_token_expiry_date': fb_access_token_expiry_date, 'fbid': fbid, 'friend_fbids': flask.json.loads(req.form.get('friend_fbids')), 'gender': req.form.get('gender'), 'last_visited': now, } user = m.User.objects(email=email).first() if email else None if user: # Update existing account with Facebook data referrer_id = None for k, v in user_data.iteritems(): user[k] = v user.save() else: # Create an account with their Facebook data user_data.update({ 'email': email, 'first_name': req.form.get('first_name'), 'join_date': now, 'join_source': m.User.JoinSource.FACEBOOK, 'last_name': req.form.get('last_name'), 'middle_name': req.form.get('middle_name'), }) referrer_id = req.form.get('referrer_id') if referrer_id: try: user_data['referrer_id'] = bson.ObjectId(referrer_id) except bson.errors.InvalidId: pass user = m.User(**user_data) user.save() # Authenticate view_helpers.login_as_user(user) rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_LOGIN, { 'new_user': True, 'user_id': user.id, 'referrer_id': referrer_id, 'type': rmclogger.LOGIN_TYPE_STRING_FACEBOOK, }, ) return ''