def delete_accounts():
    """
    Deletes all user marked for deletion. to be called from scheduler
    """
    try:
        logger.info("Scheduler deleting users marked for deletion")
        with transactional_session() as session:
            marked_for_deletion_users = session.query(User).filter(
                User.mark_for_deletion == True)  # noqa
            if marked_for_deletion_users.count() > 0:
                logger.info("sending request to party service to remove ")
                delete_party_respondents_and_auth_user(
                    marked_for_deletion_users, session)
                logger.info(
                    "Scheduler successfully deleted users marked for deletion")
            else:
                logger.info(
                    "No user marked for deletion at this time. Nothing to delete."
                )

    except SQLAlchemyError:
        logger.exception("Unable to perform scheduler delete operation")
        return make_response(
            jsonify({
                "title": "Scheduler operation for delete users error",
                "detail": "Unable to perform delete operation"
            }),
            500,
        )
    return "", 204
Ejemplo n.º 2
0
def put_account():
    put_params = request.form

    try:
        username = put_params["username"]
    except KeyError as ex:
        logger.info("Missing request parameter", exc_info=ex)
        return make_response(
            jsonify({
                "title": "Auth service account update user error",
                "detail": "Missing 'username'"
            }), 400)

    try:
        with transactional_session() as session:
            user = session.query(User).filter(
                User.username == username).first()

            if not user:
                logger.info("User does not exist")
                return make_response(
                    jsonify({
                        "title":
                        "Auth service account update user error",
                        "detail":
                        "Unauthorized user credentials. This user does not exist on the Auth server",
                    }),
                    401,
                )

            user.update_user(put_params)
    except ValueError as ex:
        logger.info("Request param is an invalid type", exc_info=ex)
        return make_response(
            jsonify({
                "title": "Auth service account update user error",
                "detail": "account_verified status is invalid"
            }),
            400,
        )
    except SQLAlchemyError:
        logger.exception("Unable to commit updated account to database")
        return make_response(
            jsonify({
                "title": "Auth service account update user error",
                "detail": "Unable to commit updated account to database",
            }),
            500,
        )

    logger.info("Successfully updated account", user_id=user.id)
    return make_response(
        jsonify({
            "account": user.username,
            "updated": "success"
        }), 201)
Ejemplo n.º 3
0
def post_token():
    """This endpoint looks weird because it has a history with the previous authentication service.
    The previous one had a /tokens endpoint to provide oauth tokens for users who provided correct credentials.
    In the changeover from the old auth service to this one, to make the changeover less risky, we kept this endpoint
    with the same name, but instead of it returning a json payload with tokens, we decided a 204 would suffice as
    the HTTP equivalent of a thumbs up that the credentials were correct.

    Once the old service has been retired, this endpoint and this services API as a whole needs to be reviewed
    and cleaned up.
    """
    post_params = request.form

    try:
        payload = account_schema.load(post_params)
    except ValidationError as ex:
        logger.info("Missing request parameter", exc_info=ex)
        return make_response(
            jsonify({
                "title": "Auth service tokens error",
                "detail": "Missing 'username' or 'password'"
            }), 400)

    bound_logger = logger.bind(
        obfuscated_username=obfuscate_email(payload.get('username')))

    with transactional_session() as session:
        bound_logger.info("Searching for user")
        user = session.query(User).filter(
            func.lower(User.username) == func.lower(payload.get(
                'username'))).first()

        if not user:
            bound_logger.info("User does not exist")
            return make_response(
                jsonify({
                    "title":
                    "Auth service tokens error",
                    "detail":
                    "Unauthorized user credentials. This user does not exist on the Auth server"
                }), 401)

        bound_logger.info("User found")
        try:
            user.authorise(payload.get('password'))
        except Unauthorized as ex:
            bound_logger.info("User is unauthorised",
                              description=ex.description)
            return make_response(
                jsonify({
                    "title": "Auth service tokens error",
                    "detail": ex.description
                }), 401)

    logger.info("User credentials correct")
    return make_response('', 204)
