"""Access Validation. Validates the usage or non-usage of Grass headers. """ from owsresponse import response from owsrequest.constants import errors from owsrequest.error_response import create_error_forbidden_user from owsrequest.error_response import create_error_incomplete_account_headers from owsrequest.error_response import create_error_incomplete_profile_headers from owsrequest.error_response import create_error_missing_account_headers # this block is for backwards compatibility ERROR_CODE_AUTHORIZATION = errors.ERROR_CODE_AUTHORIZATION ERROR_CODE_BAD_GRASS_REQUEST = errors.ERROR_CODE_BAD_GRASS_REQUEST ERROR_CODE_NOT_FOUND = errors.ERROR_CODE_NOT_FOUND ERROR_CODE_BAD_HEADERS = errors.ERROR_CODE_BAD_HEADERS ERROR_MESSAGE_MISSING_GRASS_HEADERS = ( errors.ERROR_MESSAGE_MISSING_GRASS_HEADERS) ERROR_MESSAGE_INCOMPLETE_GRASS_HEADERS = ( errors.ERROR_MESSAGE_INCOMPLETE_GRASS_HEADERS) ERROR_MESSAGE_INVALID_GRASS_ACCOUNT_TYPE = ( errors.ERROR_MESSAGE_INVALID_GRASS_ACCOUNT_TYPE) ERROR_MESSAGE_FORBIDDEN_USER = ( errors.ERROR_MESSAGE_FORBIDDEN_USER) ERROR_MESSAGE_INCOMPLETE_PROFILE_HEADERS = ( errors.ERROR_MESSAGE_INCOMPLETE_PROFILE_HEADERS) def verify_grass_headers( header_account_type, header_account_id, required=False): """Verify header values from grass. Verify that grass headers are present, if required. Verify that grass headers are complete, if given. Args: header_account_type (string): the user account type in the header. header_account_id (string): the user account id in the header. required (bool): True if grass requests are required. Returns: response.Response: indicates whether grass headers are valid. """ # Initializing as False for each request errors.LOG_NON_GRASS_HEADERS_ACCESS = False if not header_account_type and not header_account_id: if required: return create_error_missing_account_headers() else: errors.LOG_NON_GRASS_HEADERS_ACCESS = True return response.Response() elif (not header_account_type) ^ (not header_account_id): return create_error_incomplete_account_headers() return response.Response() def verify_grass_access( header_account_type, header_account_id, required=False, **kwargs): """Verify grass request headers and compare to values from route handler. Verify that grass headers are present, if required. Verify that grass headers are complete, if given. Verify that grass headers do not contradict values from kwargs. Kwarg values are typically from API route patterns. Example: GET /some-resource// Args: header_account_type (string): the user account type in the header. header_account_id (string): the user account id in the header. required (bool): True if grass requests are required. kwargs (dict): additional validation information. Returns: response.Response: describes whether access is valid. """ headers_response = verify_grass_headers( header_account_type, header_account_id, required) if not headers_response: return headers_response if not header_account_type and not header_account_id: return headers_response if str(kwargs.get(header_account_type, '')) != str(header_account_id): return create_error_forbidden_user() return response.Response() def verify_profile_headers_are_complete(profile_type, profile_id): """Verify that both the profile headers are present in a Flask Request. Both the profile headers should be present or none at all. Args: profile_type (string): type of profile eg: Artist, Label etc. profile_id (string): identifier for that profile. Returns: response.Response: indicates whether grass headers are valid. """ if not profile_type and not profile_id: return response.Response() elif profile_type and profile_id: return response.Response() return create_error_incomplete_profile_headers() def verify_profile_headers_match_route( header_profile_type, header_profile_id, profile_type, profile_id): """Verify headers profile values match route values (if headers exist). If no profile headers, always allow. If partial headers always fail. When both header exist, they should match to route values. Args: profile_type (string): type of profile eg: Artist, Label etc. profile_id (string): identifier for that profile. header_profile_type (string): Profile type in headers. header_profile_id (string): identifier for that profile. Returns: response.Response: indicates whether grass headers are valid. """ if not header_profile_type and not header_profile_id: # no headers means microservice to microservice, so always allow. return response.Response() elif (not header_profile_type) ^ (not header_profile_id): # partial headers are always bad, no need to compare to route. return create_error_incomplete_profile_headers() # when both headers exist if str(header_profile_type) == str(profile_type) \ and str(header_profile_id) == str(profile_id): return response.Response() return create_error_forbidden_user()