class User(Resource): method_decorators = [authorize()] @swagger.operation( notes='Returns user information', parameters=[], responseClass=UserResponse.__name__, responseMessages=[UserResponse.description], tags=['Users'], ) @marshal_with_parser(UserResponse) def get(self, uid, user_dict): found_user = UserTemplate.from_database( uid, user_manager.get_user(uid)) return found_user, UserResponse.code @swagger.operation( notes='Returns user information', parameters=[], responseClass=UserResponse.__name__, responseMessages=[UserResponse.description], tags=['Users'], ) @marshal_with_parser(UserResponse) def post(self, uid, user_dict): new_user = { 'email': user_dict['email'], 'name': user_dict.get('displayName', '') } new_user['id'] = uid new_user_template = UserTemplate.build(new_user) user_manager.create_or_update_user(uid, new_user_template) return new_user, UserResponse.code
class UserLock(Resource): method_decorators = [authorize()] @swagger.operation( notes='Returns a list of locks owned by a user', parameters=[], responseClass=UserLockResponse.__name__, responseMessages=[UserLockResponse.description], tags=['Locks'], ) def get(self, uid, user): return user_lock_manager.get_user_locks(uid), UserLockResponse.code @swagger.operation( notes='Adds a valid lock id to a user\'s account', parameters=[PostUserLockArgs.schema], responseClass=UserLockResponse.__name__, responseMessages=[UserLockResponse.description], tags=['Locks'], ) @use_kwargs(PostUserLockArgs.resource_fields, locations=("json", "form")) @marshal_with_parser(UserLockResponse) @record_history( state_changes={UserLockResponse.code: StateChange.USER_LOCK_DELETED}) def post(self, uid, user, **args): user_locks = UserLocks.build(args) result = user_lock_manager.create_or_update_user_lock( uid, user_locks, should_overwrite=False) return result, UserLockResponse.code
class LockStatus(Resource): method_decorators = [authorize()] @swagger.operation( notes=LOCK_STATUS_PUT_NOTES, parameters=[PutLockStatusArgs.schema], responseClass=PutUserLockStatusResponse.__name__, responseMessages=[PutUserLockStatusResponse.description], tags=['Locks'], ) @use_kwargs(PutLockStatusArgs.resource_fields, locations=("json", "form")) @marshal_with_parser(PutUserLockStatusResponse) @record_history(state_changes={ PutUserLockStatusResponse.code: StateChange.LOCK_STATE_CHANGED }) def put(self, uid, user, **args): lock_id = args['lockId'] security_utils.verify_lock_ownership(uid, lock_id) # TODO: refactor this into something less hacky than enum matching if args.get('status') != LockStatusEnum.OPEN_REQUESTED: error_message = 'Users cannot set the lock to open or closed. ' + \ 'Open or close the vault to do so.' raise AuthorizationException(error_message) was_lock_removed = False found_password = security_utils.verify_password( lock_id, args.get('password')) if found_password.type == PasswordType.OTP: password_manager.remove_password(lock_id, found_password) was_lock_removed = True result = lock_manager.change_lock_status( lock_id, args.get('status'), was_lock_removed), PutUserLockStatusResponse.code return result @swagger.operation( notes='Gets the lock status of a user owned lock', responseClass=UserLockStatusResponse.__name__, responseMessages=[UserLockStatusResponse.description], tags=['Locks'], ) @marshal_with_parser(UserLockStatusResponse) def get(self, uid, user, **kwargs): lock_id = kwargs['lockId'] security_utils.verify_lock_ownership(uid, lock_id) return lock_manager.get_lock_status( lock_id), UserLockStatusResponse.code
class LockHistory(Resource): method_decorators = [authorize()] @swagger.operation( notes=HISTORY_INFO, tags=['History'], responseClass=LockHistoryResponse.__name__, responseMessages=[LockHistoryResponse.description], ) @use_kwargs(GetLockHistoryArgs.resource_fields, locations=("json", "form")) @marshal_with_parser(LockHistoryResponse) def get(self, uid, user, **kwargs): lock_id = kwargs['lockId'] security_utils.verify_lock_ownership(uid, lock_id) events = history_manager.get_events_from_lock_id(lock_id) return ({'events': events}, LockHistoryResponse.code)
class Lock(Resource): method_decorators = [authorize()] @swagger.operation( notes='Deletes a lock id associated with a user\'s account', # parameters=[DeleteUserLockArgs.schema], responseClass=UserLockResponse.__name__, responseMessages=[UserLockResponse.description], tags=['Locks'], ) @use_kwargs(DeleteUserLockArgs.resource_fields, locations=("json", "form")) @marshal_with_parser(UserLockResponse) @record_history( state_changes={UserLockResponse.code: StateChange.USER_LOCK_ADDED}) def delete(self, uid, user, **kwargs): lock_id = kwargs['lockId'] security_utils.verify_lock_ownership(uid, lock_id) result = user_lock_manager.delete_user_lock(uid, lock_id) return result, UserLockResponse.code
class Locks(Resource): """ An admin api token is required in order to use this route. This is used to register new lock devices to the database. """ method_decorators = [authorize(admin=True)] @swagger.operation(notes='Creates a lock given an admin id token', parameters=[PostLocksArgs.schema], responseClass=AdminLocksResponse.__name__, responseMessages=[AdminLocksResponse.description], tags=['Admin']) @marshal_with_parser(AdminLocksResponse) @use_kwargs(PostLocksArgs.resource_fields, locations=("json", "form")) def post(self, uid, user, **args): args['secret'] = security_utils.hash_password(args['secret']) lock = Lock.build(args) lock_manager.add_lock(lock) return lock, AdminLocksResponse.code
class LockPasswords(Resource): method_decorators = [authorize()] @swagger.operation( notes='Gets metadata about a lock\'s passwords. ' + PASSWORD_INFO, tags=['Password Management'], responseClass=LockPasswordsResponse.__name__, responseMessages=[LockPasswordsResponse.description], ) @marshal_with_parser(LockPasswordsResponse) def get(self, uid, user, **kwargs): lock_id = kwargs['lockId'] security_utils.verify_lock_ownership(uid, lock_id) result = password_manager.get_passwords_metadata(lock_id), 200 return result @swagger.operation( notes='Adds a password to a lock. ' + PASSWORD_INFO, tags=['Password Management'], parameters=[PostLockPasswordsArgs.schema], responseClass=LockPasswordResponse.__name__, responseMessages=[LockPasswordResponse.description], ) @use_kwargs(PostLockPasswordsArgs.resource_fields, locations=("json", "form")) @record_history(state_changes={ LockPasswordResponse.code: StateChange.PASSWORD_CREATED }) @marshal_with_parser(LockPasswordResponse) def post(self, uid, user, **kwargs): lock_id = kwargs['lockId'] security_utils.verify_lock_ownership(uid, lock_id) kwargs['password'] = security_utils.hash_password(kwargs['password']) password = Password.build(kwargs) return (password_manager.add_password(lock_id, password), LockPasswordResponse.code)
class LockPassword(Resource): method_decorators = [authorize()] @swagger.operation( notes='Gets metadata on a lock password. ' + PASSWORD_INFO, tags=['Password Management'], responseClass=LockPasswordResponse.__name__, responseMessages=[LockPasswordResponse.description], ) @use_kwargs(GetLockPasswordMetadataArgs.resource_fields, locations=("json", "form")) @marshal_with_parser(LockPasswordResponse) def get(self, uid, user, **kwargs): lock_id = kwargs['lockId'] password_id = kwargs['passwordId'] security_utils.verify_lock_ownership(uid, lock_id) return (password_manager.get_password_metadata(lock_id, password_id), LockPasswordResponse.code) @swagger.operation( notes='Changes a password. ' + PASSWORD_INFO, tags=['Password Management'], parameters=[PutLockPasswordArgs.schema], responseClass=LockPasswordResponse.__name__, responseMessages=[LockPasswordResponse.description], ) @use_kwargs(PutLockPasswordArgs.resource_fields, locations=("json", "form")) @marshal_with_parser(LockPasswordResponse) @record_history(state_changes={ LockPasswordResponse.code: StateChange.PASSWORD_METADATA_CHANGED }) def put(self, uid, user, **kwargs): lock_id = kwargs['lockId'] password_id = kwargs['passwordId'] # TODO(jeremy): roll this into an update request object update_args = self._build_update_args(kwargs) result = password_manager.update_password( lock_id, password_id, update_args, ) return result, LockPasswordResponse.code @swagger.operation( notes='Gets metadata on a lock password. ' + PASSWORD_INFO, tags=['Password Management'], ) @use_kwargs(DeleteLockPasswordArgs.resource_fields, locations=("json", "form")) @record_history(state_changes={ LockPasswordResponse.code: StateChange.PASSWORD_DELETED }) def delete(self, uid, user, **kwargs): lock_id = kwargs['lockId'] password_id = kwargs['passwordId'] security_utils.verify_lock_ownership(uid, lock_id) password_manager.remove_password_by_id(lock_id, password_id) return {}, 200 def _build_update_args(self, kwargs): if 'password' in kwargs: kwargs['password'] = security_utils.hash_password( kwargs['password']) update_args = {} for arg in list(PutLockPasswordArgs.resource_fields.keys()): if arg in kwargs: update_args[arg] = kwargs[arg] return update_args