def mark_for_deletion_accounts():
    """
    Marks user accounts for deletion which has not been accessed in the last 36 months.
    To be called from scheduler
    """
    try:
        with transactional_session() as session:
            logger.info(
                "Scheduler processing Accounts not accessed in the last 36 months "
            )
            # process to mark account ready for deletion for
            # accounts not accessed in the last 36 months
            _since_36_months = datetime.utcnow() - timedelta(days=1095)
            _last_login_before_36_months = session.query(User).filter(
                and_(User.last_login_date != None,
                     User.last_login_date < _since_36_months)  # noqa
            )
            _last_login_before_36_months.update({"mark_for_deletion": True})
            _account_created_before_36_months = session.query(User).filter(
                and_(User.last_login_date == None,
                     User.account_creation_date < _since_36_months)  # noqa
            )
            _account_created_before_36_months.update(
                {"mark_for_deletion": True})
            logger.info(
                "Scheduler finished processing Accounts not accessed in last 36 months"
            )
            # process to mark account ready for deletion for
            # accounts not been activated in the last 80 hrs.
            logger.info(
                "Scheduler processing Account not activated for more than 80 hrs"
            )
            _since_80_hrs = datetime.utcnow() - timedelta(hours=80)
            _account_not_activated_80_hrs = session.query(User).filter(
                and_(User.account_verified == False,
                     User.account_creation_date < _since_80_hrs)  # noqa
            )
            _account_not_activated_80_hrs.update({"mark_for_deletion": True})
            logger.info(
                "Scheduler finished* processing Account not activated for more than 80 hrs"
            )
    except SQLAlchemyError:
        logger.exception(
            "Unable to perform scheduler mark for delete operation")
        return make_response(
            jsonify({
                "title":
                "Scheduler operation for mark for delete users error",
                "detail":
                "Unable to perform delete operation for accounts not accessed in last "
                "36 months",
            }),
            500,
        )
    return "", 204
Ejemplo n.º 5
0
def patch_account(username):
    """
    Patch endpoint for user resource.
    Currently only marked_for_deletion, first_notification, second_notification and third_notification
     attribute can be patched
    @param: username
    """
    logger.info("Starting patch operation on user",
                username=obfuscate_email(username))
    req = request.form
    try:
        patch_data = patch_account_schema.load(req)
    except ValidationError as ex:
        logger.exception("Patch data validation error", exc_info=ex)
        return make_response(
            jsonify({
                "title": "Bad Request error in Auth service",
                "detail": "Patch data validation failed"
            }), 400)
    try:
        with transactional_session() as session:
            user = session.query(User).filter(
                func.lower(User.username) == username.lower()).one()
            user.patch_user(patch_data)

    except NoResultFound:
        logger.error("User does not exist", username=obfuscate_email(username))
        return make_response(
            jsonify({
                "title": "Auth service undo delete user error",
                "detail": "This user does not exist on the Auth server",
            }),
            404,
        )
    except SQLAlchemyError:
        logger.exception("Unable to commit undo delete operation",
                         username=obfuscate_email(username))
        return make_response(
            jsonify({
                "title": "Auth service undo delete user error",
                "detail": "Unable to commit undo delete operation"
            }),
            500,
        )

    logger.info("Successfully completed patch operation on user",
                username=obfuscate_email(username))
    return "", 204
Ejemplo n.º 6
0
def get_account_by_user_name(username):
    """
    Get user data.
    """
    try:
        with transactional_session() as session:
            user = session.query(User).filter(
                func.lower(User.username) == username.lower()).one()
    except NoResultFound:
        logger.info("User does not exist", username=obfuscate_email(username))
        return make_response(
            jsonify({
                "title": "Auth service get user error",
                "detail": "This user does not exist on the Auth server"
            }), 404)
    return jsonify(user.to_user_dict())
