示例#1
0
    def get():
        if not (jwt.requires_roles(User.EDITOR)
                or jwt.requires_roles(User.APPROVER)):
            return jsonify({
                "message":
                "Error: You do not have access to the Name Request queue."
            }), 403

        try:
            user = User.find_by_jwtToken(g.jwt_oidc_token_info)
            current_app.logger.debug('find user')
            if not user:
                user = User.create_from_jwtToken(g.jwt_oidc_token_info)
            nr = RequestDAO.get_queued_oldest(user)

        except SQLAlchemyError as err:
            # TODO should put some span trace on the error message
            current_app.logger.error(err.with_traceback(None))
            return jsonify({
                'message':
                'An error occurred getting the next Name Request.'
            }), 500
        except AttributeError as err:
            current_app.logger.error(err)
            return jsonify(
                {'message': 'There are no Name Requests to work on.'}), 404

        return jsonify(nameRequest='{}'.format(nr)), 200
示例#2
0
    def patch(nr, choice, *args, **kwargs):

        json_data = request.get_json()
        if not json_data:
            return jsonify({'message': 'No input data provided'}), 400

        errors = names_schema.validate(json_data, partial=True)
        if errors:
            return jsonify(errors), 400

        nrd, nrd_name, msg, code = NRNames.common(nr, choice)
        if not nrd:
            return msg, code

        user = User.find_by_jwtToken(g.jwt_oidc_token_info)
        if not check_ownership(nrd, user):
            return jsonify({
                "message":
                "You must be the active editor and it must be INPROGRESS"
            }), 403

        names_schema.load(json_data, instance=nrd_name, partial=True)
        nrd_name.save_to_db()

        return jsonify(
            {"message": "Patched {nr} - {json}".format(nr=nr,
                                                       json=json_data)}), 200
示例#3
0
def get_or_create_user_by_jwt(jwt_oidc_token):
    # GET existing or CREATE new user based on the JWT info
    try:
        user = User.find_by_jwtToken(jwt_oidc_token)
        current_app.logger.debug('finding user: {}'.format(jwt_oidc_token))
        if not user:
            current_app.logger.debug(
                'didnt find user, attempting to create new user from the JWT info:{}'.format(jwt_oidc_token))
            user = User.create_from_jwtToken(jwt_oidc_token)

        return user
    except Exception as err:
        current_app.logger.error(err.with_traceback(None))
        raise ServicesError('unable_to_get_or_create_user',
                            '{"code": "unable_to_get_or_create_user",'
                            '"description": "Unable to get or create user from the JWT, ABORT"}'
                            )
示例#4
0
 def put():
     try:
         # GET existing or CREATE new user based on the JWT info
         user = User.find_by_jwtToken(g.jwt_oidc_token_info)
         if not user:
             return jsonify({'message': 'Could not find existing user to update settings for.'}), 400
         json_input = request.get_json()
         if not json_input or not json_input.get('searchColumns'):
             return jsonify({'message': 'Invalid user settings provided in payload.'}), 400
         search_columns = ''
         for column in json_input.get('searchColumns'):
             if search_columns != '':
                 search_columns += ',' + column
             else:
                 search_columns += column
         user.searchColumns = search_columns
         user.save_to_db()
         return {}, 204
         
     except Exception as err:
         current_app.logger.error(f'unable to update user settings: {err.with_traceback(None)}')
         return jsonify({'message': f'Error updating user settings.'}), 500
