def update(session, photo=None, name=None, email=None, website=None, location=None, bio=None): """ Update the user profile for the currently logged-in user. """ raise UnauthorizedException() # Disable for now. # Check that the session is still valid. try: if session == None: raise InvalidParametersException() sessionHandler.validate(session) user = sessionHandler.get_user(session) # Log into the 3taps Identity API. success,response = identity_api.login(username=user.username, pass_hash=user.identity_api_hash) if not success: print "No 3taps identity!" return {} # No 3taps identity -> can't update the profile. session = response # Update the user's profile. changes = {} if photo != None: changes['photo'] = photo if name != None: changes['name'] = name if email != None: changes['email'] = email if website != None: changes['website'] = website if location != None: changes['location'] = location if bio != None: changes['bio'] = bio success,response = identity_api.update(session, changes) if not success: print "Internal server error with Identity API!" print response return {} updated_profile = response['profile'] # Finally, log out again and return the updated profile back to the # caller. identity_api.logout(session) return updated_profile except: traceback.print_exc() raise
def get(session): """ Return the user profile for the currently logged-in user. """ raise UnauthorizedException() # Disable for now. # Check that the session is still valid. if session == None: raise InvalidParametersException() sessionHandler.validate(session) user = sessionHandler.get_user(session) # Log in to the 3taps identity API. success,response = identity_api.login(username=user.username, pass_hash=user.identity_api_hash) if not success: print "No 3taps identity!" return {} # No 3taps identity -> return an empty profile. session = response # Get the user's details, and extract the profile. success,response = identity_api.get_user(session) if not success: print "Should never happen!" print response return {} # Should never happen. profile = response['profile'] # Finally, log out from the identity API again, and return the profile back # to the caller. identity_api.logout(session) return profile
def update(session, username=None, password=None, phone_number=None): """ Update the details of the currently logged-in user. """ raise UnauthorizedException() # Disable for now. logger.debug("in core.api.users.update(" + "session=%s, username=%s, password=%s, phone_number=%s)" % (repr(session), repr(username), repr(password), repr(phone_number))) if session == None: raise InvalidParametersException() sessionHandler.validate(session) user = sessionHandler.get_user(session) # Remember if the user had a username or password. if user.username not in ["", None]: had_username = True else: had_username = False if user.password_salt not in ["", None]: had_password = True else: had_password = False # If we're setting a username and password for this user, and we didn't # have one previously, create a 3taps Identity for this user. Note that # this may fail, if the username is already in use. if not had_username and username != None: if password == None: raise InvalidParametersException() _check_username(username) _check_password(password) # Try creating this user within the 3taps Identity API. success,response = identity_api.create(username, password) if not success: if response.startswith("403 error"): raise DuplicateUsernameException() else: raise InvalidParametersException() # Check that we don't have a local user with that username. try: existing_user = User.objects.get(username__iexact=username) except User.DoesNotExist: existing_user = None if existing_user != None: raise DuplicateUsernameException() # Finally, save the updated user details into our database. salt = response['server_salt'] hash = hashlib.md5(password + salt).hexdigest() user.uses_identity_api = True user.username = username user.identity_api_salt = salt user.identity_api_hash = hash user.save() # If we're changing the username for this user, ask the 3taps Identity API # to change the username. Note that this may fail, if the new username is # already in use. if had_username and username != None and username != user.username: success,response = identity_api.login(user.username, pass_hash=user.identity_api_hash) if not success: raise UnauthorizedException() session = response success,response = identity_api.update(session, {'username' : username}) if not success: if response.startswith("403 error"): raise DuplicateUsernameException() else: raise InvalidParametersException() identity_api.logout(session) # Check that we don't have a local user with that username. try: existing_user = User.objects.get(username__iexact=username) except User.DoesNotExist: existing_user = None if existing_user != None: raise DuplicateUsernameException() # Finally, save the updated user details into our database. user.username = username user.save() # If we're changing the password for this user, ask the 3taps Identity API # to change the password. if password != None: if user.username in ["", None]: # We can't change the password if we don't have a username. raise InvalidParametersException() if user.uses_identity_api: success,response = \ identity_api.login(user.username, pass_hash=user.identity_api_hash) else: success,response = \ identity_api.login(user.username, password="******") if not success: raise UnauthorizedException() session = response success,response = identity_api.update(session, {'username' : username}) if not success: if response.startswith("403 error"): raise DuplicateUsernameException() else: raise InvalidParametersException() identity_api.logout(session) salt = response['server_salt'] hash = hashlib.md5(password + salt).hexdigest() user.uses_identity_api = True user.identity_api_salt = salt user.identity_api_hash = hash user.save() # If we've been asked to update the user's phone number, do so. # NOTE: someone was using this to hack our system, so I've disabled it. if False: # phone_number != None: if phone_number == "": user.phone_number = None # Remove current phone number. else: phone_number = utils.format_phone_number(phone_number) try: existing_user = User.objects.get(phone_number=phone_number) except User.DoesNotExist: existing_user = None if existing_user != None and user.id != existing_user.id: raise DuplicatePhoneNumberException() user.phone_number = phone_number # If this was an ad hoc user who we're now making permanent, change their # "ad hoc" status, and create a new default topic for the user. if user.ad_hoc and (username != None or password != None or phone_number != None): user.ad_hoc = False _create_default_topic(user) # If we have been given a username and password for this user, record them # as signing up. if not had_username and not had_password: if username not in ["", None] and password not in ["", None]: eventRecorder.record_event(eventRecorder.EVENT_TYPE_NEW_USER_SIGNUP) # Finally, save the updated user and return a copy of it back to the # caller. user.updated_at = datetime.datetime.utcnow() user.save() return user.to_dict()
def login(user_id=None, username=None, password=None, phone_number=None, verification_code=None): """ Log a user in, creating a new login session. """ raise UnauthorizedException() # Disable for now. logger.debug("in core.api.users.login(" + "user_id=%s, username=%s, password=%s, phone=%s, code=%s)" % (repr(user_id), repr(username), repr(password), repr(phone_number), repr(verification_code))) if user_id != None: try: user = User.objects.get(id=user_id) except User.DoesNotExist: raise NoSuchUserException() if not user.ad_hoc: raise UnauthorizedException() elif username != None and password != None: # Log in using a username and password. Note that we have to use the # 3taps identity API for this. try: user = User.objects.get(username__iexact=username) except User.DoesNotExist: # We don't know about this user, but that doesn't mean the user # doesn't exist. It could be that the user already has an identity # within the 3taps Identity API, but hasn't used MessageMe before. # See if the user exists in the identity API. success,response = identity_api.login(username=username, password=password) if success: identity_api.logout(response) # Create a MessageMe record for this user. salt = response['server_salt'] hash = hashlib.md5(password + salt).hexdigest() user = User() user.username = username user.uses_identity_api = True user.identity_api_salt = salt user.identity_api_hash = hash user.phone_number = phone_number user.verification_code = None user.verified = False user.created_at = datetime.datetime.utcnow() user.updated_at = datetime.datetime.utcnow() user.save() eventRecorder.record_event( eventRecorder.EVENT_TYPE_NEW_USER_SIGNUP) _create_default_topic(user) else: # We don't know about this user, and the 3taps Identity API # doesn't either -> give up. raise LoginRejectedException() if user.uses_identity_api: # Ask the 3taps Identity API to validate the supplied username and # password. salt = user.identity_api_salt hash = hashlib.md5(password + salt).hexdigest() success,response = identity_api.login(username=username, pass_hash=hash) if success: identity_api.logout(response) # Update the password hash, just in case the user changed their # password. salt = response['server_salt'] hash = hashlib.md5(password + salt).hexdigest() user.identity_api_salt = salt user.identity_api_hash = hash user.save() else: raise LoginRejectedException() else: # We haven't yet migrated this user over to the identity API. We # first check the password against the old password hash to see if # it matches our private user details. hash = bcrypt.hashpw(password, user.password_salt) if hash == user.password_hash: # We know the user entered the correct password. Try logging # in with the "mm_temp" password, and if this works update the # user's details to use the supplied (real) password. success,response = identity_api.login(username=user.username, password="******") if success: session = response ignore = identity_api.update(session, {'password' : password}) identity_api.logout(session) salt = response['server_salt'] hash = hashlib.md5(password + salt).hexdigest() user.uses_identity_api = True user.identity_api_salt = salt user.identity_api_hash = hash user.save() else: # The user may have updated their password using another # client of the 3taps Identity API. Try logging in using # the supplied password. success,response = \ identity_api.login(username=user.username, password=password) if success: session = response identity_api.logout(session) salt = response['server_salt'] hash = hashlib.md5(password + salt).hexdigest() user.uses_identity_api = True user.identity_api_salt = salt user.identity_api_hash = hash user.save() else: # We can't log in -> give up. raise LoginRejectedException() else: # The supplied password doesn't match our local records. All # we can do is hope the password is accepted by the 3taps # Identity API, and if so accept the login. success,response = identity_api.login(username=user.username, password=password) if success: session = response identity_api.logout(session) salt = response['server_salt'] hash = hashlib.md5(password + salt).hexdigest() user.uses_identity_api = True user.identity_api_salt = salt user.identity_api_hash = hash user.save() else: # We can't log in -> give up. raise LoginRejectedException() elif phone_number != None and verification_code != None: phone_number = utils.format_phone_number(phone_number) try: user = User.objects.get(phone_number=phone_number, verification_code=verification_code) except User.DoesNotExist: raise LoginRejectedException() user.verified = True user.save() elif (user_id == None and username == None and password == None and phone_number == None and verification_code == None): # Create a new ad hoc user on-the-fly for this session. user = User() user.ad_hoc = True user.username = None user.password_salt = None user.password_hash = None user.phone_number = None user.verification_code = None user.verified = False user.created_at = datetime.datetime.utcnow() user.updated_at = datetime.datetime.utcnow() user.save() else: raise InvalidParametersException() return sessionHandler.create(user)