Exemple #1
0
def validate_role(role, request_domain_id, request_user):
    """
    This method will validate given role and permissions of the requesting user.
    :param int|basestring role: Role Name or ID
    :param request_domain_id: Id of the domain in which new user is going to be created
    :param request_user: User object of Logged-in user
    :return: Role Id
    :rtype: int
    """

    if is_number(role):
        role_object = Role.query.get(int(role))
        if role_object:
            role_id = role
            role_name = role_object.name
        else:
            raise NotFoundError("Role with id:%s doesn't exist in database" %
                                role)
    else:
        role_object = Role.get_by_name(role)
        if role_object:
            role_id = role_object.id
            role_name = role_object.name
        else:
            raise NotFoundError("Role with name:%s doesn't exist in database" %
                                role)

    if request_user.role.name != 'TALENT_ADMIN' and (
            request_domain_id != request_user.domain_id
            or role_name == 'TALENT_ADMIN'):
        raise UnauthorizedError(
            "User %s doesn't have appropriate permissions to assign "
            "given role: (%s)" % role_name)

    return role_id
Exemple #2
0
def retrieve_domain_aoi(domain_id, aoi_id):
    """
    Function will retrieve aoi from db
    Caveats:
        1. AOI ID must be recognized
        2. AOI must belong to the specified domain
    :type domain_id:  int | long
    :type aoi_id:     int | long
    """
    # Area of interest id must be recognized
    aoi_object = AreaOfInterest.get(aoi_id)
    if not aoi_object:
        logger.error('Area of interest ID not recognized. ID = %s', aoi_id)
        raise NotFoundError("Area of interest ID not recognized. ID = %s" %
                            aoi_id)

    # Area of interest must belong to user's domain
    if aoi_object.domain_id != domain_id:
        logger.error(
            'Unauthorized access. aoi_domain_id = %s,\tuser_domain_id = %s',
            aoi_object.domain_id, domain_id)
        raise ForbiddenError("Not authorized")

    return {
        "id": aoi_object.id,
        "domain_id": aoi_object.domain_id,
        "description": aoi_object.name
    }
Exemple #3
0
def create_custom_fields(custom_fields, domain_id):
    """
    Function will insert domain custom fields after passing validation
    :type custom_fields:  dict
    :type domain_id:  int | long
    :rtype: list[dict]
    """
    created_custom_fields = []
    for custom_field in custom_fields:

        cf_name = custom_field['name'].strip()
        if not cf_name:  # In case name is just a whitespace
            raise InvalidUsage(
                "Custom field name is required for creating custom field(s).")

        cf_category_id = custom_field.get('category_id')

        # If custom field category ID is provided, we must link custom field with its category
        # Custom field category ID must be recognized
        if cf_category_id:
            cf_category_obj = CustomFieldCategory.get(cf_category_id)
            if not cf_category_obj:
                raise NotFoundError(
                    "Custom field category ID ({}) not recognized.".format(
                        cf_category_id))
            else:
                custom_field_obj = CustomField.query.filter_by(
                    domain_id=domain_id,
                    category_id=cf_category_id,
                    name=cf_name).first()  # type: CustomField

                # Prevent duplicates
                if custom_field_obj:
                    raise InvalidUsage(
                        error_message='Domain Custom Field already exists',
                        additional_error_info={
                            'id': custom_field_obj.id,
                            'domain_id': domain_id,
                            'category_id': custom_field_obj.category_id
                        })
                else:
                    created_custom_fields.append(
                        dict(id=add_custom_field(domain_id, cf_category_id,
                                                 cf_name)))

        # Prevent duplicate entries for the same domain
        custom_field_obj = CustomField.query.filter_by(domain_id=domain_id,
                                                       name=cf_name).first()
        if custom_field_obj:
            raise InvalidUsage(
                error_message='Domain Custom Field already exists',
                additional_error_info={'id': custom_field_obj.id})

        # This is for legacy purpose, ideally we should not be saving custom-fields w/o its category ID
        created_custom_fields.append(
            dict(id=add_custom_field(domain_id, cf_category_id, cf_name)))

    db.session.commit()
    return created_custom_fields