示例#5
0
    def put(nr, *args, **kwargs):

        # do the cheap check first before the more expensive ones
        json_input = request.get_json()
        if not json_input:
            return jsonify(message='No input data provided'), 400
        current_app.logger.debug(json_input)

        nr_num = json_input.get('nrNum', None)
        if nr_num and nr_num != nr:
            return jsonify(
                message='Data contains a different NR# than this resource'
            ), 400

        state = json_input.get('state', None)
        if not state:
            return jsonify({"message": "state not set"}), 406

        if state not in State.VALID_STATES:
            return jsonify({"message": "not a valid state"}), 406

        #check user scopes
        if not (jwt.requires_roles(User.EDITOR)
                or jwt.requires_roles(User.APPROVER)):
            raise AuthError(
                {
                    "code": "Unauthorized",
                    "description": "You don't have access to this resource."
                }, 403)

        if (state in (State.APPROVED,
                     State.REJECTED,
                     State.CONDITIONAL))\
                and not jwt.requires_roles(User.APPROVER):
            return jsonify(message='Only Names Examiners can set state: {}'.
                           format(state)), 428

        try:
            nr_d = RequestDAO.find_by_nr(nr)
            if not nr_d:
                return jsonify(message='NR not found'), 404

            user = User.find_by_jwtToken(g.jwt_oidc_token_info)
            if not user:
                user = User.create_from_jwtToken(g.jwt_oidc_token_info)

            #NR is in a final state, but maybe the user wants to pull it back for corrections
            if nr_d.stateCd in State.COMPLETED_STATE:
                if not jwt.requires_roles(User.APPROVER):
                    return jsonify(
                        message=
                        'Only Names Examiners can alter completed Requests'
                    ), 401

                if nr_d.furnished == RequestDAO.REQUEST_FURNISHED:
                    return jsonify(
                        message=
                        'Request has already been furnished and cannot be altered'
                    ), 409

                if state != State.INPROGRESS:
                    return jsonify(
                        message=
                        'Completed unfurnished Requests can only be set to an INPROGRESS state'
                    ), 400

            elif state in State.RELEASE_STATES:
                if nr_d.userId != user.id or nr_d.stateCd != State.INPROGRESS:
                    return jsonify(
                        message=
                        'The Request must be INPROGRESS and assigned to you before you can change it.'
                    ), 401
            elif nr_d.userId != user.id or nr_d.stateCd != State.INPROGRESS:
                return jsonify(
                    message=
                    'The Request must be INPROGRESS and assigned to you before you can change it.'
                ), 401

            # update request header
            request_header_schema.load(json_input, instance=nr_d, partial=True)
            nr_d.stateCd = state
            nr_d.userId = user.id

            # update applicants
            applicants_d = nr_d.applicants.one_or_none()
            if applicants_d:
                appl = json_input.get('applicants', None)
                if appl:
                    errm = applicant_schema.validate(appl, partial=False)
                    if errm:
                        return jsonify(errm)

                    applicant_schema.load(appl,
                                          instance=applicants_d,
                                          partial=False)
                else:
                    applicants_d.delete_from_db()

            ### NAMES ###
            for nrd_name in nr_d.names.all():
                for in_name in json_input['names']:
                    if nrd_name.choice == in_name['choice']:

                        errors = names_schema.validate(in_name, partial=False)
                        if errors:
                            return jsonify(errors), 400

                        names_schema.load(in_name,
                                          instance=nrd_name,
                                          partial=False)
            ### END names ###

            ### COMMENTS ###

            # we only add new comments, we do not change existing comments
            # - we can find new comments in json as those with no ID

            for in_comment in json_input['comments']:
                is_new_comment = False
                try:
                    if in_comment['id'] is None or in_comment['id'] == 0:
                        is_new_comment = True
                except KeyError:
                    is_new_comment = True

                if is_new_comment and in_comment['comment'] is not None:
                    new_comment = Comment()
                    new_comment.comment = in_comment['comment']
                    new_comment.examiner = user
                    new_comment.nrId = nr_d.id

            ### END comments ###

            ### NWPTA ###

            for nrd_nwpta in nr_d.partnerNS.all():
                for in_nwpta in json_input['nwpta']:
                    if nrd_nwpta.partnerJurisdictionTypeCd == in_nwpta[
                            'partnerJurisdictionTypeCd']:

                        errors = nwpta_schema.validate(in_nwpta, partial=False)
                        if errors:
                            return jsonify(errors), 400

                        nwpta_schema.load(in_nwpta,
                                          instance=nrd_nwpta,
                                          partial=False)
            ### END nwpta ###

            ### Finally save the entire graph
            nr_d.save_to_db()

        except ValidationError as ve:
            return jsonify(ve.messages)

        except NoResultFound as nrf:
            # not an error we need to track in the log
            return jsonify(message='Request:{} not found'.format(nr)), 404

        except Exception as err:
            current_app.logger.error(
                "Error when replacing NR:{0} Err:{1}".format(nr, err))
            return jsonify(message='NR had an internal error'), 500

        current_app.logger.debug(nr_d.json())
        return jsonify(nr_d.json()), 200
