def validate_request_create_args(request_args, config, reqmgr_db_service, *args, **kwargs): """ *arg and **kwargs are only for the interface validate post request 1. read data from body 2. validate using spec validation 3. convert data from body to arguments (spec instance, argument with default setting) TODO: raise right kind of error with clear message """ if request_args["RequestType"] == "Resubmission": # do not set default values for Resubmission since it will be inherited from parent # both create & assign args are accepted for Resubmission creation workload, request_args = validate_resubmission_create_args(request_args, config, reqmgr_db_service) else: initialize_request_args(request_args, config) # check the permission for creating the request permission = getWritePermission(request_args) authz_match(permission['role'], permission['group']) # load the correct class in order to validate the arguments specClass = loadSpecClassByType(request_args["RequestType"]) # set default values for the request_args setArgumentsWithDefault(request_args, specClass.getWorkloadCreateArgs()) spec = specClass() workload = spec.factoryWorkloadConstruction(request_args["RequestName"], request_args) return workload, request_args
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ('GET', 'HEAD'): validate_rx('match', param, safe, optional = True) elif method in ('PUT', 'POST'): validate_strlist('site_name', param, safe, RX_SITE) validate_strlist('tier', param, safe, RX_TIER) validate_ustrlist('country', param, safe, RX_COUNTRY) validate_strlist('usage', param, safe, RX_USAGE) validate_strlist('url', param, safe, RX_URL) validate_strlist('logo_url', param, safe, RX_URL) validate_strlist('devel_release', param, safe, RX_YES_NO) validate_strlist('manual_install', param, safe, RX_YES_NO) validate_lengths(safe, 'site_name', 'tier', 'country', 'usage', 'url', 'logo_url', 'devel_release', 'manual_install') if method == 'PUT': validate_strlist('executive', param, safe, RX_USER) validate_lengths(safe, 'executive') elif method == 'DELETE': validate_strlist('site_name', param, safe, RX_SITE) # Delay POST authz until we have database connection for name remapping. if method in ('PUT'): authz_match(role=["Global Admin", "Operator"], group=["global","SiteDB"]) elif method in ('DELETE'): authz_match(role=["Global Admin"], group=["global"])
def validate_request_create_args(request_args, config, *args, **kwargs): """ *arg and **kwargs are only for the interface validate post request 1. read data from body 2. validate using spec validation 3. convert data from body to arguments (spec instance, argument with default setting) TODO: rasie right kind of error with clear message """ initialize_request_args(request_args, config) #check the permission for creating the request permission = getWritePermission(request_args) authz_match(permission['role'], permission['group']) # set default values for teh request_args specClass = loadSpecClassByType(request_args["RequestType"]) setArgumentsWithDefault(request_args, specClass.getWorkloadArguments()) # get the spec type and validate arguments spec = loadSpecByType(request_args["RequestType"]) if request_args["RequestType"] == "Resubmission": request_args["OriginalRequestCouchURL"] = '%s/%s' % (config.couch_host, config.couch_reqmgr_db) workload = spec.factoryWorkloadConstruction(request_args["RequestName"], request_args) return workload, request_args
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ('GET', 'HEAD'): validate_rx('match', param, safe, optional = True) elif method in ('PUT', 'POST'): validate_strlist('username', param, safe, RX_USER) validate_strlist('email', param, safe, RX_EMAIL) validate_ustrlist('forename', param, safe, RX_NAME) validate_ustrlist('surname', param, safe, RX_NAME) validate_ustrlist('dn', param, safe, RX_DN) validate_strlist('phone1', param, safe, RX_PHONE) validate_strlist('phone2', param, safe, RX_PHONE) validate_strlist('im_handle', param, safe, RX_IM) validate_lengths(safe, 'username', 'email', 'forename', 'surname', 'dn', 'phone1', 'phone2', 'im_handle') mydn = cherrypy.request.user['dn'] me = cherrypy.request.user['login'] for user, dn in zip(safe.kwargs['username'], safe.kwargs['dn']): (method == 'POST' and user == me and dn == mydn) or \ authz_match(role=["Global Admin"], group=["global"]) elif method == 'DELETE': validate_strlist('username', param, safe, RX_USER) authz_match(role=["Global Admin"], group=["global"])
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ('PUT', 'DELETE'): validate_strlist('phedex_name', param, safe, RX_NAME) validate_strlist('psn_name', param, safe, RX_NAME) validate_lengths(safe, 'phedex_name', 'psn_name') authz_match(role=["Global Admin", "Operator"], group=["global","SiteDB"])
def validate_clone_create_args(request_args, config, reqmgr_db_service, *args, **kwargs): """ Handle clone workflows through the clone API, by loading the spec arguments definition (and chain definition, if needed) and inheriting all arguments defined in the spec. *arg and **kwargs are only for the interface """ response = reqmgr_db_service.getRequestByNames(request_args.pop("OriginalRequestName")) originalArgs = response.values()[0] chainArgs = None specClass = loadSpecClassByType(originalArgs["RequestType"]) if originalArgs["RequestType"] == 'Resubmission': # cloning an ACDC, nothing that we can validate # simply copy the whole original dictionary over and accept all args createArgs = originalArgs else: # load arguments definition from the proper/original spec factory createArgs = specClass.getWorkloadCreateArgs() if originalArgs["RequestType"] in ('StepChain', 'TaskChain'): chainArgs = specClass.getChainCreateArgs() cloned_args = initialize_clone(request_args, originalArgs, createArgs, chainArgs) initialize_request_args(cloned_args, config) permission = getWritePermission(cloned_args) authz_match(permission['role'], permission['group']) spec = specClass() workload = spec.factoryWorkloadConstruction(cloned_args["RequestName"], cloned_args) return workload, cloned_args
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ("GET", "HEAD"): validate_rx("match", param, safe, optional=True) elif method in ("PUT", "DELETE"): validate_strlist("name", param, safe, RX_LABEL) authz_match(role="Global Admin", group="global")
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ('GET', 'HEAD'): validate_rx('match', param, safe, optional = True) elif method in ('PUT', 'DELETE'): validate_strlist('title', param, safe, RX_LABEL) authz_match(role=["Global Admin"], group=["global"])
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method == 'POST': validate_str('action', param, safe, re.compile(r"^(archive|restore)$")) elif method == 'DELETE': validate_str('action', param, safe, re.compile(r"^(all|archive|current)$")) authz_match(role=["Global Admin"], group=["global"])
def validate_request_update_args(request_args, config, reqmgr_db_service, param): """ param and safe structure is RESTArgs structure: named tuple RESTArgs(args=[], kwargs={}) validate post/put request 1. read data from body 2. validate the permission (authentication) 3. validate state transition (against previous state from couchdb) 2. validate using workload validation 3. convert data from body to arguments (spec instance, argument with default setting) TODO: rasie right kind of error with clear message """ # this needs to be deleted for validation request_name = request_args.pop("RequestName") couchurl = '%s/%s' % (config.couch_host, config.couch_reqmgr_db) workload = WMWorkloadHelper() workload.loadSpecFromCouch(couchurl, request_name) # first validate the permission by status and request type. # if the status is not set only ReqMgr Admin can change the values # TODO for each step, assigned, approved, announce find out what other values # can be set request_args["RequestType"] = workload.requestType() permission = getWritePermission(request_args) authz_match(permission['role'], permission['group']) del request_args["RequestType"] #validate the status if "RequestStatus" in request_args: validate_state_transition(reqmgr_db_service, request_name, request_args["RequestStatus"]) # delete request_args since it is not part of spec argument and validation args_without_status = {} args_without_status.update(request_args) del args_without_status["RequestStatus"] else: args_without_status = request_args if len(args_without_status) == 1: if 'RequestPriority' in args_without_status: args_without_status['RequestPriority'] = int(args_without_status['RequestPriority']) if (lambda x: (x >= 0 and x < 1e6))(args_without_status['RequestPriority']) is False: raise InvalidSpecParameterValue("RequestPriority must be an integer between 0 and 1e6") return workload, args_without_status elif 'cascade' in args_without_status: # status was already validated return workload, request_args elif len(args_without_status) > 0 and not workqueue_stat_validation(args_without_status): # validate the arguments against the spec argumentSpecdefinition #TODO: currently only assigned status allows any update other then Status update workload.validateArgumentForAssignment(args_without_status) # to update request_args with type conversion request_args.update(args_without_status) return workload, request_args
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ('GET', 'HEAD'): validate_rx('match', param, safe, optional = True) elif method in ('PUT'): validate_strlist('site', param, safe, RX_LABEL) validate_reallist('value', param, safe, minval = 0.) validate_strlist('year', param, safe, RX_YEARS) authz_match(role=["Global Admin"], group=["global"])
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ('GET', 'HEAD'): validate_rx('match', param, safe, optional = True) elif method in ('PUT', 'DELETE'): validate_strlist('type', param, safe, RX_NAME_TYPE) validate_strlist('site_name', param, safe, RX_SITE) validate_strlist('alias', param, safe, RX_NAME) validate_lengths(safe, 'type', 'site_name', 'alias') authz_match(role=["Global Admin", "Operator"], group=["global","SiteDB"])
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ('GET', 'HEAD'): validate_rx('match', param, safe, optional = True) elif method == 'PUT': validate_numlist('position', param, safe, bare = True) validate_strlist('name', param, safe, RX_TIER) validate_lengths(safe, 'position', 'name') authz_match(role=["Global Admin"], group=["global"]) elif method == 'DELETE': validate_numlist('position', param, safe, bare = True) authz_match(role=["Global Admin"], group=["global"])
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ('GET', 'HEAD'): validate_rx('match', param, safe, optional = True) elif method in ('PUT', 'POST'): validate_strlist('username', param, safe, RX_USER) validate_strlist('passwd', param, safe, RX_PASSWD) validate_lengths(safe, 'username', 'passwd') authz_match(role=["Global Admin"], group=["global"]) elif method == 'DELETE': validate_strlist('username', param, safe, RX_USER) authz_match(role=["Global Admin"], group=["global"])
def validate_request_update_args(request_args, config, reqmgr_db_service, param): """ param and safe structure is RESTArgs structure: named tuple RESTArgs(args=[], kwargs={}) validate post/put request 1. read data from body 2. validate the permission (authentication) 3. validate state transition (against previous state from couchdb) 2. validate using workload validation 3. convert data from body to arguments (spec instance, argument with default setting) TODO: raise right kind of error with clear message """ # this needs to be deleted for validation request_name = request_args.pop("RequestName") couchurl = '%s/%s' % (config.couch_host, config.couch_reqmgr_db) workload = WMWorkloadHelper() workload.loadSpecFromCouch(couchurl, request_name) # first validate the permission by status and request type. # if the status is not set only ReqMgr Admin can change the values # TODO for each step, assigned, approved, announce find out what other values # can be set request_args["RequestType"] = workload.requestType() permission = getWritePermission(request_args) authz_match(permission['role'], permission['group']) del request_args["RequestType"] # validate the status if "RequestStatus" in request_args: validate_state_transition(reqmgr_db_service, request_name, request_args["RequestStatus"]) if request_args["RequestStatus"] in STATES_ALLOW_ONLY_STATE_TRANSITION: # if state change doesn't allow other transition nothing else to validate args_only_status = {} args_only_status["RequestStatus"] = request_args["RequestStatus"] args_only_status["cascade"] = request_args.get("cascade", False) return workload, args_only_status elif request_args["RequestStatus"] == 'assigned': workload.validateArgumentForAssignment(request_args) # TODO: fetch it from the assignment arg definition if 'RequestPriority' in request_args: request_args['RequestPriority'] = int(request_args['RequestPriority']) if (lambda x: (x >= 0 and x < 1e6))(request_args['RequestPriority']) is False: raise InvalidSpecParameterValue("RequestPriority must be an integer between 0 and 1e6") return workload, request_args
def oldsite_authz_match(api, sites, role=[], group=[], site=[], verbose=False): """Like authz_match, but translates site names from old to new via `api`. The caller must provide `sites`, an initially empty dictionary, used to cache site name translation lookups.""" # Initialise cache if not yet done. if not sites: c, _ = api.execute( """select s.name site_name, c.name alias from site s join site_cms_name_map cmap on cmap.site_id = s.id join cms_name c on c.id = cmap.cms_name_id""" ) for old, canonical in c: if old not in sites: sites[old] = [] sites[old].append(canonical) # Remap sites. Ignore sites which don't exist, rather than raising an error. # This is needed so that a global admin can perform the operations on site # objects even if cms name mapping is missing. This does not affect authz # decisions if someone other than global admin attempts an operation - one # cannot have privileges for a site that has no CMS name. remapped = sum((sites[s] for s in site if s in sites), []) # Now perform normal authz_match. return authz_match(role, group, remapped, verbose)
def validate_resubmission_create_args(request_args, config, reqmgr_db_service, *args, **kwargs): """ Handle resubmission workflows, loading the spec arguments definition (and chain definition, if needed) and inheriting all arguments defined in the spec. User can also override arguments, since it uses the same mechanism as a clone. *arg and **kwargs are only for the interface """ response = reqmgr_db_service.getRequestByNames( request_args["OriginalRequestName"]) originalArgs = next(iter(viewvalues(response))) ### not a nice fix for #8245, but we cannot inherit the CollectionName attr originalArgs.pop("CollectionName", None) chainArgs = None if originalArgs["RequestType"] == 'Resubmission': # ACDC of ACDC, we can't validate this case # simply copy the whole original dictionary over and accept all args createArgs = originalArgs request_args["OriginalRequestType"] = originalArgs[ "OriginalRequestType"] request_args["ResubmissionCount"] = originalArgs.get( "ResubmissionCount", 1) + 1 else: # load arguments definition from the proper/original spec factory parentClass = loadSpecClassByType(originalArgs["RequestType"]) createArgs = parentClass.getWorkloadAssignArgs() if originalArgs["RequestType"] in ('StepChain', 'TaskChain'): chainArgs = parentClass.getChainCreateArgs() createArgs.update(parentClass.getWorkloadCreateArgs()) request_args["OriginalRequestType"] = originalArgs["RequestType"] cloned_args = initialize_clone(request_args, originalArgs, createArgs, chainArgs) initialize_request_args(cloned_args, config) permission = getWritePermission(cloned_args) authz_match(permission['role'], permission['group']) specClass = loadSpecClassByType(request_args["RequestType"]) spec = specClass() workload = spec.factoryWorkloadConstruction(cloned_args["RequestName"], cloned_args) return workload, cloned_args
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" authz_match(role=["Global Admin"], group=["global"]) if method == "GET": if not self._syncer: raise cherrypy.HTTPError(503, "Not running.") elif method in ("PUT", "POST"): validate_strlist('username', param, safe, RX_USER) validate_strlist('passwd', param, safe, RX_PASSWD) validate_strlist('email', param, safe, RX_EMAIL) validate_ustrlist('name', param, safe, RX_HN_NAME) validate_lengths(safe, 'username', 'passwd', 'email', 'name') authz = cherrypy.request.user if authz['method'] != 'Internal' or authz['login'] != self._syncer.sectoken: raise cherrypy.HTTPError(403, "You are not allowed to access this resource.")
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" authz_match(role=["Global Admin"], group=["global"]) if method == "GET": if not self._syncer: raise cherrypy.HTTPError(503, "Not running.") elif method == "PUT": validate_strlist ('username', param, safe, RX_USER) validate_strlist ('passwd', param, safe, RX_PASSWD) validate_strlist ('email', param, safe, RX_EMAIL) validate_ustrlist('name', param, safe, RX_NAME) validate_ustrlist('dn', param, safe, RX_DN) validate_lengths(safe, 'username', 'passwd', 'email', 'name', 'dn') authz = cherrypy.request.user if authz['method'] != 'Internal' or authz['login'] != self._syncer.sectoken: raise cherrypy.HTTPError(403, "You are not allowed to access this resource.")
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" authz_match(role=["Global Admin"], group=["global"]) if method == "GET": if not self._syncer: raise cherrypy.HTTPError(503, "Not running.") elif method == "PUT": validate_strlist("username", param, safe, RX_USER) validate_strlist("passwd", param, safe, RX_PASSWD) validate_strlist("email", param, safe, RX_EMAIL) validate_ustrlist("name", param, safe, RX_NAME) validate_ustrlist("dn", param, safe, RX_DN) validate_lengths(safe, "username", "passwd", "email", "name", "dn") authz = cherrypy.request.user if authz["method"] != "Internal" or authz["login"] != self._syncer.sectoken: raise cherrypy.HTTPError(403, "You are not allowed to access this resource.")
def validate(self, apiobj, method, api, param, safe): if method == "GET": if not len(param.args) or param.args[0] not in ("ip", "name", "stats"): raise InvalidParameter("Missing or wrong ip/host category") safe.kwargs["kind"] = kind = param.args.pop(0) if kind == "ip": validate_iplist("host", param, safe) elif kind == "name": validate_strlist("host", param, safe, RXHOST) elif kind == "stats": authz_match(role=["Global Admin"], group=["global"]) safe.kwargs["host"] = [] elif method == "POST": authz_match(role=["Global Admin"], group=["global"]) if not len(param.args) or param.args[0] not in ("stats", "purge"): raise InvalidParameter("Invalid operation") safe.kwargs["operation"] = param.args.pop(0)
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" authz_match(role=["Global Admin"], group=["global"]) if method == "GET": if not self._syncer: raise cherrypy.HTTPError(503, "Not running.") elif method == "PUT": validate_strlist('name', param, safe, RX_FEDERATION) validate_strlist('country', param, safe, RX_FEDERATION) validate_strlist('year', param, safe, RX_YEARS) validate_strlist('cpu', param, safe, RX_NUMBER) validate_strlist('disk', param, safe, RX_NUMBER) validate_strlist('tape', param, safe, RX_NUMBER) validate_lengths(safe, 'name', 'country', 'year', 'cpu', 'disk', 'tape') authz = cherrypy.request.user if authz['method'] != 'Internal' or authz['login'] != self._syncer.sectoken: raise cherrypy.HTTPError(403, "You are not allowed to access this resource.")
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" authz_match(role=["Global Admin"], group=["global"]) if method == "GET": if not self._syncer: raise cherrypy.HTTPError(503, "Not running.") elif method == "PUT": validate_strlist('name', param, safe, RX_FEDERATION) validate_strlist('country', param, safe, RX_FEDERATION) validate_strlist('year', param, safe, RX_YEARS) validate_strlist('cpu', param, safe, RX_NUMBER) validate_strlist('disk', param, safe, RX_NUMBER) validate_strlist('tape', param, safe, RX_NUMBER) validate_lengths(safe, 'name', 'country', 'year', 'cpu', 'disk', 'tape') authz = cherrypy.request.user if authz['method'] != 'Internal' or authz[ 'login'] != self._syncer.sectoken: raise cherrypy.HTTPError( 403, "You are not allowed to access this resource.")
def validate_clone_create_args(request_args, config, reqmgr_db_service, *args, **kwargs): """ Handle clone workflows through the clone API, by loading the spec arguments definition (and chain definition, if needed) and inheriting all arguments defined in the spec. *arg and **kwargs are only for the interface """ response = reqmgr_db_service.getRequestByNames( request_args.pop("OriginalRequestName")) originalArgs = response.values()[0] chainArgs = None specClass = loadSpecClassByType(originalArgs["RequestType"]) if originalArgs["RequestType"] == 'Resubmission': # cloning an ACDC, nothing that we can validate # simply copy the whole original dictionary over and accept all args createArgs = originalArgs else: # load arguments definition from the proper/original spec factory createArgs = specClass.getWorkloadCreateArgs() if originalArgs["RequestType"] in ('StepChain', 'TaskChain'): chainArgs = specClass.getChainCreateArgs() cloned_args = initialize_clone(request_args, originalArgs, createArgs, chainArgs) initialize_request_args(cloned_args, config) ### TODO: backwards compatibility. Remove these 2 lines in ~HG1805 cloned_args.pop('MaxRSS', None) cloned_args.pop('MaxVSize', None) permission = getWritePermission(cloned_args) authz_match(permission['role'], permission['group']) spec = specClass() workload = spec.factoryWorkloadConstruction(cloned_args["RequestName"], cloned_args) return workload, cloned_args
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ('GET', 'HEAD'): validate_rx('match', param, safe, optional=True) elif method in ('PUT', 'POST'): validate_strlist('username', param, safe, RX_USER) validate_strlist('email', param, safe, RX_EMAIL) validate_ustrlist('forename', param, safe, RX_NAME) validate_ustrlist('surname', param, safe, RX_NAME) validate_ustrlist('dn', param, safe, RX_DN) validate_strlist('phone1', param, safe, RX_PHONE) validate_strlist('phone2', param, safe, RX_PHONE) validate_strlist('im_handle', param, safe, RX_IM) validate_lengths(safe, 'username', 'email', 'forename', 'surname', 'dn', 'phone1', 'phone2', 'im_handle') mydn = cherrypy.request.user['dn'] me = cherrypy.request.user['login'] for user, dn in zip(safe.kwargs['username'], safe.kwargs['dn']): if (method != 'POST' or user != me or dn != mydn): try: authz_match(role=["Global Admin"], group=["global"]) except HTTPError: authz_match(role=["Operator"], group=["SiteDB"]) elif method == 'DELETE': validate_strlist('username', param, safe, RX_USER) authz_match(role=["Global Admin"], group=["global"])
def validate_resubmission_create_args(request_args, config, reqmgr_db_service, *args, **kwargs): """ Handle resubmission workflows, loading the spec arguments definition (and chain definition, if needed) and inheriting all arguments defined in the spec. User can also override arguments, since it uses the same mechanism as a clone. *arg and **kwargs are only for the interface """ response = reqmgr_db_service.getRequestByNames(request_args["OriginalRequestName"]) originalArgs = response.values()[0] ### not a nice fix for #8245, but we cannot inherit the CollectionName attr originalArgs.pop("CollectionName", None) chainArgs = None if originalArgs["RequestType"] == 'Resubmission': # ACDC of ACDC, we can't validate this case # simply copy the whole original dictionary over and accept all args createArgs = originalArgs request_args["OriginalRequestType"] = originalArgs["OriginalRequestType"] request_args["ResubmissionCount"] = originalArgs.get("ResubmissionCount", 1) + 1 else: # load arguments definition from the proper/original spec factory parentClass = loadSpecClassByType(originalArgs["RequestType"]) createArgs = parentClass.getWorkloadAssignArgs() if originalArgs["RequestType"] in ('StepChain', 'TaskChain'): chainArgs = parentClass.getChainCreateArgs() createArgs.update(parentClass.getWorkloadCreateArgs()) request_args["OriginalRequestType"] = originalArgs["RequestType"] cloned_args = initialize_clone(request_args, originalArgs, createArgs, chainArgs) initialize_request_args(cloned_args, config) permission = getWritePermission(cloned_args) authz_match(permission['role'], permission['group']) specClass = loadSpecClassByType(request_args["RequestType"]) spec = specClass() workload = spec.factoryWorkloadConstruction(cloned_args["RequestName"], cloned_args) return workload, cloned_args
def validate_request_create_args(request_args, config, *args, **kwargs): """ *arg and **kwargs are only for the interface validate post request 1. read data from body 2. validate using spec validation 3. convert data from body to arguments (spec instance, argument with default setting) TODO: rasie right kind of error with clear message """ initialize_request_args(request_args, config) #check the permission for creating the request permission = getWritePermission(request_args) authz_match(permission['role'], permission['group']) # get the spec type and validate arguments spec = loadSpecByType(request_args["RequestType"]) if request_args["RequestType"] == "Resubmission": request_args["OriginalRequestCouchURL"] = '%s/%s' % ( config.couch_host, config.couch_reqmgr_db) workload = spec.factoryWorkloadConstruction(request_args["RequestName"], request_args) return workload, request_args
def validate(self, apiobj, method, api, param, safe): """Validate request input data.""" if method in ('GET', 'HEAD'): validate_rx('match', param, safe, optional=True) elif method in ('PUT', 'POST'): validate_strlist('site_name', param, safe, RX_SITE) validate_strlist('tier', param, safe, RX_TIER) validate_ustrlist('country', param, safe, RX_COUNTRY) validate_strlist('usage', param, safe, RX_USAGE) validate_strlist('url', param, safe, RX_URL) validate_strlist('logo_url', param, safe, RX_URL) validate_strlist('devel_release', param, safe, RX_YES_NO) validate_strlist('manual_install', param, safe, RX_YES_NO) validate_lengths(safe, 'site_name', 'tier', 'country', 'usage', 'url', 'logo_url', 'devel_release', 'manual_install') elif method == 'DELETE': validate_strlist('site_name', param, safe, RX_SITE) # Delay POST authz until we have database connection for name remapping. if method in ('PUT', 'DELETE'): authz_match(role=["Global Admin"], group=["global"])
def oldsite_authz_match(api, sites, role=[], group=[], site=[], verbose=False): """Like authz_match, but translates site names from old to new via `api`. The caller must provide `sites`, an initially empty dictionary, used to cache site name translation lookups.""" # Initialise cache if not yet done. if not sites: c, _ = api.execute("""select s.name site_name, c.name alias from site s join site_cms_name_map cmap on cmap.site_id = s.id join cms_name c on c.id = cmap.cms_name_id""") for old, canonical in c: if old not in sites: sites[old] = [] sites[old].append(canonical) # Remap sites. Ignore sites which don't exist, rather than raising an error. # This is needed so that a global admin can perform the operations on site # objects even if cms name mapping is missing. This does not affect authz # decisions if someone other than global admin attempts an operation - one # cannot have privileges for a site that has no CMS name. remapped = sum((sites[s] for s in site if s in sites), []) # Now perform normal authz_match. return authz_match(role, group, remapped, verbose)
def validate_request_update_args(request_args, config, reqmgr_db_service, param): """ param and safe structure is RESTArgs structure: named tuple RESTArgs(args=[], kwargs={}) validate post/put request 1. read data from body 2. validate the permission (authentication) 3. validate state transition (against previous state from couchdb) 2. validate using workload validation 3. convert data from body to arguments (spec instance, argument with default setting) TODO: raise right kind of error with clear message """ # this needs to be deleted for validation request_name = request_args.pop("RequestName") couchurl = '%s/%s' % (config.couch_host, config.couch_reqmgr_db) workload = WMWorkloadHelper() workload.loadSpecFromCouch(couchurl, request_name) # first validate the permission by status and request type. # if the status is not set only ReqMgr Admin can change the values # TODO for each step, assigned, approved, announce find out what other values # can be set request_args["RequestType"] = workload.requestType() permission = getWritePermission(request_args) authz_match(permission['role'], permission['group']) del request_args["RequestType"] # validate the status if "RequestStatus" in request_args: validate_state_transition(reqmgr_db_service, request_name, request_args["RequestStatus"]) # delete request_args since it is not part of spec argument and validation if request_args["RequestStatus"] not in STATES_ALLOW_ONLY_STATE_TRANSITION: args_without_status = {} args_without_status.update(request_args) del args_without_status["RequestStatus"] else: #if state change doesn't allow other transition nothing else to validate args_only_status = {} args_only_status["RequestStatus"] = request_args["RequestStatus"] return workload, args_only_status else: args_without_status = request_args if len(args_without_status) == 1: if 'RequestPriority' in args_without_status: args_without_status['RequestPriority'] = int(args_without_status['RequestPriority']) if (lambda x: (x >= 0 and x < 1e6))(args_without_status['RequestPriority']) is False: raise InvalidSpecParameterValue("RequestPriority must be an integer between 0 and 1e6") if "RequestStatus" in request_args: return workload, request_args else: return workload, args_without_status elif 'cascade' in args_without_status: # status was already validated return workload, request_args elif len(args_without_status) > 0 and not workqueue_stat_validation(args_without_status): # validate the arguments against the spec argumentSpecdefinition # TODO: currently only assigned status allows any update other then Status update workload.validateArgumentForAssignment(args_without_status) # to update request_args with type conversion request_args.update(args_without_status) return workload, request_args