Exemple #4
0
def retrieve_domain_custom_fields(domain_id, custom_field_id=None):
    """
    Function will return domain's custom field category if custom field category ID is provided,
    otherwise it will return all of domain's custom field categories
    :type domain_id:  int
    :type custom_field_id:  int | None
    :rtype:  dict[dict] | dict[list]
    """
    if custom_field_id:

        custom_field = CustomField.get(custom_field_id)  # type: CustomField

        # Custom field category ID must be recognized
        if not custom_field:
            raise NotFoundError(
                error_message="Custom field ID is not recognized"
            )  # TODO: custom error codes

        # Custom field category must belong to user's domain
        if custom_field.domain_id != domain_id:
            raise ForbiddenError(
                "Unauthorized custom field")  # TODO: custom error codes

        return {
            'custom_field': {
                'id':
                custom_field.id,
                'domain_id':
                custom_field.domain_id,
                'name':
                custom_field.name,
                'type':
                custom_field.type,
                'categories': [{
                    'id': category.id,
                    'name': category.name,
                    'subcategories': _get_cf_subcategories(category)
                } for category in custom_field.categories]
            }
        }
    else:  # return all of user's domain custom field categories
        # custom_fields = CustomField.get_domain_custom_fields(domain_id)  # type: [CustomField]
        return {
            'custom_fields': [{
                'id':
                custom_field.id,
                'name':
                custom_field.name,
                'type':
                custom_field.type,
                'categories': [{
                    'id': category.id,
                    'name': category.name,
                    'subcategories': _get_cf_subcategories(category)
                } for category in custom_field.categories]
            } for custom_field in CustomField.get_domain_custom_fields(
                domain_id)]
        }
Exemple #5
0
def get_custom_field_if_validated(custom_field_id, user):
    """
    Function will return CustomField object if it's found and it belongs to user's domain
    :type custom_field_id:  int | long
    :type user: User
    :rtype: CustomField
    """
    # Custom field ID must be recognized
    custom_field = CustomField.get(custom_field_id)
    if not custom_field:
        raise NotFoundError(
            "Custom field ID ({}) not recognized.".format(custom_field_id))

    # Custom field must belong to user's domain
    if request.user.role.name != 'TALENT_ADMIN' and custom_field.domain_id != user.domain_id:
        raise ForbiddenError("Not authorized")

    return custom_field
Exemple #6
0
    def delete(self, **kwargs):
        """
        Function will delete domain's custom field(s)
        resource url:
            i. DELETE /v1/custom_fields/:id
        :return: {"custom_field": {"id": int}}
        :rtype: dict[dict]
        Usage:
            >>> headers = {"Authorization": "Bearer {access_token}"}
            >>> requests.delete(url="host/v1/custom_fields/4", headers=headers)
            <Response [200]>
        """
        custom_field_id = kwargs.get('id')

        # Delete specified custom field
        if custom_field_id:

            # Custom field ID must be recognized
            custom_field = CustomField.get(custom_field_id)
            if not custom_field:
                raise NotFoundError(
                    "Custom field ID ({}) not recognized.".format(
                        custom_field_id))

            # Custom field must belong to user's domain
            if request.user.role.name != 'TALENT_ADMIN' and custom_field.domain_id != request.user.domain_id:
                raise ForbiddenError("Not authorized")

            custom_field_candidate_ids = CandidateCustomField.query.with_entities(
                CandidateCustomField.candidate_id).filter_by(
                    custom_field_id=custom_field_id).all()

            custom_field_candidate_ids = map(
                lambda custom_field_object: custom_field_object[0],
                custom_field_candidate_ids)

            update_candidates_on_cloudsearch(request.oauth_token,
                                             custom_field_candidate_ids)

            db.session.delete(custom_field)
            db.session.commit()

            return {'custom_field': {'id': custom_field_id}}
Exemple #7
0
def delete_domain_aoi(domain_id, aoi_id):
    """
    :type domain_id:  int | long
    :type aoi:        int | long
    :rtype:           int | long
    """
    aoi_object = AreaOfInterest.get(aoi_id)

    # Area of interest ID must be recognized
    if not aoi_object:
        logger.error('Area of interest ID not recognized. ID = %s', aoi_id)
        raise NotFoundError("Area of interest ID not recognized. ID = %s" %
                            aoi_id)

    # Area of interest must belong to user's domain
    if aoi_object.domain_id != domain_id:
        logger.error(
            'Unauthorized access. aoi_domain_id = %s,\tuser_domain_id = %s',
            aoi_object.domain_id, domain_id)
        raise ForbiddenError("Not authorized")

    db.session.delete(aoi_object)
    db.session.commit()
    return
