예제 #1
0
def get_events_from_lock_id(lock_id: str) -> List[Event]:
    events = DB.child("LockEvents").child(lock_id).get().val()
    event_ids = events.keys() if events else set()
    output = []
    for event_id in event_ids:
        event = Event.from_database(
            event_id,
            DB.child("EventHistory").child(event_id).get().val())
        output.append(event)
    return output
예제 #2
0
def update_password(lock_id: str, password_id: str,
                    update_request: Dict[str, str]) -> PasswordMetadata:
    if len(update_request.keys()) == 0:
        raise ValidationException("Fields to update weren't supplied")
    password = get_password(lock_id, password_id)
    password.update(update_request)

    DB.child("Locks").child(lock_id).child("passwords").child(
        password_id).update(password.serialize())
    return get_password_metadata(lock_id, password_id)
예제 #3
0
def change_lock_status(lock_id, status, was_lock_removed=None):
    DB.child("Locks").child(lock_id).update({'status': status.value})

    if was_lock_removed is None:
        return {
            "status": status.value,
        }
    else:
        return {
            "status": status.value,
            "providedPasswordDisabled": was_lock_removed
        }
예제 #4
0
def delete_user_lock(uid, lock_id):
    user_lock_entry = DB.child("UserLocks").child(uid).get().val()

    owned_locks = set(
        user_lock_entry.get('ownedLockIds') if user_lock_entry else [])
    owned_locks.remove(lock_id)

    DB.child("UserLocks").child(uid).set(list(owned_locks))

    # TODO: more expensive than necessary, can simply build
    # an object using the variables above
    return get_user_locks(uid)
        def decorated_func(*args, **kws):
            if 'Authorization' in request.headers:
                header_key = 'Authorization'
            else:
                abort(401)
            data = str(request.headers[header_key])

            if not data.startswith('Basic'):
                raise ValidationException("Basic authorization required")

            coded_string = str.replace(str(data), 'Basic ', '')
            decoded = base64.b64decode(coded_string).decode('utf-8')
            string_split = decoded.split(':')
            if len(string_split) < 2:
                msg = ("Basic auth must be base-64 "
                       "encoded in 'lockId:password' format")
                raise AuthorizationException(msg)

            lock_id, secret = string_split[0], ':'.join(string_split[1:])
            try:
                secret_hashed = DB.child("Locks").child(
                    lock_id).get().val().get('secret')
            except BaseException:
                raise AuthorizationException("Lock could not be found")

            if not security_utils.check_password(secret, secret_hashed):
                raise AuthorizationException("Invalid secret supplied")
            return f(lock_id, *args, **kws)
def _get_sorted_passwords(lock_id):
    type_ordinal = {
        PasswordType.UNLIMITED: 0,
        PasswordType.OTP: 1,
    }

    passwords = DB.child("Locks").child(lock_id).child(
        "passwords").get().val() or {}
    passwords_list = [(pw_id, password_dict)
                      for pw_id, password_dict in passwords.items()]
    passwords_list = sorted(
        passwords_list, key=lambda x: type_ordinal[PasswordType(x[1]['type'])])
    passwords_list = [
        Password.from_database(id, password_dict)
        for id, password_dict in passwords_list
    ]

    expired_passwords = []
    output = []
    for password in passwords_list:
        if password.expiration != -1 \
                and password.expiration < time_utils.get_current_time_ms():
            expired_passwords.append(password)
        elif _password_is_active(password):
            output.append(password)

    _prune_passwords(lock_id, expired_passwords)
    return output
        def decorated_func(*args, **kws):
            if 'api_key' in request.args:
                token = request.args['api_key']
            else:
                if 'Authorization' in request.headers:
                    header_key = 'Authorization'
                elif 'Api-Key' in request.headers:
                    header_key = 'Api-Key'
                else:
                    abort(401)
                data = str(request.headers[header_key])
                token = str.replace(str(data), 'Bearer ', '')

            try:
                user = AUTH.get_account_info(token)['users'][0]
            except BaseException:
                abort(401)
            uid = user['localId']
            found_user = DB.child("Users").child(uid).get().val()
            if not found_user:
                create_or_update_user_from_json(uid, user)

            if admin and not found_user.get('isAdmin', False):
                raise AdminOnlyException("Admin account required")

            return f(uid, user, *args, **kws)