Ejemplo n.º 7
0
def post_account():
    post_params = request.form

    try:
        payload = account_schema.load(post_params)
    except ValidationError as ex:
        logger.info("Missing request parameter", exc_info=ex)
        return make_response(
            jsonify({
                "title": "Authentication error in Auth service",
                "detail": "Missing 'username' or 'password'"
            }),
            400,
        )

    try:
        with transactional_session() as session:
            user = User(username=payload.get("username"))
            user.set_hashed_password(payload.get("password"))
            session.add(user)
    except IntegrityError:
        logger.exception("Unable to create account with requested username")
        return make_response(
            jsonify({
                "title":
                "Auth service account create error",
                "detail":
                "Unable to create account with requested username",
            }),
            500,
        )
    except SQLAlchemyError:
        logger.exception("Unable to commit account to database")
        return make_response(
            jsonify({
                "title": "Auth service account create db error",
                "detail": "Unable to commit account to database"
            }),
            500,
        )

    logger.info("Successfully created account", user_id=user.id)
    return make_response(
        jsonify({
            "account": user.username,
            "created": "success"
        }), 201)
Ejemplo n.º 8
0
def delete_account():
    """
    Updates user data to be marked for deletion.
    """
    params = request.form
    try:
        username = params["username"]
        logger.info("Deleting user", username=obfuscate_email(username))
        with transactional_session() as session:
            user = session.query(User).filter(
                func.lower(User.username) == username.lower()).one()
            user.mark_for_deletion = True
            if "force_delete" in params.keys():
                user.force_delete = strtobool(params["force_delete"])
            session.commit()
    except KeyError:
        logger.exception("Missing request parameter")
        return make_response(
            jsonify({
                "title": "Auth service delete user error",
                "detail": "Missing 'username'"
            }), 400)
    except NoResultFound:
        logger.error("User does not exist", username=obfuscate_email(username))
        return make_response(
            jsonify({
                "title": "Auth service delete user error",
                "detail": "This user does not exist on the Auth server"
            }),
            404,
        )

    except SQLAlchemyError:
        logger.exception("Unable to commit delete operation",
                         username=obfuscate_email(username))
        return make_response(
            jsonify({
                "title": "Auth service delete user error",
                "detail": "Unable to commit delete operation"
            }), 500)

    logger.info("Successfully deleted user",
                username=obfuscate_email(username))
    return "", 204
def get_users_eligible_for_first_notification():
    _datetime_24_months_ago = datetime.utcnow() - timedelta(days=730)
    _datetime_30_months_ago = datetime.utcnow() - timedelta(days=913)
    try:
        with transactional_session() as session:
            logger.info(
                "Getting users eligible for fist due deletion notification")
            users_eligible_for_first_notification = session.query(
                User.username).filter(
                    or_(
                        and_(
                            User.last_login_date != None,  # noqa
                            User.last_login_date.between(
                                _datetime_30_months_ago,
                                _datetime_24_months_ago),
                            User.first_notification == None,  # noqa
                        ),
                        and_(
                            User.last_login_date == None,  # noqa
                            User.account_creation_date.between(
                                _datetime_30_months_ago,
                                _datetime_24_months_ago),
                            User.first_notification == None,  # noqa
                        ),
                    ))
            logger.info(
                "Found users eligible for first due deletion notification")
            return jsonify([
                x for x in chain.from_iterable(
                    users_eligible_for_first_notification)
                if isinstance(x, str)
            ])
    except NoResultFound:
        logger.info(
            "No existing user eligible for first due deletion notification")
        return {}, 404
 def is_first_notification_set(self, user_name):
     with self.app.app_context():
         with transactional_session() as session:
             user = session.query(User.first_notification).filter(User.username == user_name).first()
             return user.first_notification != None  # noqa
 def is_user_marked_for_deletion(self, user_name):
     with self.app.app_context():
         with transactional_session() as session:
             user = session.query(User.mark_for_deletion).filter(User.username == user_name).first()
             return user.mark_for_deletion == True  # noqa
 def does_user_exists(self, user_name):
     with self.app.app_context():
         with transactional_session() as session:
             return bool(session.query(User).filter(User.username == user_name).first())