Exemple #8
0
    def put(self, **kwargs):
        """
        Function will update domain's custom field(s)
        resource url:
             i. PUT /v1/custom_fields
            ii. PUT /v1/custom_fields/:id
        :return: {"custom_fields": [{"id": int}, {"id": int}, ...]}
        :rtype: dict[list[dict]]
        Usage:
            >>> headers = {"Authorization": "Bearer {access_token}"}
            >>> data = {"custom_fields": [{"id": 4, "name": "job status"}]}
            >>> requests.put(url="host/v1/custom_fields", headers=headers, data=json.dumps(data))
            <Response [200]>
        """
        custom_field_id = kwargs.get('id')

        # Validate and obtain json data from request body
        schema = custom_field_schema if custom_field_id else custom_fields_schema
        body_dict = get_json_data_if_validated(request, schema, False)

        # Update specified custom field
        if custom_field_id:

            # Custom field ID must be recognized & belong to user's domain
            get_custom_field_if_validated(custom_field_id, request.user)

            # Remove whitespace(s) from custom field name
            custom_field_name = body_dict['custom_field']['name'].strip()
            if not custom_field_name:  # In case name is just a whitespace
                raise InvalidUsage(
                    "Name is required for creating custom field.")

            custom_field_query = CustomField.query.filter_by(
                id=custom_field_id)
            custom_field_query.update(dict(name=custom_field_name))
            db.session.commit()

            return {'custom_field': {'id': custom_field_id}}

        updated_custom_field_ids = []
        for custom_field in body_dict['custom_fields']:

            # Custom field ID must be provided
            custom_field_id = custom_field.get('id')
            if not custom_field_id:
                raise InvalidUsage("Custom field ID is required for updating.")

            # Remove whitespace(s) from custom field name
            custom_field_name = custom_field['name'].strip()
            if not custom_field_name:  # In case name is just a whitespace
                raise InvalidUsage(
                    "Name is required for creating custom field.")

            custom_field_query = CustomField.query.filter_by(
                id=custom_field_id)

            # Custom field ID must be recognized
            cf_object = custom_field_query.first()
            if not cf_object:
                raise NotFoundError(
                    'Custom field ID ({}) not recognized.'.format(
                        custom_field_id))

            # Custom field must belong to user's domain
            if cf_object.domain_id != request.user.domain_id:
                raise ForbiddenError('Not authorized')

            custom_field_query.update(dict(name=custom_field_name))
            updated_custom_field_ids.append(custom_field_id)

        db.session.commit()
        return {
            'custom_fields': [{
                'id': custom_field_id
            } for custom_field_id in updated_custom_field_ids]
        }
Exemple #9
0
def create_or_update_domain_aois(domain_id,
                                 aois,
                                 aoi_id_from_url=None,
                                 is_creating=False,
                                 is_updating=False):
    """
    Function will create or update domain AOI(s).
    Function must not be used to create AND update in the same call.

    AOI description is a required field

    Create Caveats:
        - AOI must not exists in db for a successful creation
    Update Caveats:
        - AOI ID must be provided for updating
        - If aoi_id_from_url is provided, only one record may be updated
        _ AOI must belong to user's domain

    :type domain_id:  User
    :param domain_id: logged in user's domain ID
    :type aois:  list[dict]
    :param aois: a list of dicts containing area of interest's information
    :type aoi_id_from_url: basestring
    :param aoi_id_from_url: area of interest's ID provided in resource's url
    :type is_creating: bool
    :type is_updating: bool
    :rtype:  list[int]
    """
    created_or_updated_aoi_ids = [
    ]  # Aggregate created or updated aoi ids here

    for aoi in aois:
        aoi_id = aoi.get('id')

        # normalize AOI's description
        aoi_description = aoi['description'].lower().strip()
        if not aoi_description:  # In case description is just a whitespace
            logger.error(
                "Description not provided for area of interest. Description = %s",
                aoi_description)
            raise InvalidUsage(
                "Description is required for creating/updating area of interest."
            )

        if is_creating:  # create
            # Prevent duplicate entries for the same domain
            aoi_object = AreaOfInterest.query.filter_by(
                domain_id=domain_id, name=aoi_description).first()
            if aoi_object:
                raise InvalidUsage(
                    "Creation failed: Area of interest already exists",
                    additional_error_info=dict(id=aoi_object.id))
            else:
                aoi_object = AreaOfInterest(domain_id=domain_id,
                                            name=aoi_description)
                db.session.add(aoi_object)
                db.session.flush()
                created_or_updated_aoi_ids.append(aoi_object.id)

        elif is_updating:  # update
            aoi_id = aoi_id or aoi_id_from_url
            if not aoi_id:
                raise InvalidUsage(
                    "Area of interest ID is required for updating")

            # Area of interest must be recognized
            aoi_object = AreaOfInterest.get(aoi_id)
            if not aoi_object:
                logger.error('Area of interest ID not recognized. ID = %s',
                             aoi_id)
                raise NotFoundError(
                    "Area of interest ID not recognized. ID = %s" % aoi_id)

            # Area of interest must belong to user's domain
            if aoi_object.domain_id != domain_id:
                raise ForbiddenError("Not authorized")

            aoi_object.update(name=aoi_description)
            created_or_updated_aoi_ids.append(aoi_id)

    db.session.commit()
    return created_or_updated_aoi_ids