예제 #8
0
def create_or_update_user_lock(uid, user_locks, should_overwrite=False):
    invalid_ids = []
    for lock_id in user_locks.owned_lock_ids:
        if DB.child("Locks").child(lock_id).get().val() is None:
            invalid_ids.append(lock_id)

    if len(invalid_ids) > 0:
        raise ValidationException("Invalid lock ids: {}".format(invalid_ids))

    if not should_overwrite:
        user_lock_entry = DB.child("UserLocks").child(uid).get().val()
        prev_locks = user_lock_entry.get(
            'ownedLockIds') if user_lock_entry else []

        combined_locks = list(set(prev_locks).union(user_locks.owned_lock_ids))
        user_locks.owned_lock_ids = combined_locks
    DB.child("UserLocks").child(uid).set(user_locks.serialize())
    return user_locks.serialize()
def verify_lock_ownership(uid, lock_id):
    is_owned = True
    message = ''

    uid_lookup = DB.child("UserLocks").child(uid).get().val()

    if DB.child("Locks").child(lock_id).get().val() is None:
        is_owned = False
        message = 'Lock could not be identified'
    elif uid_lookup is None:
        is_owned = False
        message = 'User could not be identified or has not registered a lock'
    else:
        owned_locks = set(uid_lookup.get('ownedLockIds'))
        if lock_id not in owned_locks:
            is_owned = False
            message = 'User does not own this lock'

    if not is_owned:
        raise AuthorizationException(message=message)
예제 #10
0
def add_password(lock_id, password: Password) -> PasswordMetadata:
    new_id = DB.child("Locks").child(lock_id).child("passwords").push(
        password.serialize())['name']
    # return a metadata object instead of a password to ensure that the
    # password is not shared with the outside world
    return PasswordMetadata(
        type=password.type,
        expiration=password.expiration,
        active_days=password.active_days,
        active_times=password.active_times,
        id=new_id,
    )
예제 #11
0
def add_event(event: Event):
    serialized_event = event.serialize()
    new_id = DB.child("EventHistory").push(serialized_event)['name']
    event.id = new_id
    DB.child("LockEvents").child(event.lock_id).update({new_id: True})
    return {new_id: serialized_event}
예제 #12
0
def get_user_locks(uid):
    owned_lock_ids = DB.child("UserLocks").child(uid).child(
        'ownedLockIds').get().val()
    if owned_lock_ids is None:
        owned_lock_ids = []
    return {'ownedLockIds': owned_lock_ids}
def get_user(uid):
    return DB.child("Users").child(uid).get().val()
예제 #14
0
def get_lock_status(lock_id):
    status_str = DB.child("Locks").child(lock_id).get().val().get("status")
    return {"status": status_str}
예제 #15
0
def add_lock(lock):
    new_id = DB.child("Locks").push(lock.serialize())['name']
    lock.id = new_id
    return {new_id: lock.serialize()}
예제 #16
0
def remove_password_by_id(lock_id: str, password_id: str) -> None:
    if password_id.strip() == '':
        return
    DB.child("Locks").child(lock_id).child("passwords").child(
        password_id).remove()
def create_or_update_user_locks(user_locks):
    DB.child("UserLocks").set(user_locks.serialize())
예제 #18
0
def get_locks(lock_ids):
    return {
        lock_id: DB.child("Locks").child(lock_id).get().val()
        for lock_id in lock_ids
    }
def create_or_update_user(uid, user):
    DB.child("Users").child(uid).set(user.serialize())
def _prune_passwords(lock_id, passwords):
    for password in passwords:
        DB.child("Locks").child(lock_id).child("passwords").child(
            password.id).remove()