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
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 }
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
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)] }
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
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}}
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
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] }
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