示例#6
0
    def patch(nr, *args, **kwargs):
        """  Patches the NR, only STATE can be changed with some business rules around roles/scopes

        :param nr (str): NameRequest Number in the format of 'NR 000000000'
        :param args:  __futures__
        :param kwargs: __futures__
        :return: 200 - success; 40X for errors

        :HEADER: Valid JWT Bearer Token for a valid REALM
        :JWT Scopes: - USER.APPROVER, USER.EDITOR, USER.VIEWONLY

        APPROVERS: Can change from almost any state, other than CANCELLED, EXPIRED and ( COMPLETED not yet furnished )
        EDITOR: Can't change to a COMPLETED state (ACCEPTED, REJECTED, CONDITION)
        VIEWONLY: Can't change anything, so that are bounced
        """

        # do the cheap check first before the more expensive ones
        #check states
        json_input = request.get_json()
        if not json_input:
            return jsonify({'message': 'No input data provided'}), 400

        # Currently only state changes are supported by patching
        # all these checks to get removed to marshmallow
        state = json_input.get('state', None)
        if not state:
            return jsonify({"message": "state not set"}), 406

        if state not in State.VALID_STATES:
            return jsonify({"message": "not a valid state"}), 406

        #check user scopes
        if not (jwt.requires_roles(User.EDITOR)
                or jwt.requires_roles(User.APPROVER)):
            raise AuthError(
                {
                    "code": "Unauthorized",
                    "description": "You don't have access to this resource."
                }, 403)

        if (state in (State.APPROVED,
                     State.REJECTED,
                     State.CONDITIONAL))\
                and not jwt.requires_roles(User.APPROVER):
            return jsonify({
                "message":
                "Only Names Examiners can set state: {}".format(state)
            }), 428

        try:
            nrd = RequestDAO.find_by_nr(nr)
            if not nrd:
                return jsonify({"message": "NR not found"}), 404

            user = User.find_by_jwtToken(g.jwt_oidc_token_info)
            if not user:
                user = User.create_from_jwtToken(g.jwt_oidc_token_info)

            #NR is in a final state, but maybe the user wants to pull it back for corrections
            if nrd.stateCd in State.COMPLETED_STATE:
                if not jwt.requires_roles(User.APPROVER):
                    return jsonify({
                        "message":
                        "Only Names Examiners can alter completed Requests"
                    }), 401

                if nrd.furnished == RequestDAO.REQUEST_FURNISHED:
                    return jsonify({
                        "message":
                        "Request has already been furnished and cannot be altered"
                    }), 409

                if state != State.INPROGRESS:
                    return jsonify({
                        "message":
                        "Completed unfurnished Requests can only be set to an INPROGRESS state"
                    }), 400

            elif state in State.RELEASE_STATES:
                if nrd.userId != user.id or nrd.stateCd != State.INPROGRESS:
                    return jsonify({
                        "message":
                        "The Request must be INPROGRESS and assigned to you before you can change it."
                    }), 401

            existing_nr = RequestDAO.get_inprogress(user)
            if existing_nr:
                existing_nr.stateCd = State.HOLD
                existing_nr.save_to_db()

            nrd.stateCd = state
            nrd.userId = user.id
            nrd.save_to_db()

        except NoResultFound as nrf:
            # not an error we need to track in the log
            return jsonify({"message": "Request:{} not found".format(nr)}), 404
        except Exception as err:
            current_app.logger.error(
                "Error when patching NR:{0} Err:{1}".format(nr, err))
            return jsonify({"message": "NR had an internal error"}), 404

        return jsonify({'message': 'Request:{} - patched'.format(nr)}), 200