Example #1
0
def close_missing_case2():
    json_body = app.current_request.json_body

    # Load json data into object
    schema = MissingClosingSchema()
    missing, errors = schema.load(json_body)
    # Invalid JSON body
    if errors:
        raise ChaliceViewError(errors)

    with contextlib.closing(session_factory()) as session:
        try:
            # Check resident id is valid
            resident = session.query(Resident).get(missing.resident_id)
            if not resident:
                raise NotFoundError('Resident not exists')
            resident.status = 0
            session.merge(resident)
            # Close existing active missing cases
            updated = session.query(Missing).filter(
                Missing.resident_id == missing.resident_id,
                Missing.status == 1).all()
            count = session.query(Missing).filter(Missing.resident_id == missing.resident_id, Missing.status == 1) \
                .update({'status': 0, 'closed_by': missing.closed_by, 'closure': missing.closure,
                         'closed_at': datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')})
            notify_close_missing(db_session=session, missing=missing)
            # Call flush() to update id value in missing
            session.flush()
            session.commit()
            schema = MissingClosingSchema(many=True)
            return schema.dump(updated).data
        except exc.SQLAlchemyError as e:
            session.rollback()
            raise ChaliceViewError(str(e))
Example #2
0
def reset_password():
    json_body = app.current_request.json_body
    email = json_body['email']
    token = str(json_body['token'])
    password = json_body['password']
    if not (email or password or token):
        raise BadRequestError("Email, password and token mush be supplied.")
    with contextlib.closing(session_factory()) as session:
        user = session.query(User).filter(User.email == email).first()
        user_token = session.query(UserToken).filter(
            UserToken.user_id == user.id).first()
        if not user:
            raise NotFoundError("User not found")
        if datetime.now() > user_token.expire:
            raise BadRequestError("Token is expired.")
        if not user_token:
            raise BadRequestError("Please request for a token first")
        if not verify_password_reset_token(token=token,
                                           salt=user.password_salt,
                                           hashed_token=user_token.token):
            raise BadRequestError("Token is invalid")
        result = encode_password(password=password, salt=user.password_salt)
        session.query(User).filter(User.email == email).update(
            {'password_hash': result['hashed']})
        session.flush()
        session.commit()
        jwt_token = get_jwt_token(
            user.email + "," + str(user.role) + "," + str(user.id), password,
            user.password_salt, user.password_hash, JWT_SECRET)
        info = {'token': jwt_token, 'user': user}
        schema = TokenSchema()
        response = schema.dumps(info)
        if response.errors:
            raise ChaliceViewError(response.errors)
        return response.data
Example #3
0
def register():
    json_body = app.current_request.json_body
    email = json_body['email']
    password = json_body['password']
    if not (email or password):
        raise BadRequestError("Email and password must be supplied.")

    result = encode_password(password)
    hashed_password = result['hashed']
    salt_used = result['salt']
    json_body.pop('password', None)
    schema = UserSchema()
    user, errors = schema.load(json_body)
    user.password_hash = hashed_password
    user.password_salt = salt_used

    with contextlib.closing(session_factory()) as session:
        try:
            session.add(user)
            session.commit()
            user_profile = UserProfile()
            user_profile.email = user.email
            user_profile.user_id = user.id
            session.add(user_profile)
            session.commit()
            user_schema = UserSchema(exclude=('password_hash', 'salt',
                                              'access_token'))
            result = user_schema.dump(user)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
        except exc.SQLAlchemyError as e:
            session.rollback()
            raise ChaliceViewError(str(e))
Example #4
0
def expire_missing_case_minutes_older(minutes):
    deadline = datetime.datetime.utcnow() - datetime.timedelta(minutes=minutes)
    hours = minutes / 60.0
    with contextlib.closing(session_factory()) as session:
        query_missing = session.query(Missing)
        query_resident = session.query(Resident)
        try:
            expired_list = query_missing.filter(
                and_(Missing.created_at < deadline,
                     Missing.status == 1)).all()
            for missing_case in expired_list:
                print(missing_case)
                # Update missing case as expired
                missing_case.status = 0
                missing_case.closure = "Expired after {:.2f} hours".format(
                    hours)
                missing_case.closed_at = datetime.datetime.utcnow()
                session.merge(missing_case)
                # Update resident status to 0 if missing is closed
                resident = query_resident.get(missing_case.resident_id)
                resident.status = 0
                # Notify all caregivers
                notify_expired_missing(db_session=session,
                                       missing=missing_case)
                session.flush()

            session.commit()
        except Exception as e:
            session.rollback()
            raise ChaliceViewError(str(e))
Example #5
0
def forgot_password():
    json_body = app.current_request.json_body
    email = json_body['email']
    if not email:
        raise BadRequestError("Email must be supplied.")
    # Generate 5 digit code
    token = str(randint(10000, 99999))
    expire = datetime.now() + timedelta(days=1)

    with contextlib.closing(session_factory()) as session:
        try:
            user = session.query(User).filter(User.email == email).first()
            if not user:
                raise NotFoundError("User not found")
            # Uncomment this if we want to hash the token
            if user.password_salt is None:
                user.password_salt = base64.b64encode(
                    os.urandom(16)).decode('utf-8')
                session.merge(user)

            result = encode_password_reset_token(token=token,
                                                 salt=user.password_salt)
            hashed_token = result['hashed']
            user_token = session.query(UserToken).filter(
                and_(UserToken.user_id == user.id, UserToken.label ==
                     UserToken.LABEL_PASSWORD_RESET)).first()
            if not user_token:
                schema = UserTokenSchema()
                json_body['user_id'] = user.id
                json_body['token'] = hashed_token
                user_token, errors = schema.load(json_body)
                user_token.expire = expire
                user_token.label = UserToken.LABEL_PASSWORD_RESET
                session.add(user_token)
                session.flush()
            else:
                # Update the existing user_token
                user_token.token = hashed_token
                user_token.expire = expire
                user_token.label = UserToken.LABEL_PASSWORD_RESET
                session.flush()

            if not user.user_profile:
                user_profile = UserProfile()
                user_profile.user_id = user.id
                user_profile.email = user.email
                session.add(user_profile)
                session.flush()

            session.commit()
            notify_password_reset(db_session=session, user=user, token=token)
            # return json.dumps({"token": token})
            return json.dumps({
                'Code': 'Successful',
                'Message': 'Reset code has been emailed to you.'
            })
        except Exception as e:
            session.rollback()
            raise ChaliceViewError(str(e))
Example #6
0
def get_missing_by_id(id):
    with contextlib.closing(session_factory()) as session:
        missing = session.query(Missing).get(id)
        if not missing:
            raise NotFoundError("Missing case not found")
        else:
            missing_schema = MissingSchema()
            result = missing_schema.dump(missing)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #7
0
def list_all_beacons():
    with contextlib.closing(session_factory()) as session:
        beacons = session.query(Beacon).all()
        if not beacons:
            raise NotFoundError("No beacon found")
        else:
            beacons_schema = BeaconSchema(many=True, exclude=('resident', ))
            result = beacons_schema.dump(beacons)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #8
0
def list_settings():
    with contextlib.closing(session_factory()) as session:
        settings = session.query(Setting).all()
        if not settings:
            raise NotFoundError("No setting available")
        else:
            settings_schema = SettingSchema(many=True)
            result = settings_schema.dump(settings)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #9
0
def get_beacon_by_id(id):
    with contextlib.closing(session_factory()) as session:
        beacon = session.query(Beacon).get(id)
        if not beacon:
            raise NotFoundError("No beacon found")
        else:
            beacon_schema = BeaconSchema(exclude=('resident.missings', ))
            result = beacon_schema.dump(beacon)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #10
0
def list_caregivers_by_resident_id(id):
    with contextlib.closing(session_factory()) as session:
        resident = session.query(Resident).get(id)
        if not resident:
            raise NotFoundError("Missing case not found")
        else:
            resident_schema = ResidentSchema(only=('caregivers', ))
            result = resident_schema.dump(resident)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #11
0
def expire_missing_case(event):
    with contextlib.closing(session_factory()) as session:
        minutes = 24 * 60  # by default 24 hours
        try:
            setting = session.query(Setting).filter(
                Setting.label == Setting.LABEL_MINUTES_TO_EXPIRE_CASE)
            if setting:
                minutes = int(setting.val)
        except Exception as e:
            print(str(e))

        expire_missing_case_minutes_older(minutes)
Example #12
0
def add_location_by_beacon_info():
    json_body = app.current_request.json_body
    # Load json data into object
    schema = LocationBeaconSchema()
    location, errors = schema.load(json_body)
    # Invalid JSON body
    if errors:
        raise ChaliceViewError(errors)

    with contextlib.closing(session_factory()) as session:
        try:
            beacon = session.query(Beacon).filter(
                Beacon.uuid == location['uuid'],
                Beacon.major == location['major'],
                Beacon.minor == location['minor']).first()
            if not beacon:
                raise BadRequestError("Invalid beacon id")
            if beacon.status != 1:
                raise BadRequestError("Beacon is disabled")
            missing = session.query(Missing).filter(
                Missing.resident_id == beacon.resident_id,
                Missing.status == 1).first()
            if not missing:
                raise BadRequestError("No active missing case")

            location['beacon_id'] = beacon.id
            location.pop('uuid', None)
            location.pop('major', None)
            location.pop('minor', None)
            location = Location(**location)
            location.resident_id = missing.resident_id
            location.missing_id = missing.id
            session.add(location)

            # Send notification on 1st time found
            if not (missing.latitude and missing.longitude):
                notify_found_missing(db_session=session, missing=missing)

            # Update latest location to missing
            missing.latitude = location.latitude
            missing.longitude = location.longitude
            missing.address = location.address
            session.merge(missing)

            # Call flush() to update id value in missing
            session.flush()
            session.commit()
            schema = LocationSchema(exclude=('user', 'locator', 'resident'))
            return schema.dump(location)
        except exc.SQLAlchemyError as e:
            session.rollback()
            raise ChaliceViewError(str(e))
Example #13
0
def list_all_missing_cases():
    with contextlib.closing(session_factory()) as session:
        missings = session.query(Missing).all()
        if not missings:
            raise NotFoundError("No missing case")
        else:
            missings_schema = MissingSchema(many=True,
                                            exclude=('resident.caregivers',
                                                     'resident.beacons'))
            result = missings_schema.dump(missings)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #14
0
def list_uuid_of_active_missing_cases_beacons():
    with contextlib.closing(session_factory()) as session:
        beacons = session.query(Beacon) \
            .join(Resident, Resident.id == Beacon.resident_id) \
            .join(Missing, Missing.resident_id == Resident.id) \
            .filter(Missing.status == 1).all()
        if not beacons:
            raise NotFoundError("No beacon of missing residents found")
        else:
            uuid_list = set()
            for beacon in beacons:
                uuid_list.add(beacon.uuid)
            return json.dumps({"uuid_list": uuid_list}, cls=SetEncoder)
Example #15
0
def list_all_residents():
    with contextlib.closing(session_factory()) as session:
        residents = session.query(Resident).all()
        if not residents:
            raise NotFoundError("No resident found")
        else:
            residents_schema = ResidentSchema(exclude=('beacons', 'missings',
                                                       'caregivers'),
                                              many=True)
            result = residents_schema.dump(residents)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #16
0
def get_beacon_by_resident_id(resident_id):
    with contextlib.closing(session_factory()) as session:
        beacons = session.query(Beacon) \
            .join(Resident, Resident.id == Beacon.resident_id) \
            .filter(Resident.id == resident_id).all()
        if not beacons:
            raise NotFoundError("No beacon found")
        else:
            beacons_schema = BeaconSchema(exclude=('resident', ), many=True)
            result = beacons_schema.dump(beacons)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #17
0
def disable_beacon_by_id(id):
    with contextlib.closing(session_factory()) as session:
        try:
            beacon = session.query(Beacon).get(id)
            count = session.query(Beacon).filter(
                Beacon.id == id, Beacon.status == 1).update({'status': 0})
            # Call flush() to update id value in missing
            session.flush()
            session.commit()
            schema = BeaconSchema(exclude=('resident', ))
            return schema.dump(beacon).data
        except exc.SQLAlchemyError as e:
            session.rollback()
            raise ChaliceViewError(str(e))
Example #18
0
def list_missing_residents():
    with contextlib.closing(session_factory()) as session:
        residents = session.query(Resident) \
            .join(Missing, Missing.resident_id == Resident.id) \
            .filter(and_(Resident.status == 1, Missing.status == 1)) \
            .all()
        if not residents:
            raise NotFoundError("No missing resident found")
        else:
            residents_schema = ResidentSchema(
                exclude=('beacons', 'missings', 'caregivers',
                         'missing_active.locations'),
                many=True)
            result = residents_schema.dump(residents)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #19
0
def list_beacons_of_active_missing_cases():
    with contextlib.closing(session_factory()) as session:
        beacons = session.query(Beacon) \
            .join(Resident, Resident.id == Beacon.resident_id) \
            .join(Missing, Missing.resident_id == Resident.id) \
            .filter(Missing.status == 1, Beacon.status == 1).all()
        if not beacons:
            raise NotFoundError("No beacon of missing residents found")
        else:
            beacons_schema = BeaconSchema(many=True,
                                          exclude=('resident.caregivers',
                                                   'resident.beacons',
                                                   'resident.missings'))
            result = beacons_schema.dump(beacons)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #20
0
def update_beacon_status_by_id(id, status):
    if int(status) not in [0, 1]:
        raise BadRequestError("Status value can only be 0 or 1")
    with contextlib.closing(session_factory()) as session:
        try:
            beacon = session.query(Beacon).get(id)
            if beacon is None:
                raise NotFoundError("Beacon ({}) not exists.".format(id))
            count = session.query(Beacon).filter(Beacon.id == id).update(
                {'status': status})
            # Call flush() to update id value in missing
            session.flush()
            session.commit()
            schema = BeaconSchema(exclude=('resident', ))
            return schema.dump(beacon).data
        except exc.SQLAlchemyError as e:
            session.rollback()
            raise ChaliceViewError(str(e))
Example #21
0
def list_latest_locations_of_missing_case(missing_id):
    with contextlib.closing(session_factory()) as session:
        locations = session.query(Location) \
            .join(Missing, Missing.id == Location.missing_id) \
            .filter(Missing.id == missing_id) \
            .order_by(Location.id.desc()) \
            .limit(20) \
            .all()
        if not locations:
            raise NotFoundError("No location of this missing case found")
        else:
            locations_schema = LocationSchema(many=True,
                                              exclude=('resident', 'missing',
                                                       'locator', 'user'))
            result = locations_schema.dump(locations)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #22
0
def list_relative_residents():
    current_user = auth.get_authorized_user(app.current_request)
    with contextlib.closing(session_factory()) as session:
        residents = session.query(Resident) \
            .join(Caregiver, Caregiver.resident_id == Resident.id) \
            .filter(Caregiver.user_id == current_user['id']) \
            .order_by(Resident.status.desc(), Resident.fullname.asc()) \
            .all()
        if not residents:
            raise NotFoundError("No resident found")
        else:
            residents_schema = ResidentSchema(
                exclude=('beacons', 'missings', 'caregivers',
                         'missing_active.locations'),
                many=True)
            result = residents_schema.dump(residents)
            if result.errors:  # errors not empty
                raise ChaliceViewError(result.errors)
            return result.data
Example #23
0
def login():
    json_body = app.current_request.json_body
    email = json_body['email']
    password = json_body['password']
    if not (email or password):
        raise BadRequestError("Email and password must be supplied.")

    with contextlib.closing(session_factory()) as session:
        user = session.query(User).filter(User.email == email).first()
        if not user:
            raise NotFoundError("User not found")
        print("{}, {}, {}".format(user.email, user.role, user.id))
        # Add to token ==> email + "|" + role
        jwt_token = get_jwt_token(
            user.email + "," + str(user.role) + "," + str(user.id), password,
            user.password_salt, user.password_hash, JWT_SECRET)
        info = {'token': jwt_token, 'user': user}
        schema = TokenSchema()
        response = schema.dumps(info)
        if response.errors:
            raise ChaliceViewError(response.errors)
        return response.data
Example #24
0
def create_new_missing_case2():
    json_body = app.current_request.json_body

    # Load json data into object
    missing_schema = MissingSchema(exclude=('resident.beacons',
                                            'resident.missings',
                                            'resident.missing_active',
                                            'resident.caregivers'))
    missing, errors = missing_schema.load(json_body)
    # Invalid JSON body
    if errors:
        raise ChaliceViewError(errors)

    with contextlib.closing(session_factory()) as session:
        try:
            # Check resident id is valid
            resident = session.query(Resident).get(missing.resident_id)
            if not resident:
                raise NotFoundError('Resident not exists')
            resident.status = 1
            session.merge(resident)
            # Close existing active missing cases
            session.query(Missing).filter(Missing.resident_id == missing.resident_id, Missing.status == 1) \
                .update({'status': 0, 'closed_by': missing.reported_by,
                         'closed_at': datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')})
            # Add new missing case
            session.add(missing)
            # Notify other caregivers
            notify_new_missing(db_session=session, missing=missing)
            # Call flush() to update id value in missing
            session.flush()
            session.commit()
            return missing_schema.dump(missing).data
        except exc.SQLAlchemyError as e:
            session.rollback()
            raise ChaliceViewError(str(e))