<commit_before>from datetime import datetime

from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound

from flask import request, jsonify
from flask_login import current_user

from app.user import user
from app.models import Users, Events
from app.constants import USER_ID_DELIMITER, event_type
from app.lib.db_utils import update_object, create_object
from app.lib.utils import eval_request_bool


@user.route('/<user_id>', methods=['PATCH'])
def patch(user_id):
    """
    Request Parameters:
    - title
    - organization
    - email
    - phone_number
    - fax_number
    - mailing_address
    - is_super
    - is_agency_active
    - is_agency_admin
    (Mailing Address)
    - zip
    - city
    - state
    - address_one
    - address_two

    Restrictions:
    - Anonymous Users
        - cannot access this endpoint
    - Agency Administrators
        - cannot change their agency status
        - can only update the agency status of users within their agency
        - cannot change any super user status
    - Super Users
        - cannot change their super user status
    - Agency Users
        - cannot change any user except for themselves or
          *anonymous* requesters for requests they are assigned to
        - cannot change super user or agency status
    - Public Users
        - can only update themselves
        - cannot change super user or agency status

    """
    if not current_user.is_anonymous:
        # attempt to parse user_id and find user
        try:
            guid, auth_type = user_id.split(USER_ID_DELIMITER)
            user_ = Users.query.filter_by(guid=guid,
                                          auth_user_type=auth_type).one()
        except (ValueError, NoResultFound, MultipleResultsFound):
            return jsonify({}), 404

        updating_self = current_user == user_
        current_user_is_agency_user = (current_user.is_agency
                                       and not current_user.is_agency_admin
                                       and current_user.is_agency_active)
        current_user_is_agency_admin = (current_user.is_agency
                                        and current_user.is_agency_admin
                                        and current_user.is_agency_active)
        same_agency = current_user.agency is user_.agency
        associated_anonymous_requester = (user_.is_anonymous_requester
                                          and current_user.user_requests.filter_by(
                                            request_id=user_.anonymous_request.id
                                          ).first() is None)

        is_agency_admin = request.form.get('is_agency_admin')
        is_agency_active = request.form.get('is_agency_active')
        is_super = request.form.get('is_super')

        changing_status = any((is_agency_active, is_agency_admin, is_super))

        rform_copy = dict(request.form)
        try:
            rform_copy.pop('is_agency_admin')
            rform_copy.pop('is_agency_active')
            changing_more_than_agency_status = len(rform_copy) != 0
        except KeyError:
            changing_more_than_agency_status = False

        # VALIDATE
        if ((updating_self and (
                # super user attempting to change their own super status
                (current_user.is_super and is_super is not None)
            or
                # agency admin or public user attempting to change their own agency/super status
                (changing_status and (current_user_is_agency_admin or current_user.is_public)))) or
           (not updating_self and (
                # public user attempting to change another user
                current_user.is_public
            or
                # agency user attempting to change a agency/super status
                (current_user_is_agency_user and changing_status)
            or
                # agency admin attempting to change another user that is not in the same agency or
                # attempting to change more than just the agency status of a user
                (current_user_is_agency_admin and (not same_agency or changing_more_than_agency_status))
            or
                # agency user attempting to change a user that is not an anonymous requester
                # for a request they are assigned to
                (current_user_is_agency_user and (
                            not user_.is_anonymous_requester or associated_anonymous_requester))
            or
                # agency admin attempting to change an anonymous requester for a request
                # they are not assigned to
                (current_user_is_agency_admin and associated_anonymous_requester)))):
            return jsonify({}), 403

        # UPDATE
        user_fields = [
            'email',
            'phone_number',
            'fax_number',
            'title',
            'organization'
        ]
        status_fields = [<commit_msg>Fixed edit requester information<commit_after>from datetime import datetime

from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound

from flask import request, jsonify
from flask_login import current_user

from app.user import user
from app.models import Users, Events
from app.constants import USER_ID_DELIMITER, event_type
from app.lib.db_utils import update_object, create_object
from app.lib.utils import eval_request_bool


@user.route('/<user_id>', methods=['PATCH'])
def patch(user_id):
    """
    Request Parameters:
    - title
    - organization
    - email
    - phone_number
    - fax_number
    - mailing_address
    - is_super
    - is_agency_active
    - is_agency_admin
    (Mailing Address)
    - zip
    - city
    - state
    - address_one
    - address_two

    Restrictions:
    - Anonymous Users
        - cannot access this endpoint
    - Agency Administrators
        - cannot change their agency status
        - can only update the agency status of users within their agency
        - cannot change any super user status
    - Super Users
        - cannot change their super user status
    - Agency Users
        - cannot change any user except for themselves or
          *anonymous* requesters for requests they are assigned to
        - cannot change super user or agency status
    - Public Users
        - can only update themselves
        - cannot change super user or agency status

    """
    if not current_user.is_anonymous:
        # attempt to parse user_id and find user
        try:
            guid, auth_type = user_id.split(USER_ID_DELIMITER)
            user_ = Users.query.filter_by(guid=guid,
                                          auth_user_type=auth_type).one()
        except (ValueError, NoResultFound, MultipleResultsFound):
            return jsonify({}), 404

        updating_self = current_user == user_
        current_user_is_agency_user = (current_user.is_agency
                                       and not current_user.is_agency_admin
                                       and current_user.is_agency_active)
        current_user_is_agency_admin = (current_user.is_agency
                                        and current_user.is_agency_admin
                                        and current_user.is_agency_active)
        same_agency = current_user.agency is user_.agency
        associated_anonymous_requester = (user_.is_anonymous_requester
                                          and current_user.user_requests.filter_by(
                                            request_id=user_.anonymous_request.id
                                          ).first() is None)

        is_agency_admin = request.form.get('is_agency_admin')
        is_agency_active = request.form.get('is_agency_active')
        is_super = request.form.get('is_super')

        changing_status = any((is_agency_active, is_agency_admin, is_super))

        rform_copy = dict(request.form)
        try:
            rform_copy.pop('is_agency_admin')
            rform_copy.pop('is_agency_active')
            changing_more_than_agency_status = len(rform_copy) != 0
        except KeyError:
            changing_more_than_agency_status = False

        # VALIDATE
        if ((updating_self and (
                # super user attempting to change their own super status
                (current_user.is_super and is_super is not None)
            or
                # agency admin or public user attempting to change their own agency/super status
                (changing_status and (current_user_is_agency_admin or current_user.is_public)))) or
           (not updating_self and (
                # public user attempting to change another user
                current_user.is_public
            or
                # agency user attempting to change a agency/super status
                (current_user_is_agency_user and changing_status)
            or
                # agency user attempting to change a user that is not an anonymous requester
                # for a request they are assigned to
                (current_user_is_agency_user and (
                            not user_.is_anonymous_requester or not associated_anonymous_requester))
            or
               # agency admin attempting to change another user that is not in the same agency or
               # attempting to change more than just the agency status of a user
               (current_user_is_agency_admin
                and not (associated_anonymous_requester or user_.is_anonymous_requester)
                and (not same_agency or changing_more_than_agency_status))
            or
                # agency admin attempting to change an anonymous requester for a request
                # they are not assigned to
                (current_user_is_agency_admin and associated_anonymous_requester)))):
            return jsonify({}), 403

        # UPDATE
        user_fields = [
            'email',
            'phone_number',
            'fax_number',
            'title',
            'organization'
        ]
        status_fields = [
{'fraction_non_alphanumeric': 0.051677785522254306, 'fraction_numerical': 0.0013940057751667828, 'mean_word_length': 1.8795871559633028, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6390685', 'n_tokens_mistral': 2583, 'n_tokens_neox': 2431, 'n_words': 757}