diff --git a/Dockerfile b/Dockerfile index 4a12a2a86..27bae7029 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ ENV MAGPIE_ENV_DIR=$MAGPIE_DIR/env WORKDIR $MAGPIE_DIR # magpie cron service -ADD magpie-cron /etc/cron.d/magpie-cron +COPY magpie-cron /etc/cron.d/magpie-cron RUN chmod 0644 /etc/cron.d/magpie-cron RUN touch ~/magpie_cron_status.log # set /etc/environment so that cron runs using the environment variables set by docker diff --git a/magpie/__init__.py b/magpie/__init__.py index e28641866..d2982397f 100644 --- a/magpie/__init__.py +++ b/magpie/__init__.py @@ -4,10 +4,10 @@ def includeme(config): # import needs to be here, otherwise ImportError happens during setup.py install (modules not yet installed) - from magpie.definitions.pyramid_definitions import NewRequest, EXCVIEW from magpie.api.api_generic import internal_server_error, unauthorized_or_forbidden, not_found_or_method_not_allowed from magpie.constants import get_constant - from magpie.common import get_logger + from magpie.definitions.pyramid_definitions import NewRequest, EXCVIEW + from magpie.utils import get_logger mod_dir = get_constant('MAGPIE_MODULE_DIR') logger = get_logger(__name__) diff --git a/magpie/adapter/__init__.py b/magpie/adapter/__init__.py index 88b95b499..b1aecdf93 100644 --- a/magpie/adapter/__init__.py +++ b/magpie/adapter/__init__.py @@ -4,7 +4,7 @@ from magpie.models import get_user from magpie.security import auth_config_from_settings from magpie.db import get_session_factory, get_tm_session, get_engine -from magpie.common import get_logger +from magpie.utils import get_logger from magpie import __meta__ LOGGER = get_logger("TWITCHER") diff --git a/magpie/adapter/magpieowssecurity.py b/magpie/adapter/magpieowssecurity.py index c515aed31..fe253a37c 100644 --- a/magpie/adapter/magpieowssecurity.py +++ b/magpie/adapter/magpieowssecurity.py @@ -1,6 +1,5 @@ from magpie.api.api_except import evaluate_call, verify_param from magpie.constants import get_constant -from magpie.common import get_logger, JSON_TYPE from magpie.definitions.pyramid_definitions import ( HTTPOk, HTTPNotFound, @@ -19,7 +18,7 @@ ) from magpie.models import Service from magpie.services import service_factory -from magpie.utils import get_magpie_url +from magpie.utils import get_magpie_url, get_logger, CONTENT_TYPE_JSON from requests.cookies import RequestsCookieJar from six.moves.urllib.parse import urlparse import requests @@ -70,7 +69,7 @@ def update_request_cookies(self, request): magpie_prov = request.params.get('provider', 'WSO2') magpie_auth = '{host}/providers/{provider}/signin'.format(host=self.magpie_url, provider=magpie_prov) headers = dict(request.headers) - headers.update({'Homepage-Route': '/session', 'Accept': JSON_TYPE}) + headers.update({'Homepage-Route': '/session', 'Accept': CONTENT_TYPE_JSON}) session_resp = requests.get(magpie_auth, headers=headers, verify=self.twitcher_ssl_verify) if session_resp.status_code != HTTPOk.code: raise OWSAccessForbidden("Not authorized to access this resource. " + diff --git a/magpie/adapter/magpieprocess.py b/magpie/adapter/magpieprocess.py index 311f81ae2..55fffb3ea 100644 --- a/magpie/adapter/magpieprocess.py +++ b/magpie/adapter/magpieprocess.py @@ -1,10 +1,8 @@ """ Store adapters to read data from magpie. """ -from magpie.utils import get_magpie_url, get_admin_cookies from magpie.api.api_except import raise_http from magpie.constants import get_constant -from magpie.common import get_logger, JSON_TYPE from magpie.definitions.pyramid_definitions import ( HTTPOk, HTTPCreated, @@ -13,6 +11,7 @@ HTTPNotImplemented, asbool, ) +from magpie.utils import get_magpie_url, get_admin_cookies, get_logger, CONTENT_TYPE_JSON # import 'process' elements separately than 'twitcher_definitions' because not defined in master # noinspection PyUnresolvedReferences @@ -59,7 +58,7 @@ def __init__(self, registry): self.default_process_store = DefaultAdapter().processstore_factory(registry) self.twitcher_config = get_twitcher_configuration(registry.settings) self.twitcher_url = get_twitcher_url(registry.settings) - self.json_headers = {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE} + self.json_headers = {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON} # setup basic configuration ('/ems' service of type 'api', '/ems/processes' resource, admin full permissions) ems_res_id = self._create_resource(self.magpie_service, resource_parent_id=None, resource_type='service', @@ -111,7 +110,7 @@ def _find_resource_id(self, parent_resource_id, resource_name): raise_http(httpError=HTTPNotFound, detail=detail) def _get_service_processes_resource(self): - # type: (...) -> Union[int, None] + # type: () -> Optional[int] """ Finds the magpie resource 'processes' corresponding to '/ems/processes'. @@ -378,7 +377,7 @@ def list_processes(self, visibility=None, request=None): return processes def fetch_by_id(self, process_id, visibility=None, request=None): - # type: (AnyStr, Optional[AnyStr], Optional[requests.Request]) -> Union[Process, None] + # type: (AnyStr, Optional[AnyStr], Optional[requests.Request]) -> Optional[Process] """ Get a process if visible for user. diff --git a/magpie/adapter/magpieservice.py b/magpie/adapter/magpieservice.py index 65707f1ec..8a2380f18 100644 --- a/magpie/adapter/magpieservice.py +++ b/magpie/adapter/magpieservice.py @@ -5,8 +5,7 @@ # noinspection PyUnresolvedReferences from magpie.definitions.twitcher_definitions import ServiceStore, Service, ServiceNotFound from magpie.definitions.pyramid_definitions import HTTPOk, asbool -from magpie.common import get_logger, JSON_TYPE -from magpie.utils import get_admin_cookies, get_magpie_url +from magpie.utils import get_admin_cookies, get_magpie_url, get_logger, CONTENT_TYPE_JSON import requests LOGGER = get_logger("TWITCHER") @@ -40,7 +39,7 @@ def list_services(self, request=None): # obtain admin access since 'service_url' is only provided on admin routes services = [] path = '{}/services'.format(self.magpie_url) - resp = requests.get(path, cookies=self.magpie_admin_token, headers={'Accept': JSON_TYPE}, + resp = requests.get(path, cookies=self.magpie_admin_token, headers={'Accept': CONTENT_TYPE_JSON}, verify=self.twitcher_ssl_verify) if resp.status_code != HTTPOk.code: raise resp.raise_for_status() diff --git a/magpie/alembic/env.py b/magpie/alembic/env.py index 3c4ac20d2..804a9c34f 100644 --- a/magpie/alembic/env.py +++ b/magpie/alembic/env.py @@ -8,7 +8,7 @@ from sqlalchemy_utils import database_exists, create_database from magpie.db import get_db_url from magpie.constants import get_constant -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) diff --git a/magpie/api/__init__.py b/magpie/api/__init__.py index 51a8327e6..be08fb8df 100644 --- a/magpie/api/__init__.py +++ b/magpie/api/__init__.py @@ -1,4 +1,4 @@ -from magpie.common import get_logger +from magpie.utils import get_logger logger = get_logger(__name__) diff --git a/magpie/api/api_except.py b/magpie/api/api_except.py index d4de6c99e..6d53af058 100644 --- a/magpie/api/api_except.py +++ b/magpie/api/api_except.py @@ -1,4 +1,3 @@ -from magpie.common import islambda, isclass, JSON_TYPE, HTML_TYPE, PLAIN_TYPE, CONTENT_TYPES from magpie.definitions.pyramid_definitions import ( HTTPError, HTTPException, @@ -8,13 +7,17 @@ HTTPRedirection, HTTPOk, ) +from magpie.utils import ( + islambda, isclass, + CONTENT_TYPE_ANY, CONTENT_TYPE_JSON, CONTENT_TYPE_HTML, CONTENT_TYPE_PLAIN, SUPPORTED_CONTENT_TYPES +) from typing import TYPE_CHECKING from sys import exc_info import json import six if TYPE_CHECKING: from magpie.definitions.typedefs import ( # noqa: F401 - Any, Str, Callable, List, Iterable, Optional, Tuple, Union, JsonBody, ParamKWArgs, PyramidResponse + Any, Str, Callable, List, Iterable, Optional, Tuple, Union, JSON, ParamsType, PyramidResponse ) # control variables to avoid infinite recursion in case of @@ -30,24 +33,24 @@ def verify_param( # noqa: E126 paramCompare=None, # type: Optional[Union[Any, List[Any]]] # --- output options on failure --- paramName=None, # type: Optional[Str] - withParam=True, # type: Optional[bool] - httpError=HTTPNotAcceptable, # type: Optional[HTTPError] - httpKWArgs=None, # type: Optional[ParamKWArgs] - msgOnFail="", # type: Optional[Str] - content=None, # type: Optional[JsonBody] - contentType=JSON_TYPE, # type: Optional[Str] + withParam=True, # type: bool + httpError=HTTPNotAcceptable, # type: HTTPError + httpKWArgs=None, # type: Optional[ParamsType] + msgOnFail="", # type: Str + content=None, # type: Optional[JSON] + contentType=CONTENT_TYPE_JSON, # type: Str # --- verification flags (method) --- - notNone=False, # type: Optional[bool] - notEmpty=False, # type: Optional[bool] - notIn=False, # type: Optional[bool] - notEqual=False, # type: Optional[bool] - isTrue=False, # type: Optional[bool] - isFalse=False, # type: Optional[bool] - isNone=False, # type: Optional[bool] - isEmpty=False, # type: Optional[bool] - isIn=False, # type: Optional[bool] - isEqual=False, # type: Optional[bool] - ofType=False, # type: Optional[bool] + notNone=False, # type: bool + notEmpty=False, # type: bool + notIn=False, # type: bool + notEqual=False, # type: bool + isTrue=False, # type: bool + isFalse=False, # type: bool + isNone=False, # type: bool + isEmpty=False, # type: bool + isIn=False, # type: bool + isEqual=False, # type: bool + ofType=False, # type: bool ): # type: (...) -> None """ Evaluate various parameter combinations given the requested verification flags. @@ -64,7 +67,7 @@ def verify_param( # noqa: E126 :param httpKWArgs: additional keyword arguments to pass to `httpError` if called in case of HTTP exception :param msgOnFail: message details to return in HTTP exception if flag condition failed :param content: json formatted additional content to provide in case of exception - :param contentType: format in which to return the exception (one of `magpie.common.CONTENT_TYPES`) + :param contentType: format in which to return the exception (one of `magpie.common.SUPPORTED_CONTENT_TYPES`) :param notNone: test that `param` is None type :param notEmpty: test that `param` is an empty string :param notIn: test that `param` does not exist in `paramCompare` values @@ -86,42 +89,42 @@ def verify_param( # noqa: E126 # precondition evaluation of input parameters try: if not isinstance(notNone, bool): - raise TypeError("`notNone` is not a `bool`") + raise TypeError("'notNone' is not a 'bool'") if not isinstance(notEmpty, bool): - raise TypeError("`notEmpty` is not a `bool`") + raise TypeError("'notEmpty' is not a 'bool'") if not isinstance(notIn, bool): - raise TypeError("`notIn` is not a `bool`") + raise TypeError("'notIn' is not a 'bool'") if not isinstance(notEqual, bool): - raise TypeError("`notEqual` is not a `bool`") + raise TypeError("'notEqual' is not a 'bool'") if not isinstance(isTrue, bool): - raise TypeError("`isTrue` is not a `bool`") + raise TypeError("'isTrue' is not a 'bool'") if not isinstance(isFalse, bool): - raise TypeError("`isFalse` is not a `bool`") + raise TypeError("'isFalse' is not a 'bool'") if not isinstance(isNone, bool): - raise TypeError("`isNone` is not a `bool`") + raise TypeError("'isNone' is not a 'bool'") if not isinstance(isEmpty, bool): - raise TypeError("`isEmpty` is not a `bool`") + raise TypeError("'isEmpty' is not a 'bool'") if not isinstance(isIn, bool): - raise TypeError("`isIn` is not a `bool`") + raise TypeError("'isIn' is not a 'bool'") if not isinstance(isEqual, bool): - raise TypeError("`isEqual` is not a `bool`") + raise TypeError("'isEqual' is not a 'bool'") if not isinstance(ofType, bool): - raise TypeError("`ofType` is not a `bool`") + raise TypeError("'ofType' is not a 'bool'") if paramCompare is None and (isIn or notIn or isEqual or notEqual): - raise TypeError("`paramCompare` cannot be `None` with specified test flags") + raise TypeError("'paramCompare' cannot be 'None' with specified test flags") if isEqual or notEqual: # allow 'different' string literals for comparison, otherwise types must match exactly if not (isinstance(param, six.string_types) and isinstance(paramCompare, six.string_types)) and type(param) != type(paramCompare): - raise TypeError("`paramCompare` cannot be of incompatible type with specified test flags") - if not hasattr(paramCompare, '__iter__') and (isIn or notIn): + raise TypeError("'paramCompare' cannot be of incompatible type with specified test flags") + if not hasattr(paramCompare, "__iter__") and (isIn or notIn): paramCompare = [paramCompare] # error if none of the flags specified if not any([notNone, notEmpty, notIn, notEqual, isTrue, isFalse, isNone, isEmpty, isIn, isEqual, ofType]): raise ValueError("no comparison flag specified for verification") except Exception as e: - content[u'traceback'] = repr(exc_info()) - content[u'exception'] = repr(e) + content[u"traceback"] = repr(exc_info()) + content[u"exception"] = repr(e) raise_http(httpError=HTTPInternalServerError, httpKWArgs=httpKWArgs, content=content, contentType=contentType, detail="Error occurred during parameter verification") @@ -152,22 +155,22 @@ def verify_param( # noqa: E126 fail_verify = fail_verify or (not isinstance(param, paramCompare)) if fail_verify: if withParam: - content[u'param'] = {u'value': str(param)} + content[u"param"] = {u"value": str(param)} if paramName is not None: - content[u'param'][u'name'] = str(paramName) + content[u"param"][u"name"] = str(paramName) if paramCompare is not None: - content[u'param'][u'compare'] = str(paramCompare) + content[u"param"][u"compare"] = str(paramCompare) raise_http(httpError, httpKWArgs=httpKWArgs, detail=msgOnFail, content=content, contentType=contentType) # noinspection PyPep8Naming -def evaluate_call(call, # type: Optional[Callable[[], Any]] +def evaluate_call(call, # type: Callable[[], Any] fallback=None, # type: Optional[Callable[[], None]] - httpError=HTTPInternalServerError, # type: Optional[HTTPError] - httpKWArgs=None, # type: Optional[ParamKWArgs] - msgOnFail="", # type: Optional[Str] - content=None, # type: Optional[JsonBody] - contentType=JSON_TYPE # type: Optional[Str] + httpError=HTTPInternalServerError, # type: HTTPError + httpKWArgs=None, # type: Optional[ParamsType] + msgOnFail="", # type: Str + content=None, # type: Optional[JSON] + contentType=CONTENT_TYPE_JSON # type: Str ): # type: (...) -> Any """ Evaluates the specified ``call`` with a wrapped HTTP exception handling. @@ -196,24 +199,24 @@ def evaluate_call(call, # type: Optional[Callabl :param httpKWArgs: additional keyword arguments to pass to `httpError` if called in case of HTTP exception :param msgOnFail: message details to return in HTTP exception if `call` failed :param content: json formatted additional content to provide in case of exception - :param contentType: format in which to return the exception (one of `magpie.common.CONTENT_TYPES`) + :param contentType: format in which to return the exception (one of `magpie.common.SUPPORTED_CONTENT_TYPES`) :raises httpError: on `call` failure :raises `HTTPInternalServerError`: on `fallback` failure :return: whichever return value `call` might have if no exception occurred """ - msgOnFail = repr(msgOnFail) if type(msgOnFail) is not str else msgOnFail + msgOnFail = repr(msgOnFail) if isinstance(msgOnFail, six.string_types) else msgOnFail if not islambda(call): raise_http(httpError=HTTPInternalServerError, httpKWArgs=httpKWArgs, - detail="Input `call` is not a lambda expression", - content={u'call': {u'detail': msgOnFail, u'content': repr(content)}}, + detail="Input 'call' is not a lambda expression.", + content={u"call": {u"detail": msgOnFail, u"content": repr(content)}}, contentType=contentType) # preemptively check fallback to avoid possible call exception without valid recovery if fallback is not None: if not islambda(fallback): raise_http(httpError=HTTPInternalServerError, httpKWArgs=httpKWArgs, - detail="Input `fallback` is not a lambda expression, not attempting `call`", - content={u'call': {u'detail': msgOnFail, u'content': repr(content)}}, + detail="Input 'fallback' is not a lambda expression, not attempting 'call'.", + content={u"call": {u"detail": msgOnFail, u"content": repr(content)}}, contentType=contentType) try: return call() @@ -225,22 +228,22 @@ def evaluate_call(call, # type: Optional[Callabl except Exception as e: fe = repr(e) raise_http(httpError=HTTPInternalServerError, httpKWArgs=httpKWArgs, - detail="Exception occurred during `fallback` called after failing `call` exception", - content={u'call': {u'exception': ce, u'detail': msgOnFail, u'content': repr(content)}, - u'fallback': {u'exception': fe}}, + detail="Exception occurred during 'fallback' called after failing 'call' exception.", + content={u"call": {u"exception": ce, u"detail": msgOnFail, u"content": repr(content)}, + u"fallback": {u"exception": fe}}, contentType=contentType) raise_http(httpError, detail=msgOnFail, httpKWArgs=httpKWArgs, - content={u'call': {u'exception': ce, u'content': repr(content)}}, + content={u"call": {u"exception": ce, u"content": repr(content)}}, contentType=contentType) # noinspection PyPep8Naming -def valid_http(httpSuccess=HTTPOk, # type: Optional[HTTPSuccessful] - httpKWArgs=None, # type: Optional[ParamKWArgs] - detail="", # type: Optional[Str] - content=None, # type: Optional[JsonBody] - contentType=JSON_TYPE, # type: Optional[Str] - ): # type: (...) -> HTTPException +def valid_http(httpSuccess=HTTPOk, # type: Optional[HTTPSuccessful] + httpKWArgs=None, # type: Optional[ParamsType] + detail="", # type: Optional[Str] + content=None, # type: Optional[JSON] + contentType=CONTENT_TYPE_JSON, # type: Optional[Str] + ): # type: (...) -> HTTPException """ Returns successful HTTP with standardized information formatted with content type. (see :function:`raise_http` for HTTP error calls) @@ -249,14 +252,14 @@ def valid_http(httpSuccess=HTTPOk, # type: Optional[HTTPSuccessful] :param httpKWArgs: additional keyword arguments to pass to `httpSuccess` when called :param detail: additional message information (default: empty) :param content: json formatted content to include - :param contentType: format in which to return the exception (one of `magpie.common.CONTENT_TYPES`) + :param contentType: format in which to return the exception (one of `magpie.common.SUPPORTED_CONTENT_TYPES`) :return `HTTPSuccessful`: formatted successful with additional details and HTTP code """ global RAISE_RECURSIVE_SAFEGUARD_COUNT content = dict() if content is None else content - detail = repr(detail) if type(detail) is not str else detail - contentType = JSON_TYPE if contentType == '*/*' else contentType + detail = repr(detail) if not isinstance(detail, six.string_types) else detail + contentType = CONTENT_TYPE_JSON if contentType == CONTENT_TYPE_ANY else contentType httpCode, detail, content = validate_params(httpSuccess, [HTTPSuccessful, HTTPRedirection], detail, content, contentType) json_body = format_content_json_str(httpCode, detail, content, contentType) @@ -266,13 +269,13 @@ def valid_http(httpSuccess=HTTPOk, # type: Optional[HTTPSuccessful] # noinspection PyPep8Naming -def raise_http(httpError=HTTPInternalServerError, # type: Optional[HTTPError] - httpKWArgs=None, # type: Optional[ParamKWArgs] - detail="", # type: Optional[Str] - content=None, # type: Optional[JsonBody] - contentType=JSON_TYPE, # type: Optional[Str] - nothrow=False # type: Optional[bool] - ): # type: (...) -> Union[HTTPException, None] +def raise_http(httpError=HTTPInternalServerError, # type: HTTPError + httpKWArgs=None, # type: Optional[ParamsType] + detail="", # type: Str + content=None, # type: Optional[JSON] + contentType=CONTENT_TYPE_JSON, # type: Str + nothrow=False # type: bool + ): # type: (...) -> Optional[HTTPException] """ Raises error HTTP with standardized information formatted with content type. @@ -286,7 +289,7 @@ def raise_http(httpError=HTTPInternalServerError, # type: Optional[HTTPError] :param httpKWArgs: additional keyword arguments to pass to `httpError` if called in case of HTTP exception :param detail: additional message information (default: empty) :param content: json formatted content to include - :param contentType: format in which to return the exception (one of `magpie.common.CONTENT_TYPES`) + :param contentType: format in which to return the exception (one of `magpie.common.SUPPORTED_CONTENT_TYPES`) :param nothrow: returns the error response instead of raising it automatically, but still handles execution errors :raises HTTPError: formatted raised exception with additional details and HTTP code :returns: HTTPError formatted exception with additional details and HTTP code only if `nothrow` is `True` @@ -302,7 +305,7 @@ def raise_http(httpError=HTTPInternalServerError, # type: Optional[HTTPError] # try dumping content with json format, `HTTPInternalServerError` with caller info if fails. # content is added manually to avoid auto-format and suppression of fields by `HTTPException` - contentType = JSON_TYPE if contentType == '*/*' else contentType + contentType = CONTENT_TYPE_JSON if contentType == CONTENT_TYPE_ANY else contentType httpCode, detail, content = validate_params(httpError, HTTPError, detail, content, contentType) json_body = format_content_json_str(httpError.code, detail, content, contentType) resp = generate_response_http_format(httpError, httpKWArgs, json_body, outputType=contentType) @@ -319,9 +322,9 @@ def raise_http(httpError=HTTPInternalServerError, # type: Optional[HTTPError] def validate_params(httpClass, # type: HTTPException httpBase, # type: Union[HTTPException, Iterable[HTTPException]] detail, # type: Str - content, # type: Union[JsonBody, None] + content, # type: Optional[JSON] contentType, # type: Str - ): # type: (...) -> Tuple[int, Str, JsonBody] + ): # type: (...) -> Tuple[int, Str, JSON] """ Validates parameter types and formats required by :function:`valid_http` and :function:`raise_http`. @@ -330,7 +333,7 @@ def validate_params(httpClass, # type: HTTPException (ie: 2xx, 4xx, 5xx codes). Can be a single class of an iterable of possible requirements (any). :param detail: additional message information (default: empty) :param content: json formatted content to include - :param contentType: format in which to return the exception (one of `magpie.common.CONTENT_TYPES`) + :param contentType: format in which to return the exception (one of `magpie.common.SUPPORTED_CONTENT_TYPES`) :raise `HTTPInternalServerError`: if any parameter is of invalid expected format :returns httpCode, detail, content: parameters with corrected and validated format if applicable """ @@ -338,24 +341,24 @@ def validate_params(httpClass, # type: HTTPException # cannot be done within a try/except because it would always trigger with `raise_http` content = dict() if content is None else content detail = repr(detail) if not isinstance(detail, six.string_types) else detail - caller = {u'content': content, u'type': contentType, u'detail': detail, u'code': 520} # 'unknown' code error - verify_param(isclass(httpClass), paramName='httpClass', isTrue=True, - httpError=HTTPInternalServerError, contentType=JSON_TYPE, content={u'caller': caller}, + caller = {u"content": content, u"type": contentType, u"detail": detail, u"code": 520} # "unknown" code error + verify_param(isclass(httpClass), paramName="httpClass", isTrue=True, + httpError=HTTPInternalServerError, contentType=CONTENT_TYPE_JSON, content={u"caller": caller}, msgOnFail="Object specified is not a class, class derived from `HTTPException` is expected.") # if `httpClass` derives from `httpBase` (ex: `HTTPSuccessful` or `HTTPError`) it is of proper requested type # if it derives from `HTTPException`, it *could* be different than base (ex: 2xx instead of 4xx codes) # return 'unknown error' (520) if not of lowest level base `HTTPException`, otherwise use the available code - httpBase = tuple(httpBase if hasattr(httpBase, '__iter__') else [httpBase]) + httpBase = tuple(httpBase if hasattr(httpBase, "__iter__") else [httpBase]) # noinspection PyUnresolvedReferences httpCode = httpClass.code if issubclass(httpClass, httpBase) else \ httpClass.code if issubclass(httpClass, HTTPException) else 520 # noqa: F401 - caller[u'code'] = httpCode - verify_param(issubclass(httpClass, httpBase), paramName='httpBase', isTrue=True, - httpError=HTTPInternalServerError, contentType=JSON_TYPE, content={u'caller': caller}, - msgOnFail="Invalid `httpBase` derived class specified.") - verify_param(contentType, paramName='contentType', paramCompare=CONTENT_TYPES, isIn=True, - httpError=HTTPInternalServerError, contentType=JSON_TYPE, content={u'caller': caller}, - msgOnFail="Invalid `contentType` specified for exception output.") + caller[u"code"] = httpCode + verify_param(issubclass(httpClass, httpBase), paramName="httpBase", isTrue=True, + httpError=HTTPInternalServerError, contentType=CONTENT_TYPE_JSON, content={u"caller": caller}, + msgOnFail="Invalid 'httpBase' derived class specified.") + verify_param(contentType, paramName="contentType", paramCompare=SUPPORTED_CONTENT_TYPES, isIn=True, + httpError=HTTPInternalServerError, contentType=CONTENT_TYPE_JSON, content={u"caller": caller}, + msgOnFail="Invalid 'contentType' specified for exception output.") return httpCode, detail, content @@ -371,64 +374,64 @@ def format_content_json_str(httpCode, detail, content, contentType): """ json_body = {} try: - content[u'code'] = httpCode - content[u'detail'] = detail - content[u'type'] = contentType + content[u"code"] = httpCode + content[u"detail"] = detail + content[u"type"] = contentType json_body = json.dumps(content) except Exception as e: - msg = "Dumping json content `" + str(content) + \ - "` resulted in exception `" + repr(e) + "`" + msg = "Dumping json content '{!s}' resulted in exception '{!r}'.".format(content, e) raise_http(httpError=HTTPInternalServerError, detail=msg, - contentType=JSON_TYPE, - content={u'traceback': repr(exc_info()), u'exception': repr(e), - u'caller': {u'content': repr(content), # raw string to avoid recursive json.dumps error - u'detail': detail, - u'code': httpCode, - u'type': contentType}}) + contentType=CONTENT_TYPE_JSON, + content={u"traceback": repr(exc_info()), + u"exception": repr(e), + u"caller": {u"content": repr(content), # raw string to avoid recursive json.dumps error + u"detail": detail, + u"code": httpCode, + u"type": contentType}}) return json_body # noinspection PyPep8Naming -def generate_response_http_format(httpClass, httpKWArgs, jsonContent, outputType=PLAIN_TYPE): - # type: (Union[HTTPException, PyramidResponse], ParamKWArgs, JsonBody, Optional[Str]) -> PyramidResponse +def generate_response_http_format(httpClass, httpKWArgs, jsonContent, outputType=CONTENT_TYPE_PLAIN): + # type: (Union[HTTPException, PyramidResponse], ParamsType, JSON, Optional[Str]) -> PyramidResponse """ Formats the HTTP response output according to desired ``outputType`` using provided HTTP code and content. :param httpClass: `HTTPException` derived class to use for output (code, generic title/explanation, etc.) :param httpKWArgs: additional keyword arguments to pass to `httpClass` when called :param jsonContent: formatted json content providing additional details for the response cause - :param outputType: one of `magpie.common.CONTENT_TYPES` (default: `magpie.common.PLAIN_TYPE`) + :param outputType: one of `magpie.common.SUPPORTED_CONTENT_TYPES` (default: `magpie.common.CONTENT_TYPE_PLAIN`) :return: `httpClass` instance with requested information and output type if creation succeeds :raises: `HTTPInternalServerError` instance details about requested information and output type if creation fails """ # content body is added manually to avoid auto-format and suppression of fields by `HTTPException` - jsonContent = str(jsonContent) if not type(jsonContent) == str else jsonContent + jsonContent = str(jsonContent) if not isinstance(jsonContent, six.string_types) else jsonContent # adjust additional keyword arguments and try building the http response class with them httpKWArgs = dict() if httpKWArgs is None else httpKWArgs try: # directly output json - if outputType == JSON_TYPE: - json_type = '{}; charset=UTF-8'.format(JSON_TYPE) + if outputType == CONTENT_TYPE_JSON: + json_type = "{}; charset=UTF-8".format(CONTENT_TYPE_JSON) httpResponse = httpClass(body=jsonContent, content_type=json_type, **httpKWArgs) # otherwise json is contained within the html section - elif outputType == HTML_TYPE: + elif outputType == CONTENT_TYPE_HTML: # add preformat
 section to output as is within the  section
             htmlBody = "{}

Exception Details

" \ "

Exception Details

" \ "
{}
" \ .format(httpClass.explanation, jsonContent) - httpResponse = httpClass(body_template=htmlBody, content_type=HTML_TYPE, **httpKWArgs) + httpResponse = httpClass(body_template=htmlBody, content_type=CONTENT_TYPE_HTML, **httpKWArgs) # default back to plain text else: - httpResponse = httpClass(body=jsonContent, content_type=PLAIN_TYPE, **httpKWArgs) + httpResponse = httpClass(body=jsonContent, content_type=CONTENT_TYPE_PLAIN, **httpKWArgs) return httpResponse except Exception as e: raise_http(httpError=HTTPInternalServerError, detail="Failed to build HTTP response", - content={u'traceback': repr(exc_info()), u'exception': repr(e), - u'caller': {u'httpKWArgs': repr(httpKWArgs), - u'httpClass': repr(httpClass), - u'outputType': str(outputType)}}) + content={u"traceback": repr(exc_info()), u"exception": repr(e), + u"caller": {u"httpKWArgs": repr(httpKWArgs), + u"httpClass": repr(httpClass), + u"outputType": str(outputType)}}) diff --git a/magpie/api/api_generic.py b/magpie/api/api_generic.py index 2133f5ae1..fea57941f 100644 --- a/magpie/api/api_generic.py +++ b/magpie/api/api_generic.py @@ -1,3 +1,5 @@ +from magpie.api.api_except import raise_http +from magpie.api import api_rest_schemas as s from magpie.definitions.pyramid_definitions import ( IAuthenticationPolicy, Authenticated, @@ -9,16 +11,14 @@ HTTPInternalServerError, HTTPServerError, ) -from magpie.api.api_except import raise_http -from magpie.api import api_rest_schemas as s -from magpie.common import get_header, JSON_TYPE +from magpie.utils import get_header, CONTENT_TYPE_JSON from simplejson import JSONDecodeError def internal_server_error(request): content = get_request_info(request, default_message=s.InternalServerErrorResponseSchema.description) return raise_http(nothrow=True, httpError=HTTPInternalServerError, detail=content['detail'], content=content, - contentType=get_header('Accept', request.headers, default=JSON_TYPE, split=';,')) + contentType=get_header('Accept', request.headers, default=CONTENT_TYPE_JSON, split=';,')) def not_found_or_method_not_allowed(request): @@ -41,7 +41,7 @@ def not_found_or_method_not_allowed(request): http_msg = s.NotFoundResponseSchema.description content = get_request_info(request, default_message=http_msg) return raise_http(nothrow=True, httpError=http_err, detail=content['detail'], content=content, - contentType=get_header('Accept', request.headers, default=JSON_TYPE, split=';,')) + contentType=get_header('Accept', request.headers, default=CONTENT_TYPE_JSON, split=';,')) def unauthorized_or_forbidden(request): @@ -67,7 +67,7 @@ def unauthorized_or_forbidden(request): content = get_request_info(request, default_message=http_msg) return raise_http(nothrow=True, httpError=http_err, detail=content['detail'], content=content, - contentType=get_header('Accept', request.headers, default=JSON_TYPE, split=';,')) + contentType=get_header('Accept', request.headers, default=CONTENT_TYPE_JSON, split=';,')) def get_request_info(request, default_message="undefined"): diff --git a/magpie/api/api_requests.py b/magpie/api/api_requests.py index 1ff91a7f5..dd51e0f61 100644 --- a/magpie/api/api_requests.py +++ b/magpie/api/api_requests.py @@ -1,6 +1,5 @@ from magpie.api.api_except import evaluate_call, verify_param from magpie.api import api_rest_schemas as s -from magpie.common import JSON_TYPE from magpie.constants import get_constant from magpie.definitions import ziggurat_definitions as zig from magpie.definitions.pyramid_definitions import ( @@ -11,23 +10,24 @@ HTTPUnprocessableEntity, HTTPInternalServerError, ) +from magpie.utils import CONTENT_TYPE_JSON from magpie import models from typing import TYPE_CHECKING if TYPE_CHECKING: from magpie.definitions.pyramid_definitions import Request # noqa: F401 - from magpie.definitions.typedefs import Any, AnyStr, Optional # noqa: F401 + from magpie.definitions.typedefs import Any, Str, Optional # noqa: F401 def get_request_method_content(request): # 'request' object stores GET content into 'GET' property, while other methods are in 'POST' property - method_property = 'GET' if request.method == 'GET' else 'POST' + method_property = "GET" if request.method == "GET" else "POST" return getattr(request, method_property) def get_multiformat_any(request, key, default=None): - msg = "Key `{key}` could not be extracted from {method} of type `{type}`" \ + msg = "Key '{key}' could not be extracted from '{method}' of type '{type}'" \ .format(key=repr(key), method=request.method, type=request.content_type) - if request.content_type == JSON_TYPE: + if request.content_type == CONTENT_TYPE_JSON: # avoid json parse error if body is empty if not len(request.body): return default @@ -49,11 +49,11 @@ def get_multiformat_delete(request, key, default=None): return get_multiformat_any(request, key, default) -def get_permission_multiformat_post_checked(request, service_resource, permission_name_key='permission_name'): +def get_permission_multiformat_post_checked(request, service_resource, permission_name_key="permission_name"): # import here to avoid circular import error with undefined functions between (api_request, resource_utils) - from magpie.api.management.resource.resource_utils import check_valid_service_resource_permission + from magpie.api.management.resource.resource_utils import check_valid_service_or_resource_permission perm_name = get_value_multiformat_post_checked(request, permission_name_key) - check_valid_service_resource_permission(perm_name, service_resource, request.db) + check_valid_service_or_resource_permission(perm_name, service_resource, request.db) return perm_name @@ -69,7 +69,7 @@ def get_userid_by_token(token, authn_policy): cookie = token if cookie is None: return None - remote_addr = '0.0.0.0' + remote_addr = "0.0.0.0" timestamp, userid, tokens, user_data = cookie_helper.parse_ticket( cookie_helper.secret, @@ -81,12 +81,12 @@ def get_userid_by_token(token, authn_policy): def get_user(request, user_name_or_token): - if user_name_or_token == get_constant('MAGPIE_LOGGED_USER'): + if user_name_or_token == get_constant("MAGPIE_LOGGED_USER"): curr_user = request.user if curr_user: return curr_user else: - anonymous_user = get_constant('MAGPIE_ANONYMOUS_USER') + anonymous_user = get_constant("MAGPIE_ANONYMOUS_USER") anonymous = evaluate_call(lambda: zig.UserService.by_user_name(anonymous_user, db_session=request.db), fallback=lambda: request.db.rollback(), httpError=HTTPForbidden, msgOnFail=s.User_CheckAnonymous_ForbiddenResponseSchema.description) @@ -96,8 +96,8 @@ def get_user(request, user_name_or_token): else: authn_policy = request.registry.queryUtility(IAuthenticationPolicy) principals = authn_policy.effective_principals(request) - admin_group = zig.GroupService.by_group_name(get_constant('MAGPIE_ADMIN_GROUP'), db_session=request.db) - admin_principal = 'group:{}'.format(admin_group.id) + admin_group = zig.GroupService.by_group_name(get_constant("MAGPIE_ADMIN_GROUP"), db_session=request.db) + admin_principal = "group:{}".format(admin_group.id) if admin_principal not in principals: raise HTTPForbidden() user = evaluate_call(lambda: zig.UserService.by_user_name(user_name_or_token, db_session=request.db), @@ -108,20 +108,20 @@ def get_user(request, user_name_or_token): return user -def get_user_matchdict_checked_or_logged(request, user_name_key='user_name'): - logged_user_name = get_constant('MAGPIE_LOGGED_USER') - logged_user_path = s.UserAPI.path.replace('{' + user_name_key + '}', logged_user_name) +def get_user_matchdict_checked_or_logged(request, user_name_key="user_name"): + logged_user_name = get_constant("MAGPIE_LOGGED_USER") + logged_user_path = s.UserAPI.path.replace("{" + user_name_key + "}", logged_user_name) if user_name_key not in request.matchdict and request.path_info.startswith(logged_user_path): return get_user(request, logged_user_name) return get_user_matchdict_checked(request, user_name_key) -def get_user_matchdict_checked(request, user_name_key='user_name'): +def get_user_matchdict_checked(request, user_name_key="user_name"): user_name = get_value_matchdict_checked(request, user_name_key) return get_user(request, user_name) -def get_group_matchdict_checked(request, group_name_key='group_name'): +def get_group_matchdict_checked(request, group_name_key="group_name"): group_name = get_value_matchdict_checked(request, group_name_key) group = evaluate_call(lambda: zig.GroupService.by_group_name(group_name, db_session=request.db), fallback=lambda: request.db.rollback(), httpError=HTTPForbidden, @@ -131,7 +131,7 @@ def get_group_matchdict_checked(request, group_name_key='group_name'): return group -def get_resource_matchdict_checked(request, resource_name_key='resource_id'): +def get_resource_matchdict_checked(request, resource_name_key="resource_id"): resource_id = get_value_matchdict_checked(request, resource_name_key) resource_id = evaluate_call(lambda: int(resource_id), httpError=HTTPNotAcceptable, msgOnFail=s.Resource_MatchDictCheck_NotAcceptableResponseSchema.description) @@ -143,7 +143,7 @@ def get_resource_matchdict_checked(request, resource_name_key='resource_id'): return resource -def get_service_matchdict_checked(request, service_name_key='service_name'): +def get_service_matchdict_checked(request, service_name_key="service_name"): service_name = get_value_matchdict_checked(request, service_name_key) service = evaluate_call(lambda: models.Service.by_service_name(service_name, db_session=request.db), fallback=lambda: request.db.rollback(), httpError=HTTPForbidden, @@ -153,11 +153,21 @@ def get_service_matchdict_checked(request, service_name_key='service_name'): return service -def get_permission_matchdict_checked(request, service_resource, permission_name_key='permission_name'): +def get_permission_matchdict_checked(request, service_or_resource, permission_name_key="permission_name"): + # type: (Request, models.Resource, Str) -> Str + """ + Obtains the `permission` specified in the ``request`` path and validates that it is allowed for the + specified ``service_or_resource`` which can be a `service` or a children `resource`. + + Allowed permissions correspond to the direct `service` permissions or restrained permissions of the `resource` + under its root `service`. + + :returns: found permission name if valid for the service/resource + """ # import here to avoid circular import error with undefined functions between (api_request, resource_utils) - from magpie.api.management.resource.resource_utils import check_valid_service_resource_permission + from magpie.api.management.resource.resource_utils import check_valid_service_or_resource_permission perm_name = get_value_matchdict_checked(request, permission_name_key) - check_valid_service_resource_permission(perm_name, service_resource, request.db) + check_valid_service_or_resource_permission(perm_name, service_or_resource, request.db) return perm_name @@ -169,7 +179,7 @@ def get_value_matchdict_checked(request, key): def get_query_param(request, case_insensitive_key, default=None): - # type: (Request, AnyStr, Optional[Any]) -> Any + # type: (Request, Str, Optional[Any]) -> Any """Retrieves a query string value by name (case insensitive), or returns the default if not present.""" for p in request.params: if p.lower() == case_insensitive_key: diff --git a/magpie/api/api_rest_schemas.py b/magpie/api/api_rest_schemas.py index 236cdb944..6254a2bdd 100644 --- a/magpie/api/api_rest_schemas.py +++ b/magpie/api/api_rest_schemas.py @@ -14,9 +14,9 @@ HTTPInternalServerError, NO_PERMISSION_REQUIRED, ) -from magpie.common import JSON_TYPE from magpie.constants import get_constant -from magpie.utils import get_magpie_url +from magpie.permissions import Permission +from magpie.utils import get_magpie_url, CONTENT_TYPE_JSON # from magpie.security import get_provider_names from magpie import __meta__ import six @@ -30,19 +30,19 @@ # Tags -APITag = 'API' -LoginTag = 'Login' -UsersTag = 'User' -LoggedUserTag = 'Logged User' -GroupsTag = 'Group' -ResourcesTag = 'Resource' -ServicesTag = 'Service' +APITag = "API" +LoginTag = "Login" +UsersTag = "User" +LoggedUserTag = "Logged User" +GroupsTag = "Group" +ResourcesTag = "Resource" +ServicesTag = "Service" # Security -SecurityCookieAuthAPI = {'cookieAuth': {'type': 'apiKey', 'in': 'cookie', 'name': get_constant('MAGPIE_COOKIE_NAME')}} -SecurityDefinitionsAPI = {'securityDefinitions': SecurityCookieAuthAPI} -SecurityAdministratorAPI = [{'cookieAuth': []}] +SecurityCookieAuthAPI = {"cookieAuth": {"type": "apiKey", "in": "cookie", "name": get_constant("MAGPIE_COOKIE_NAME")}} +SecurityDefinitionsAPI = {"securityDefinitions": SecurityCookieAuthAPI} +SecurityAdministratorAPI = [{"cookieAuth": []}] SecurityEveryoneAPI = [{}] @@ -54,219 +54,219 @@ def get_security(service, method): if met == method: break # automatically retrieve permission if specified within the view definition - permission = args.get('permission') + permission = args.get("permission") if permission == NO_PERMISSION_REQUIRED: return SecurityEveryoneAPI - elif permission == get_constant('MAGPIE_ADMIN_PERMISSION'): + elif permission == get_constant("MAGPIE_ADMIN_PERMISSION"): return SecurityAdministratorAPI # return default admin permission otherwise unless specified form cornice decorator - return SecurityAdministratorAPI if 'security' not in args else args['security'] + return SecurityAdministratorAPI if "security" not in args else args["security"] # Service Routes def service_api_route_info(service_api): - return {'name': service_api.name, 'pattern': service_api.path} + return {"name": service_api.name, "pattern": service_api.path} -LoggedUserBase = '/users/{}'.format(get_constant('MAGPIE_LOGGED_USER')) +LoggedUserBase = "/users/{}".format(get_constant("MAGPIE_LOGGED_USER")) SwaggerGenerator = Service( - path='/json', - name='swagger_schema_json') + path="/json", + name="swagger_schema_json") SwaggerAPI = Service( - path='/api', - name='swagger_schema_ui', + path="/api", + name="swagger_schema_ui", description="{} documentation".format(TitleAPI)) UsersAPI = Service( - path='/users', - name='Users') + path="/users", + name="Users") UserAPI = Service( - path='/users/{user_name}', - name='User') + path="/users/{user_name}", + name="User") UserGroupsAPI = Service( - path='/users/{user_name}/groups', - name='UserGroups') + path="/users/{user_name}/groups", + name="UserGroups") UserGroupAPI = Service( - path='/users/{user_name}/groups/{group_name}', - name='UserGroup') + path="/users/{user_name}/groups/{group_name}", + name="UserGroup") UserInheritedResourcesAPI = Service( - path='/users/{user_name}/inherited_resources', - name='UserInheritedResources') + path="/users/{user_name}/inherited_resources", + name="UserInheritedResources") UserResourcesAPI = Service( - path='/users/{user_name}/resources', - name='UserResources') + path="/users/{user_name}/resources", + name="UserResources") UserResourceInheritedPermissionsAPI = Service( - path='/users/{user_name}/resources/{resource_id}/inherited_permissions', - name='UserResourceInheritedPermissions') + path="/users/{user_name}/resources/{resource_id}/inherited_permissions", + name="UserResourceInheritedPermissions") UserResourcePermissionAPI = Service( - path='/users/{user_name}/resources/{resource_id}/permissions/{permission_name}', - name='UserResourcePermission') + path="/users/{user_name}/resources/{resource_id}/permissions/{permission_name}", + name="UserResourcePermission") UserResourcePermissionsAPI = Service( - path='/users/{user_name}/resources/{resource_id}/permissions', - name='UserResourcePermissions') + path="/users/{user_name}/resources/{resource_id}/permissions", + name="UserResourcePermissions") UserResourceTypesAPI = Service( - path='/users/{user_name}/resources/types/{resource_type}', - name='UserResourceTypes') + path="/users/{user_name}/resources/types/{resource_type}", + name="UserResourceTypes") UserInheritedServicesAPI = Service( - path='/users/{user_name}/inherited_services', - name='UserInheritedServices') + path="/users/{user_name}/inherited_services", + name="UserInheritedServices") UserServicesAPI = Service( - path='/users/{user_name}/services', - name='UserServices') + path="/users/{user_name}/services", + name="UserServices") UserServiceAPI = Service( - path='/users/{user_name}/services/{service_name}', - name='UserService') + path="/users/{user_name}/services/{service_name}", + name="UserService") UserServiceInheritedResourcesAPI = Service( - path='/users/{user_name}/services/{service_name}/inherited_resources', - name='UserServiceInheritedResources') + path="/users/{user_name}/services/{service_name}/inherited_resources", + name="UserServiceInheritedResources") UserServiceResourcesAPI = Service( - path='/users/{user_name}/services/{service_name}/resources', - name='UserServiceResources') + path="/users/{user_name}/services/{service_name}/resources", + name="UserServiceResources") UserServiceInheritedPermissionsAPI = Service( - path='/users/{user_name}/services/{service_name}/inherited_permissions', - name='UserServiceInheritedPermissions') + path="/users/{user_name}/services/{service_name}/inherited_permissions", + name="UserServiceInheritedPermissions") UserServicePermissionsAPI = Service( - path='/users/{user_name}/services/{service_name}/permissions', - name='UserServicePermissions') + path="/users/{user_name}/services/{service_name}/permissions", + name="UserServicePermissions") UserServicePermissionAPI = Service( - path='/users/{user_name}/services/{service_name}/permissions/{permission_name}', - name='UserServicePermission') + path="/users/{user_name}/services/{service_name}/permissions/{permission_name}", + name="UserServicePermission") LoggedUserAPI = Service( path=LoggedUserBase, - name='LoggedUser') + name="LoggedUser") LoggedUserGroupsAPI = Service( - path=LoggedUserBase + '/groups', - name='LoggedUserGroups') + path=LoggedUserBase + "/groups", + name="LoggedUserGroups") LoggedUserGroupAPI = Service( - path=LoggedUserBase + '/groups/{group_name}', - name='LoggedUserGroup') + path=LoggedUserBase + "/groups/{group_name}", + name="LoggedUserGroup") LoggedUserInheritedResourcesAPI = Service( - path=LoggedUserBase + '/inherited_resources', - name='LoggedUserInheritedResources') + path=LoggedUserBase + "/inherited_resources", + name="LoggedUserInheritedResources") LoggedUserResourcesAPI = Service( - path=LoggedUserBase + '/resources', - name='LoggedUserResources') + path=LoggedUserBase + "/resources", + name="LoggedUserResources") LoggedUserResourceInheritedPermissionsAPI = Service( - path=LoggedUserBase + '/resources/{resource_id}/inherited_permissions', - name='LoggedUserResourceInheritedPermissions') + path=LoggedUserBase + "/resources/{resource_id}/inherited_permissions", + name="LoggedUserResourceInheritedPermissions") LoggedUserResourcePermissionAPI = Service( - path=LoggedUserBase + '/resources/{resource_id}/permissions/{permission_name}', - name='LoggedUserResourcePermission') + path=LoggedUserBase + "/resources/{resource_id}/permissions/{permission_name}", + name="LoggedUserResourcePermission") LoggedUserResourcePermissionsAPI = Service( - path=LoggedUserBase + '/resources/{resource_id}/permissions', - name='LoggedUserResourcePermissions') + path=LoggedUserBase + "/resources/{resource_id}/permissions", + name="LoggedUserResourcePermissions") LoggedUserResourceTypesAPI = Service( - path=LoggedUserBase + '/resources/types/{resource_type}', - name='LoggedUserResourceTypes') + path=LoggedUserBase + "/resources/types/{resource_type}", + name="LoggedUserResourceTypes") LoggedUserInheritedServicesAPI = Service( - path=LoggedUserBase + '/inherited_services', - name='LoggedUserInheritedServices') + path=LoggedUserBase + "/inherited_services", + name="LoggedUserInheritedServices") LoggedUserServicesAPI = Service( - path=LoggedUserBase + '/services', - name='LoggedUserServices') + path=LoggedUserBase + "/services", + name="LoggedUserServices") LoggedUserServiceInheritedResourcesAPI = Service( - path=LoggedUserBase + '/services/{service_name}/inherited_resources', - name='LoggedUserServiceInheritedResources') + path=LoggedUserBase + "/services/{service_name}/inherited_resources", + name="LoggedUserServiceInheritedResources") LoggedUserServiceResourcesAPI = Service( - path=LoggedUserBase + '/services/{service_name}/resources', - name='LoggedUserServiceResources') + path=LoggedUserBase + "/services/{service_name}/resources", + name="LoggedUserServiceResources") LoggedUserServiceInheritedPermissionsAPI = Service( - path=LoggedUserBase + '/services/{service_name}/inherited_permissions', - name='LoggedUserServiceInheritedPermissions') + path=LoggedUserBase + "/services/{service_name}/inherited_permissions", + name="LoggedUserServiceInheritedPermissions") LoggedUserServicePermissionsAPI = Service( - path=LoggedUserBase + '/services/{service_name}/permissions', - name='LoggedUserServicePermissions') + path=LoggedUserBase + "/services/{service_name}/permissions", + name="LoggedUserServicePermissions") LoggedUserServicePermissionAPI = Service( - path=LoggedUserBase + '/services/{service_name}/permissions/{permission_name}', - name='LoggedUserServicePermission') + path=LoggedUserBase + "/services/{service_name}/permissions/{permission_name}", + name="LoggedUserServicePermission") GroupsAPI = Service( - path='/groups', - name='Groups') + path="/groups", + name="Groups") GroupAPI = Service( - path='/groups/{group_name}', - name='Group') + path="/groups/{group_name}", + name="Group") GroupUsersAPI = Service( - path='/groups/{group_name}/users', - name='GroupUsers') + path="/groups/{group_name}/users", + name="GroupUsers") GroupServicesAPI = Service( - path='/groups/{group_name}/services', - name='GroupServices') + path="/groups/{group_name}/services", + name="GroupServices") GroupServicePermissionsAPI = Service( - path='/groups/{group_name}/services/{service_name}/permissions', - name='GroupServicePermissions') + path="/groups/{group_name}/services/{service_name}/permissions", + name="GroupServicePermissions") GroupServicePermissionAPI = Service( - path='/groups/{group_name}/services/{service_name}/permissions/{permission_name}', - name='GroupServicePermission') + path="/groups/{group_name}/services/{service_name}/permissions/{permission_name}", + name="GroupServicePermission") GroupServiceResourcesAPI = Service( - path='/groups/{group_name}/services/{service_name}/resources', - name='GroupServiceResources') + path="/groups/{group_name}/services/{service_name}/resources", + name="GroupServiceResources") GroupResourcesAPI = Service( - path='/groups/{group_name}/resources', - name='GroupResources') + path="/groups/{group_name}/resources", + name="GroupResources") GroupResourcePermissionsAPI = Service( - path='/groups/{group_name}/resources/{resource_id}/permissions', - name='GroupResourcePermissions') + path="/groups/{group_name}/resources/{resource_id}/permissions", + name="GroupResourcePermissions") GroupResourcePermissionAPI = Service( - path='/groups/{group_name}/resources/{resource_id}/permissions/{permission_name}', - name='GroupResourcePermission') + path="/groups/{group_name}/resources/{resource_id}/permissions/{permission_name}", + name="GroupResourcePermission") GroupResourceTypesAPI = Service( - path='/groups/{group_name}/resources/types/{resource_type}', - name='GroupResourceTypes') + path="/groups/{group_name}/resources/types/{resource_type}", + name="GroupResourceTypes") ResourcesAPI = Service( - path='/resources', - name='Resources') + path="/resources", + name="Resources") ResourceAPI = Service( - path='/resources/{resource_id}', - name='Resource') + path="/resources/{resource_id}", + name="Resource") ResourcePermissionsAPI = Service( - path='/resources/{resource_id}/permissions', - name='ResourcePermissions') + path="/resources/{resource_id}/permissions", + name="ResourcePermissions") ServicesAPI = Service( - path='/services', - name='Services') + path="/services", + name="Services") ServiceAPI = Service( - path='/services/{service_name}', - name='Service') + path="/services/{service_name}", + name="Service") ServiceTypesAPI = Service( - path='/services/types', - name='ServiceTypes') + path="/services/types", + name="ServiceTypes") ServiceTypeAPI = Service( - path='/services/types/{service_type}', - name='ServiceType') + path="/services/types/{service_type}", + name="ServiceType") ServicePermissionsAPI = Service( - path='/services/{service_name}/permissions', - name='ServicePermissions') + path="/services/{service_name}/permissions", + name="ServicePermissions") ServiceResourcesAPI = Service( - path='/services/{service_name}/resources', - name='ServiceResources') + path="/services/{service_name}/resources", + name="ServiceResources") ServiceResourceAPI = Service( - path='/services/{service_name}/resources/{resource_id}', - name='ServiceResource') + path="/services/{service_name}/resources/{resource_id}", + name="ServiceResource") ServiceTypeResourcesAPI = Service( - path='/services/types/{service_type}/resources', - name='ServiceTypeResources') + path="/services/types/{service_type}/resources", + name="ServiceTypeResources") ServiceTypeResourceTypesAPI = Service( - path='/services/types/{service_type}/resources/types', - name='ServiceTypeResourceTypes') + path="/services/types/{service_type}/resources/types", + name="ServiceTypeResourceTypes") ProvidersAPI = Service( - path='/providers', - name='Providers') + path="/providers", + name="Providers") ProviderSigninAPI = Service( - path='/providers/{provider_name}/signin', - name='ProviderSignin') + path="/providers/{provider_name}/signin", + name="ProviderSignin") SigninAPI = Service( - path='/signin', - name='signin') + path="/signin", + name="signin") SignoutAPI = Service( - path='/signout', - name='signout') + path="/signout", + name="signout") SessionAPI = Service( - path='/session', - name='Session') + path="/session", + name="Session") VersionAPI = Service( - path='/version', - name='Version') + path="/version", + name="Version") # Common path parameters @@ -301,21 +301,21 @@ def service_api_route_info(service_api): class HeaderResponseSchema(colander.MappingSchema): content_type = colander.SchemaNode( colander.String(), - default=JSON_TYPE, - example=JSON_TYPE, - description='Content type of the response body.', + default=CONTENT_TYPE_JSON, + example=CONTENT_TYPE_JSON, + description="Content type of the response body.", ) - content_type.name = 'Content-Type' + content_type.name = "Content-Type" class HeaderRequestSchema(colander.MappingSchema): content_type = colander.SchemaNode( colander.String(), - default=JSON_TYPE, - example=JSON_TYPE, + default=CONTENT_TYPE_JSON, + example=CONTENT_TYPE_JSON, missing=colander.drop, ) - content_type.name = 'Content-Type' + content_type.name = "Content-Type" QueryEffectivePermissions = colander.SchemaNode( @@ -343,11 +343,11 @@ def __init__(self, code, description, **kw): self.__desc = description # update the values - child_nodes = getattr(self, 'children') + child_nodes = getattr(self, "children") for node in child_nodes: - if node.name == 'code': + if node.name == "code": node.example = self.__code - if node.name == 'detail': + if node.name == "detail": node.example = self.__desc code = colander.SchemaNode( @@ -357,7 +357,7 @@ def __init__(self, code, description, **kw): type = colander.SchemaNode( colander.String(), description="Response content type", - example=JSON_TYPE) + example=CONTENT_TYPE_JSON) detail = colander.SchemaNode( colander.String(), description="Response status message", @@ -399,13 +399,13 @@ def __init__(self, code, description, **kw): class InternalServerErrorResponseBodySchema(ErrorResponseBodySchema): def __init__(self, **kw): - kw['code'] = HTTPInternalServerError.code + kw["code"] = HTTPInternalServerError.code super(InternalServerErrorResponseBodySchema, self).__init__(**kw) class UnauthorizedResponseBodySchema(BaseResponseBodySchema): def __init__(self, **kw): - kw['code'] = HTTPUnauthorized.code + kw["code"] = HTTPUnauthorized.code super(UnauthorizedResponseBodySchema, self).__init__(**kw) route_name = colander.SchemaNode(colander.String(), description="Specified route") @@ -523,7 +523,7 @@ class ServiceBodySchema(colander.MappingSchema): description="Resource identification number", ) permission_names = PermissionListSchema( - example=['read', 'write'] + example=["read", "write"] ) service_name = colander.SchemaNode( colander.String(), diff --git a/magpie/api/home/__init__.py b/magpie/api/home/__init__.py index 4f2220945..d69914e04 100644 --- a/magpie/api/home/__init__.py +++ b/magpie/api/home/__init__.py @@ -1,5 +1,5 @@ from magpie.api import api_rest_schemas as s -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) diff --git a/magpie/api/home/home.py b/magpie/api/home/home.py index dbc07bac3..550e4e373 100644 --- a/magpie/api/home/home.py +++ b/magpie/api/home/home.py @@ -1,7 +1,7 @@ from magpie.api import api_except as ax, api_rest_schemas as s from magpie.definitions.pyramid_definitions import NO_PERMISSION_REQUIRED, HTTPOk, view_config -from magpie.common import JSON_TYPE from magpie.db import get_database_revision +from magpie.utils import CONTENT_TYPE_JSON from magpie import __meta__ @@ -21,5 +21,5 @@ def get_version(request): u'version': __meta__.__version__, u'db_version': version_db } - return ax.valid_http(httpSuccess=HTTPOk, content=version, contentType=JSON_TYPE, + return ax.valid_http(httpSuccess=HTTPOk, content=version, contentType=CONTENT_TYPE_JSON, detail=s.Version_GET_OkResponseSchema.description) diff --git a/magpie/api/login/__init__.py b/magpie/api/login/__init__.py index a0bd825ff..05a0689fd 100644 --- a/magpie/api/login/__init__.py +++ b/magpie/api/login/__init__.py @@ -1,10 +1,10 @@ -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) def includeme(config): from magpie.api import api_rest_schemas as s - LOGGER.info('Adding api login ...') + LOGGER.info("Adding api login ...") # Add all the rest api routes config.add_route(**s.service_api_route_info(s.SessionAPI)) config.add_route(**s.service_api_route_info(s.SigninAPI)) diff --git a/magpie/api/login/esgfopenid.py b/magpie/api/login/esgfopenid.py index c2c97972a..1ba164b00 100644 --- a/magpie/api/login/esgfopenid.py +++ b/magpie/api/login/esgfopenid.py @@ -7,12 +7,12 @@ This providers are dependent on the |python-openid|_ package. """ -import ssl -from six.moves.urllib.request import urlopen +from magpie.utils import get_logger from authomatic.providers.openid import OpenID # noinspection PyProtectedMember, PyUnresolvedReferences from openid.fetchers import Urllib2Fetcher # , setDefaultFetcher -from magpie.common import get_logger +from six.moves.urllib.request import urlopen +import ssl LOGGER = get_logger(__name__) __all__ = ['ESGFOpenID'] diff --git a/magpie/api/login/login.py b/magpie/api/login/login.py index 2fc8ca39c..e9dac9c31 100644 --- a/magpie/api/login/login.py +++ b/magpie/api/login/login.py @@ -30,10 +30,9 @@ from magpie.api.api_requests import get_multiformat_post, get_value_multiformat_post_checked from magpie.api.management.user.user_formats import format_user from magpie.api.management.user.user_utils import create_user -from magpie.common import convert_response, get_logger, JSON_TYPE from magpie.constants import get_constant from magpie.models import User, ExternalIdentity -from magpie.utils import get_magpie_url +from magpie.utils import get_magpie_url, convert_response, get_logger, CONTENT_TYPE_JSON from authomatic.adapters import WebObAdapter from authomatic.core import LoginResult, Credentials, resolve_provider_class from authomatic.exceptions import OAuth2Error @@ -42,50 +41,51 @@ # dictionaries of {'provider_id': 'provider_display_name'} -default_provider = get_constant('MAGPIE_DEFAULT_PROVIDER') +default_provider = get_constant("MAGPIE_DEFAULT_PROVIDER") MAGPIE_INTERNAL_PROVIDERS = {default_provider: default_provider.capitalize()} MAGPIE_EXTERNAL_PROVIDERS = get_provider_names() MAGPIE_PROVIDER_KEYS = list(MAGPIE_INTERNAL_PROVIDERS.keys()) + list(MAGPIE_EXTERNAL_PROVIDERS.keys()) +# FIXME: use provider enum def process_sign_in_external(request, username, provider): provider_name = provider.lower() - if provider_name == 'openid': + if provider_name == "openid": query_field = dict(id=username) - elif provider_name == 'github': + elif provider_name == "github": query_field = None # query_field = dict(login_field=username) - elif provider_name == 'wso2': + elif provider_name == "wso2": query_field = {} else: query_field = dict(username=username) - came_from = request.POST.get('came_from', '/') - request.response.set_cookie('homepage_route', came_from) + came_from = request.POST.get("came_from", "/") + request.response.set_cookie("homepage_route", came_from) external_login_route = request.route_url(s.ProviderSigninAPI.name, provider_name=provider_name, _query=query_field) return HTTPTemporaryRedirect(location=external_login_route, headers=request.response.headers) def verify_provider(provider_name): - ax.verify_param(provider_name, paramName=u'provider_name', paramCompare=MAGPIE_PROVIDER_KEYS, isIn=True, + ax.verify_param(provider_name, paramName=u"provider_name", paramCompare=MAGPIE_PROVIDER_KEYS, isIn=True, httpError=HTTPNotFound, msgOnFail=s.ProviderSignin_GET_NotFoundResponseSchema.description) @s.SigninAPI.post(schema=s.Signin_POST_RequestSchema(), tags=[s.LoginTag], response_schemas=s.Signin_POST_responses) -@view_config(route_name=s.SigninAPI.name, request_method='POST', permission=NO_PERMISSION_REQUIRED) +@view_config(route_name=s.SigninAPI.name, request_method="POST", permission=NO_PERMISSION_REQUIRED) def sign_in(request): """Signs in a user session.""" - provider_name = get_value_multiformat_post_checked(request, 'provider_name', default=default_provider).lower() - user_name = get_value_multiformat_post_checked(request, 'user_name') - password = get_multiformat_post(request, 'password') # no check since password is None for external login + provider_name = get_value_multiformat_post_checked(request, "provider_name", default=default_provider).lower() + user_name = get_value_multiformat_post_checked(request, "user_name") + password = get_multiformat_post(request, "password") # no check since password is None for external login verify_provider(provider_name) if provider_name in MAGPIE_INTERNAL_PROVIDERS.keys(): # obtain the raw path, without any '/magpie' prefix (if any), let 'application_url' handle it - signin_internal_path = request.route_url('ziggurat.routes.sign_in', _app_url='') - signin_internal_data = {u'user_name': user_name, u'password': password, u'provider_name': provider_name} + signin_internal_path = request.route_url("ziggurat.routes.sign_in", _app_url="") + signin_internal_data = {u"user_name": user_name, u"password": password, u"provider_name": provider_name} signin_sub_request = Request.blank(signin_internal_path, base_url=request.application_url, - headers={'Accept': JSON_TYPE}, POST=signin_internal_data) + headers={"Accept": CONTENT_TYPE_JSON}, POST=signin_internal_data) signin_response = request.invoke_subrequest(signin_sub_request) if signin_response.status_code == HTTPOk.code: return convert_response(signin_response) @@ -94,7 +94,7 @@ def sign_in(request): elif provider_name in MAGPIE_EXTERNAL_PROVIDERS.keys(): return ax.evaluate_call(lambda: process_sign_in_external(request, user_name, provider_name), httpError=HTTPInternalServerError, - content={u'user_name': user_name, u'provider_name': provider_name}, + content={u"user_name": user_name, u"provider_name": provider_name}, msgOnFail=s.Signin_POST_InternalServerErrorResponseSchema.description) @@ -102,7 +102,7 @@ def sign_in(request): @view_config(context=ZigguratSignInSuccess, permission=NO_PERMISSION_REQUIRED) def login_success_ziggurat(request): # headers contains login authorization cookie - return ax.valid_http(httpSuccess=HTTPOk, httpKWArgs={'headers': request.context.headers}, + return ax.valid_http(httpSuccess=HTTPOk, httpKWArgs={"headers": request.context.headers}, detail=s.Signin_POST_OkResponseSchema.description) @@ -113,7 +113,7 @@ def login_failure(request, reason=None): if reason is None: http_err = HTTPNotAcceptable reason = s.Signin_POST_NotAcceptableResponseSchema.description - user_name = get_multiformat_post(request, 'user_name', default=None) + user_name = get_multiformat_post(request, "user_name", default=None) if user_name is None: http_err = HTTPBadRequest reason = s.Signin_POST_BadRequestResponseSchema.description @@ -131,9 +131,9 @@ def login_failure(request, reason=None): def new_user_external(external_user_name, external_id, email, provider_name, db_session): """Create new user with an External Identity""" - internal_user_name = external_id + '_' + provider_name - internal_user_name = internal_user_name.replace(" ", '_') - group_name = get_constant('MAGPIE_USERS_GROUP') + internal_user_name = external_id + "_" + provider_name + internal_user_name = internal_user_name.replace(" ", "_") + group_name = get_constant("MAGPIE_USERS_GROUP") create_user(internal_user_name, password=None, email=email, group_name=group_name, db_session=db_session) user = UserService.by_user_name(internal_user_name, db_session=db_session) @@ -142,10 +142,10 @@ def new_user_external(external_user_name, external_id, email, provider_name, db_ local_user_id=user.id, provider_name=provider_name) ax.evaluate_call(lambda: db_session.add(ex_identity), fallback=lambda: db_session.rollback(), httpError=HTTPConflict, msgOnFail=s.Signin_POST_ConflictResponseSchema.description, - content={u'provider_name': str(provider_name), - u'internal_user_name': str(internal_user_name), - u'external_user_name': str(external_user_name), - u'external_id': str(external_id)}) + content={u"provider_name": str(provider_name), + u"internal_user_name": str(internal_user_name), + u"external_user_name": str(external_user_name), + u"external_id": str(external_id)}) user.external_identities.append(ex_identity) return user @@ -161,21 +161,21 @@ def login_success_external(request, external_user_name, external_id, email, prov headers = remember(request, user.id) # redirect to 'Homepage-Route' header only if corresponding to Magpie host - if 'homepage_route' in request.cookies: - homepage_route = str(request.cookies['homepage_route']) - elif 'Homepage-Route' in request.headers: - homepage_route = str(request.headers['Homepage-Route']) + if "homepage_route" in request.cookies: + homepage_route = str(request.cookies["homepage_route"]) + elif "Homepage-Route" in request.headers: + homepage_route = str(request.headers["Homepage-Route"]) else: - homepage_route = '/' + homepage_route = "/" header_host = urlparse(homepage_route).hostname magpie_host = get_magpie_url(request) if header_host and header_host != magpie_host: ax.raise_http(httpError=HTTPForbidden, detail=s.ProviderSignin_GET_ForbiddenResponseSchema.description) if not header_host: - homepage_route = magpie_host + ('/' if not homepage_route.startswith('/') else '') + homepage_route + homepage_route = magpie_host + ("/" if not homepage_route.startswith("/") else "") + homepage_route return ax.valid_http(httpSuccess=HTTPFound, detail=s.ProviderSignin_GET_FoundResponseSchema.description, - content={u'homepage_route': homepage_route}, - httpKWArgs={'location': homepage_route, 'headers': headers}) + content={u"homepage_route": homepage_route}, + httpKWArgs={"location": homepage_route, "headers": headers}) @s.ProviderSigninAPI.get(schema=s.ProviderSignin_GET_RequestSchema, tags=[s.LoginTag], @@ -184,20 +184,20 @@ def login_success_external(request, external_user_name, external_id, email, prov def authomatic_login(request): """Signs in a user session using an external provider.""" - provider_name = request.matchdict.get('provider_name', '').lower() + provider_name = request.matchdict.get("provider_name", "").lower() response = Response() verify_provider(provider_name) try: authomatic_handler = authomatic_setup(request) # if we directly have the Authorization header, bypass authomatic login and retrieve 'userinfo' to signin - if 'Authorization' in request.headers and 'authomatic' not in request.cookies: + if "Authorization" in request.headers and "authomatic" not in request.cookies: provider_config = authomatic_handler.config.get(provider_name, {}) - provider_class = resolve_provider_class(provider_config.get('class_')) + provider_class = resolve_provider_class(provider_config.get("class_")) provider = provider_class(authomatic_handler, adapter=None, provider_name=provider_name) # provide the token user data, let the external provider update it on login afterwards - token_type, access_token = request.headers.get('Authorization').split() - data = {'access_token': access_token, 'token_type': token_type} + token_type, access_token = request.headers.get("Authorization").split() + data = {"access_token": access_token, "token_type": token_type} cred = Credentials(authomatic_handler.config, token=access_token, token_type=token_type, provider=provider) provider.credentials = cred result = LoginResult(provider) @@ -215,7 +215,7 @@ def authomatic_login(request): if result: if result.error: # Login procedure finished with an error. - error = result.error.to_dict() if hasattr(result.error, 'to_dict') else result.error + error = result.error.to_dict() if hasattr(result.error, "to_dict") else result.error LOGGER.debug("Login failure with error. [{!r}]".format(error)) return login_failure(request, reason=result.error.message) elif result.user: @@ -227,7 +227,7 @@ def authomatic_login(request): # this error can happen if providing incorrectly formed authorization header except OAuth2Error as exc: LOGGER.debug("Login failure with Authorization header.") - ax.raise_http(httpError=HTTPBadRequest, content={u'reason': str(exc.message)}, + ax.raise_http(httpError=HTTPBadRequest, content={u"reason": str(exc.message)}, detail=s.ProviderSignin_GET_BadRequestResponseSchema.description) # verify that the update procedure succeeded with provided token if 400 <= response.status < 500: @@ -245,7 +245,7 @@ def authomatic_login(request): LOGGER.exception(exc_msg, exc_info=True) ax.raise_http(httpError=HTTPInternalServerError, detail=exc_msg) - LOGGER.debug('Reached end of login function. Response: {!r}'.format(response)) + LOGGER.debug("Reached end of login function. Response: {!r}".format(response)) return response @@ -253,7 +253,7 @@ def authomatic_login(request): @view_config(context=ZigguratSignOut, permission=NO_PERMISSION_REQUIRED) def sign_out(request): """Signs out the current user session.""" - return ax.valid_http(httpSuccess=HTTPOk, httpKWArgs={'headers': forget(request)}, + return ax.valid_http(httpSuccess=HTTPOk, httpKWArgs={"headers": forget(request)}, detail=s.Signout_GET_OkResponseSchema.description) @@ -266,9 +266,9 @@ def _get_session(req): principals = authn_policy.effective_principals(req) if Authenticated in principals: user = request.user - json_resp = {u'authenticated': True, u'user': format_user(user)} + json_resp = {u"authenticated": True, u"user": format_user(user)} else: - json_resp = {u'authenticated': False} + json_resp = {u"authenticated": False} return json_resp session_json = ax.evaluate_call(lambda: _get_session(request), httpError=HTTPInternalServerError, @@ -278,9 +278,9 @@ def _get_session(req): # noinspection PyUnusedLocal @s.ProvidersAPI.get(tags=[s.LoginTag], response_schemas=s.Providers_GET_responses) -@view_config(route_name=s.ProvidersAPI.name, request_method='GET', permission=NO_PERMISSION_REQUIRED) +@view_config(route_name=s.ProvidersAPI.name, request_method="GET", permission=NO_PERMISSION_REQUIRED) def get_providers(request): """Get list of login providers.""" return ax.valid_http(httpSuccess=HTTPOk, detail=s.Providers_GET_OkResponseSchema.description, - content={u'providers': {u'internal': sorted(MAGPIE_INTERNAL_PROVIDERS.values()), - u'external': sorted(MAGPIE_EXTERNAL_PROVIDERS.values()), }}) + content={u"providers": {u"internal": sorted(MAGPIE_INTERNAL_PROVIDERS.values()), + u"external": sorted(MAGPIE_EXTERNAL_PROVIDERS.values()), }}) diff --git a/magpie/api/login/wso2.py b/magpie/api/login/wso2.py index 9504370bd..2c5231347 100644 --- a/magpie/api/login/wso2.py +++ b/magpie/api/login/wso2.py @@ -1,4 +1,4 @@ -from magpie.common import get_logger +from magpie.utils import get_logger from authomatic.providers.oauth2 import OAuth2 from authomatic.core import SupportedUserAttributes from os import path diff --git a/magpie/api/management/__init__.py b/magpie/api/management/__init__.py index de44f0960..04d26bbf5 100644 --- a/magpie/api/management/__init__.py +++ b/magpie/api/management/__init__.py @@ -1,4 +1,4 @@ -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) diff --git a/magpie/api/management/group/__init__.py b/magpie/api/management/group/__init__.py index e79d9cc01..1affcfc04 100644 --- a/magpie/api/management/group/__init__.py +++ b/magpie/api/management/group/__init__.py @@ -1,5 +1,5 @@ from magpie.api import api_rest_schemas as s -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) diff --git a/magpie/api/management/group/group_utils.py b/magpie/api/management/group/group_utils.py index a19dd274c..3ea2e8d94 100644 --- a/magpie/api/management/group/group_utils.py +++ b/magpie/api/management/group/group_utils.py @@ -1,6 +1,6 @@ -from magpie.services import service_type_dict +from magpie.services import SERVICE_TYPE_DICT from magpie.api import api_except as ax, api_rest_schemas as s -from magpie.api.management.resource.resource_utils import check_valid_service_resource_permission +from magpie.api.management.resource.resource_utils import check_valid_service_or_resource_permission from magpie.api.management.resource.resource_formats import format_resource from magpie.api.management.service.service_formats import format_service_resources, format_service from magpie.api.management.group.group_formats import format_group @@ -75,7 +75,7 @@ def create_group_resource_permission(permission_name, resource, group, db_sessio :returns: corresponding HTTP response according to the encountered situation. """ resource_id = resource.resource_id - check_valid_service_resource_permission(permission_name, resource, db_session) + check_valid_service_or_resource_permission(permission_name, resource, db_session) perm_content = {u'permission_name': str(permission_name), u'resource': format_resource(resource, basic_info=True), u'group': format_group(group, basic_info=True)} @@ -121,7 +121,7 @@ def get_grp_res_perm(grp, db, res_ids, res_types): def get_group_resource_permissions(group, resource, db_session): def get_grp_res_perms(grp, res, db): if res.owner_group_id == grp.id: - perm_names = models.resource_type_dict[res.type].permission_names + perm_names = models.RESOURCE_TYPE_DICT[res.type].permission_names else: grp_res_perm = db.query(models.GroupResourcePermission) \ .filter(models.GroupResourcePermission.resource_id == res.resource_id) \ @@ -136,7 +136,7 @@ def get_grp_res_perms(grp, res, db): def delete_group_resource_permission(permission_name, resource, group, db_session): resource_id = resource.resource_id - check_valid_service_resource_permission(permission_name, resource, db_session) + check_valid_service_or_resource_permission(permission_name, resource, db_session) perm_content = {u'permission_name': str(permission_name), u'resource': format_resource(resource, basic_info=True), u'group': format_group(group, basic_info=True)} @@ -168,7 +168,7 @@ def get_group_services(resources_permissions_dict, db_session): def get_group_service_permissions(group, service, db_session): def get_grp_svc_perms(grp, svc, db): if svc.owner_group_id == grp.id: - perm_names = service_type_dict[svc.type].permission_names + perm_names = SERVICE_TYPE_DICT[svc.type].permission_names else: grp_res_perm = db.query(models.GroupResourcePermission) \ .filter(models.GroupResourcePermission.resource_id == svc.resource_id) \ diff --git a/magpie/api/management/resource/__init__.py b/magpie/api/management/resource/__init__.py index 6492c606e..ce76d02a9 100644 --- a/magpie/api/management/resource/__init__.py +++ b/magpie/api/management/resource/__init__.py @@ -1,5 +1,5 @@ from magpie.api import api_rest_schemas as s -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) diff --git a/magpie/api/management/resource/resource_formats.py b/magpie/api/management/resource/resource_formats.py index 56faf6b49..d20bd5781 100644 --- a/magpie/api/management/resource/resource_formats.py +++ b/magpie/api/management/resource/resource_formats.py @@ -1,7 +1,7 @@ from magpie.definitions.pyramid_definitions import HTTPInternalServerError from magpie.definitions.ziggurat_definitions import ResourceService from magpie.models import resource_tree_service -from magpie.services import service_type_dict +from magpie.services import SERVICE_TYPE_DICT from magpie.api.api_except import evaluate_call @@ -61,13 +61,13 @@ def format_resource_tree(children, db_session, resources_perms_dict=None, intern service_id = resource.resource_id # add to dict only if not already added if service_id not in internal_svc_res_perm_dict: - internal_svc_res_perm_dict[service_id] = service_type_dict[service.type].resource_types_permissions + internal_svc_res_perm_dict[service_id] = SERVICE_TYPE_DICT[service.type].resource_types_permissions # obtain corresponding top-level service resource if not already available else: service_id = resource.root_service_id if service_id not in internal_svc_res_perm_dict: service = ResourceService.by_resource_id(service_id, db_session=db_session) - internal_svc_res_perm_dict[service_id] = service_type_dict[service.type].resource_types_permissions + internal_svc_res_perm_dict[service_id] = SERVICE_TYPE_DICT[service.type].resource_types_permissions perms = internal_svc_res_perm_dict[service_id][resource.resource_type] diff --git a/magpie/api/management/resource/resource_utils.py b/magpie/api/management/resource/resource_utils.py index bf59329c3..0ac3828d3 100644 --- a/magpie/api/management/resource/resource_utils.py +++ b/magpie/api/management/resource/resource_utils.py @@ -1,4 +1,4 @@ -from magpie.services import service_type_dict +from magpie.services import SERVICE_TYPE_DICT from magpie.register import sync_services_phoenix from magpie.definitions.ziggurat_definitions import ResourceService from magpie.definitions.pyramid_definitions import ( @@ -19,23 +19,25 @@ if TYPE_CHECKING: from magpie.definitions.pyramid_definitions import HTTPException # noqa: F401 from magpie.definitions.sqlalchemy_definitions import Session # noqa: F401 - from magpie.definitions.typedefs import Str, Union # noqa: F401 + from magpie.definitions.typedefs import List, Str, Optional # noqa: F401 + from magpie.permissions import Permission # noqa: F401 -def check_valid_service_resource_permission(permission_name, service_resource, db_session): +def check_valid_service_or_resource_permission(permission_name, service_resource, db_session): """ - Checks if a permission is valid to be applied to a specific service or a resource under a specific service. + Checks if a permission is valid to be applied to a specific `service` or a `resource` under a root service. + :param permission_name: permission to apply :param service_resource: resource item corresponding to either a Service or a Resource :param db_session: :return: """ - svc_res_perms = get_resource_permissions(service_resource, db_session=db_session) + svc_res_perm_names = [p.value for p in get_resource_permissions(service_resource, db_session=db_session)] svc_res_type = service_resource.resource_type svc_res_name = service_resource.resource_name - ax.verify_param(permission_name, paramName=u'permission_name', paramCompare=svc_res_perms, isIn=True, + ax.verify_param(permission_name, paramName=u"permission_name", paramCompare=svc_res_perm_names, isIn=True, httpError=HTTPBadRequest, - content={u'resource_type': str(svc_res_type), u'resource_name': str(svc_res_name)}, + content={u"resource_type": str(svc_res_type), u"resource_name": str(svc_res_name)}, msgOnFail=s.UserResourcePermissions_POST_BadRequestResponseSchema.description) @@ -44,33 +46,33 @@ def check_valid_service_resource(parent_resource, resource_type, db_session): Checks if a new Resource can be contained under a parent Resource given the requested type and the corresponding Service under which the parent Resource is already assigned. - :param parent_resource: Resource under which the new Resource of `resource_type` must be placed - :param resource_type: desired Resource type + :param parent_resource: Resource under which the new resource of `resource_type` must be placed + :param resource_type: desired resource type :param db_session: :return: root Service if all checks were successful """ parent_type = parent_resource.resource_type_name - ax.verify_param(models.resource_type_dict[parent_type].child_resource_allowed, isEqual=True, + ax.verify_param(models.RESOURCE_TYPE_DICT[parent_type].child_resource_allowed, isEqual=True, paramCompare=True, httpError=HTTPNotAcceptable, - msgOnFail="Child resource not allowed for specified parent resource type `{}`".format(parent_type)) + msgOnFail="Child resource not allowed for specified parent resource type '{}'".format(parent_type)) root_service = get_resource_root_service(parent_resource, db_session=db_session) ax.verify_param(root_service, notNone=True, httpError=HTTPInternalServerError, - msgOnFail="Failed retrieving `root_service` from db") + msgOnFail="Failed retrieving 'root_service' from db") ax.verify_param(root_service.resource_type, isEqual=True, httpError=HTTPInternalServerError, - paramName=u'resource_type', paramCompare=models.Service.resource_type_name, - msgOnFail="Invalid `root_service` retrieved from db is not a service") - ax.verify_param(service_type_dict[root_service.type].child_resource_allowed, isEqual=True, + paramName=u"resource_type", paramCompare=models.Service.resource_type_name, + msgOnFail="Invalid 'root_service' retrieved from db is not a service") + ax.verify_param(SERVICE_TYPE_DICT[root_service.type].child_resource_allowed, isEqual=True, paramCompare=True, httpError=HTTPNotAcceptable, - msgOnFail="Child resource not allowed for specified service type `{}`".format(root_service.type)) + msgOnFail="Child resource not allowed for specified service type '{}'".format(root_service.type)) ax.verify_param(resource_type, isIn=True, httpError=HTTPNotAcceptable, - paramName=u'resource_type', paramCompare=service_type_dict[root_service.type].resource_types, - msgOnFail="Invalid `resource_type` specified for service type `{}`".format(root_service.type)) + paramName=u"resource_type", paramCompare=SERVICE_TYPE_DICT[root_service.type].resource_types, + msgOnFail="Invalid 'resource_type' specified for service type '{}'".format(root_service.type)) return root_service def crop_tree_with_permission(children, resource_id_list): for child_id, child_dict in list(children.items()): - new_children = child_dict[u'children'] + new_children = child_dict[u"children"] children_returned, resource_id_list = crop_tree_with_permission(new_children, resource_id_list) if child_id not in resource_id_list and not children_returned: children.pop(child_id) @@ -81,47 +83,49 @@ def crop_tree_with_permission(children, resource_id_list): def get_resource_path(resource_id, db_session): parent_resources = models.resource_tree_service.path_upper(resource_id, db_session=db_session) - parent_path = '' + parent_path = "" for parent_resource in parent_resources: - parent_path = '/' + parent_resource.resource_name + parent_path + parent_path = "/" + parent_resource.resource_name + parent_path return parent_path def get_service_or_resource_types(service_resource): if isinstance(service_resource, models.Service): - svc_res_type_obj = service_type_dict[service_resource.type] + svc_res_type_obj = SERVICE_TYPE_DICT[service_resource.type] svc_res_type_str = u"service" elif isinstance(service_resource, models.Resource): - svc_res_type_obj = models.resource_type_dict[service_resource.resource_type] + svc_res_type_obj = models.RESOURCE_TYPE_DICT[service_resource.resource_type] svc_res_type_str = u"resource" else: ax.raise_http(httpError=HTTPInternalServerError, detail="Invalid service/resource object", - content={u'service_resource': repr(type(service_resource))}) + content={u"service_resource": repr(type(service_resource))}) # noinspection PyUnboundLocalVariable return svc_res_type_obj, svc_res_type_str def get_resource_permissions(resource, db_session): - ax.verify_param(resource, notNone=True, httpError=HTTPNotAcceptable, paramName=u'resource', + # type: (models.Resource, Session) -> List[Permission] + ax.verify_param(resource, notNone=True, httpError=HTTPNotAcceptable, paramName=u"resource", msgOnFail=s.UserResourcePermissions_GET_NotAcceptableResourceResponseSchema.description) # directly access the service resource if resource.root_service_id is None: service = resource - return service_type_dict[service.type].permission_names + return SERVICE_TYPE_DICT[service.type].permission_names # otherwise obtain root level service to infer sub-resource permissions service = ResourceService.by_resource_id(resource.root_service_id, db_session=db_session) ax.verify_param(service.resource_type, isEqual=True, httpError=HTTPNotAcceptable, - paramName=u'resource_type', paramCompare=models.Service.resource_type_name, + paramName=u"resource_type", paramCompare=models.Service.resource_type_name, msgOnFail=s.UserResourcePermissions_GET_NotAcceptableRootServiceResponseSchema.description) - service_obj = service_type_dict[service.type] + service_obj = SERVICE_TYPE_DICT[service.type] ax.verify_param(resource.resource_type, isIn=True, httpError=HTTPNotAcceptable, - paramName=u'resource_type', paramCompare=service_obj.resource_types, + paramName=u"resource_type", paramCompare=service_obj.resource_types, msgOnFail=s.UserResourcePermissions_GET_NotAcceptableResourceTypeResponseSchema.description) return service_obj.resource_types_permissions[resource.resource_type] def get_resource_root_service(resource, db_session): + # type: (models.Resource, Session) -> Optional[models.Resource] """ Recursively rewinds back through the top of the resource tree up to the top-level service-resource. @@ -138,18 +142,18 @@ def get_resource_root_service(resource, db_session): def create_resource(resource_name, resource_display_name, resource_type, parent_id, db_session): - # type: (Str, Union[Str, None], Str, int, Session) -> HTTPException - ax.verify_param(resource_name, paramName=u'resource_name', notNone=True, notEmpty=True, httpError=HTTPBadRequest, - msgOnFail="Invalid `resource_name` specified for child resource creation.") - ax.verify_param(resource_type, paramName=u'resource_type', notNone=True, notEmpty=True, httpError=HTTPBadRequest, - msgOnFail="Invalid `resource_type` specified for child resource creation.") - ax.verify_param(parent_id, paramName=u'parent_id', notNone=True, notEmpty=True, paramCompare=int, ofType=True, + # type: (Str, Optional[Str], Str, int, Session) -> HTTPException + ax.verify_param(resource_name, paramName=u"resource_name", notNone=True, notEmpty=True, httpError=HTTPBadRequest, + msgOnFail="Invalid 'resource_name' specified for child resource creation.") + ax.verify_param(resource_type, paramName=u"resource_type", notNone=True, notEmpty=True, httpError=HTTPBadRequest, + msgOnFail="Invalid 'resource_type' specified for child resource creation.") + ax.verify_param(parent_id, paramName=u"parent_id", notNone=True, notEmpty=True, paramCompare=int, ofType=True, httpError=HTTPBadRequest, msgOnFail="Invalid `parent_id` specified for child resource creation.") parent_resource = ax.evaluate_call(lambda: ResourceService.by_resource_id(parent_id, db_session=db_session), fallback=lambda: db_session.rollback(), httpError=HTTPNotFound, msgOnFail=s.Resources_POST_NotFoundResponseSchema.description, - content={u'parent_id': str(parent_id), u'resource_name': str(resource_name), - u'resource_type': str(resource_type)}) + content={u"parent_id": str(parent_id), u"resource_name": str(resource_name), + u"resource_type": str(resource_type)}) # verify for valid permissions from top-level service-specific corresponding resources permissions root_service = check_valid_service_resource(parent_resource, resource_type, db_session) diff --git a/magpie/api/management/resource/resource_views.py b/magpie/api/management/resource/resource_views.py index 102844404..2b2de5125 100644 --- a/magpie/api/management/resource/resource_views.py +++ b/magpie/api/management/resource/resource_views.py @@ -11,7 +11,7 @@ HTTPInternalServerError, ) from magpie.register import sync_services_phoenix -from magpie.services import service_type_dict +from magpie.services import SERVICE_TYPE_DICT from magpie import models @@ -20,7 +20,7 @@ def get_resources_view(request): """List all registered resources.""" res_json = {} - for svc_type in service_type_dict.keys(): + for svc_type in SERVICE_TYPE_DICT.keys(): services = get_services_by_type(svc_type, db_session=request.db) res_json[svc_type] = {} for svc in services: diff --git a/magpie/api/management/service/__init__.py b/magpie/api/management/service/__init__.py index 58f382727..6473c8f25 100644 --- a/magpie/api/management/service/__init__.py +++ b/magpie/api/management/service/__init__.py @@ -1,5 +1,5 @@ from magpie.api import api_rest_schemas as s -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) diff --git a/magpie/api/management/service/service_formats.py b/magpie/api/management/service/service_formats.py index e5dffdbac..8938a7e24 100644 --- a/magpie/api/management/service/service_formats.py +++ b/magpie/api/management/service/service_formats.py @@ -3,17 +3,18 @@ from magpie.api.management.resource.resource_formats import get_resource_children, format_resource_tree from magpie.definitions.pyramid_definitions import HTTPInternalServerError from magpie.utils import get_twitcher_protected_service_url -from magpie.services import service_type_dict +from magpie.services import SERVICE_TYPE_DICT from typing import TYPE_CHECKING if TYPE_CHECKING: - from magpie.definitions.typedefs import Optional, JsonBody, AnyStr, Dict, List # noqa: F401 + from magpie.definitions.typedefs import Optional, JSON, AnyStr, Dict, List # noqa: F401 from magpie.definitions.sqlalchemy_definitions import Session # noqa: F401 from magpie.models import Resource, Service # noqa: F401 - from magpie.services import ServiceI # noqa: F401 + from magpie.permissions import Permission + from magpie.services import ServiceInterface # noqa: F401 def format_service(service, permissions=None, show_private_url=False, show_resources_allowed=False): - # type: (Service, Optional[bool], Optional[bool], Optional[bool]) -> JsonBody + # type: (Service, Optional[Permission], Optional[bool], Optional[bool]) -> JSON def fmt_svc(svc, perms): svc_info = { u'public_url': str(get_twitcher_protected_service_url(svc.resource_name)), @@ -21,13 +22,14 @@ def fmt_svc(svc, perms): u'service_type': str(svc.type), u'service_sync_type': str(svc.sync_type) if svc.sync_type is not None else svc.sync_type, u'resource_id': svc.resource_id, - u'permission_names': sorted(service_type_dict[svc.type].permission_names if perms is None else perms) + u'permission_names': sorted(SERVICE_TYPE_DICT[svc.type].permissions + if perms is None else [p.value for p in perms]) } if show_private_url: svc_info[u'service_url'] = str(svc.url) if show_resources_allowed: - svc_info[u'resource_types_allowed'] = sorted(service_type_dict[svc.type].resource_types) - svc_info[u'resource_child_allowed'] = service_type_dict[svc.type].child_resource_allowed + svc_info[u'resource_types_allowed'] = sorted(SERVICE_TYPE_DICT[svc.type].resource_types) + svc_info[u'resource_child_allowed'] = SERVICE_TYPE_DICT[svc.type].child_resource_allowed return svc_info return evaluate_call( @@ -44,7 +46,7 @@ def format_service_resources(service, # type: Service resources_perms_dict=None, # type: Optional[Dict[AnyStr, List[AnyStr]]] show_all_children=False, # type: Optional[bool] show_private_url=True, # type: Optional[bool] - ): # type: (...) -> JsonBody + ): # type: (...) -> JSON """ Formats the service and its resource tree as a JSON body. @@ -61,7 +63,7 @@ def fmt_svc_res(svc, db, svc_perms, res_perms, show_all): if not show_all: tree, resource_id_list_remain = crop_tree_with_permission(tree, list(res_perms.keys())) - svc_perms = service_type_dict[svc.type].permission_names if svc_perms is None else svc_perms + svc_perms = SERVICE_TYPE_DICT[svc.type].permission_names if svc_perms is None else svc_perms svc_res = format_service(svc, svc_perms, show_private_url=show_private_url) svc_res[u'resources'] = format_resource_tree(tree, resources_perms_dict=res_perms, db_session=db) return svc_res @@ -75,7 +77,7 @@ def fmt_svc_res(svc, db, svc_perms, res_perms, show_all): def format_service_resource_type(resource_type, service_type): - # type: (Resource, ServiceI) -> JsonBody + # type: (Resource, ServiceInterface) -> JSON return { u'resource_type': resource_type.resource_type_name, u'resource_child_allowed': resource_type.child_resource_allowed, diff --git a/magpie/api/management/service/service_utils.py b/magpie/api/management/service/service_utils.py index b74ab63a1..c2ce12617 100644 --- a/magpie/api/management/service/service_utils.py +++ b/magpie/api/management/service/service_utils.py @@ -2,7 +2,6 @@ from magpie.api.management.group.group_utils import create_group_resource_permission from magpie.api.management.service.service_formats import format_service from magpie.constants import get_constant -from magpie.common import get_logger from magpie.definitions.pyramid_definitions import ( HTTPCreated, HTTPForbidden, @@ -11,7 +10,8 @@ ) from magpie.definitions.ziggurat_definitions import GroupService, ResourceService from magpie.register import sync_services_phoenix, SERVICES_PHOENIX_ALLOWED -from magpie.services import service_type_dict +from magpie.services import SERVICE_TYPE_DICT +from magpie.utils import get_logger from magpie import models from typing import TYPE_CHECKING if TYPE_CHECKING: @@ -70,7 +70,7 @@ def get_services_by_type(service_type, db_session): def add_service_getcapabilities_perms(service, db_session, group_name=None): if service.type in SERVICES_PHOENIX_ALLOWED \ - and 'getcapabilities' in service_type_dict[service.type].permission_names: # noqa: F401 + and 'getcapabilities' in SERVICE_TYPE_DICT[service.type].permission_names: # noqa: F401 if group_name is None: group_name = get_constant('MAGPIE_ANONYMOUS_USER') group = GroupService.by_group_name(group_name, db_session=db_session) diff --git a/magpie/api/management/service/service_views.py b/magpie/api/management/service/service_views.py index 1c5e133cc..63a3f4eff 100644 --- a/magpie/api/management/service/service_views.py +++ b/magpie/api/management/service/service_views.py @@ -11,44 +11,45 @@ HTTPNotAcceptable, HTTPConflict, ) -from magpie.common import JSON_TYPE +from magpie.permissions import Permission from magpie.register import sync_services_phoenix, SERVICES_PHOENIX_ALLOWED -from magpie.services import service_type_dict +from magpie.services import SERVICE_TYPE_DICT +from magpie.utils import CONTENT_TYPE_JSON from magpie import models # noinspection PyUnusedLocal @s.ServiceTypesAPI.get(tags=[s.ServicesTag], response_schemas=s.ServiceTypes_GET_responses) -@view_config(route_name=s.ServiceTypesAPI.name, request_method='GET') +@view_config(route_name=s.ServiceTypesAPI.name, request_method="GET") def get_service_types_view(request): """List all available service types.""" - return ax.valid_http(httpSuccess=HTTPOk, content={u'service_types': list(sorted(service_type_dict.keys()))}, + return ax.valid_http(httpSuccess=HTTPOk, content={u"service_types": list(sorted(SERVICE_TYPE_DICT.keys()))}, detail=s.ServiceTypes_GET_OkResponseSchema.description) @s.ServiceTypeAPI.get(tags=[s.ServicesTag], response_schemas=s.ServiceType_GET_responses) -@view_config(route_name=s.ServiceTypeAPI.name, request_method='GET') +@view_config(route_name=s.ServiceTypeAPI.name, request_method="GET") def get_services_by_type_view(request): """List all registered services from a specific type.""" return get_services_runner(request) @s.ServicesAPI.get(tags=[s.ServicesTag], response_schemas=s.Services_GET_responses) -@view_config(route_name=s.ServicesAPI.name, request_method='GET') +@view_config(route_name=s.ServicesAPI.name, request_method="GET") def get_services_view(request): """List all registered services.""" return get_services_runner(request) def get_services_runner(request): - service_type_filter = request.matchdict.get('service_type') # no check because None/empty is for 'all services' + service_type_filter = request.matchdict.get("service_type") # no check because None/empty is for 'all services' json_response = {} if not service_type_filter: - service_types = service_type_dict.keys() + service_types = SERVICE_TYPE_DICT.keys() else: - ax.verify_param(service_type_filter, paramCompare=service_type_dict.keys(), isIn=True, + ax.verify_param(service_type_filter, paramCompare=SERVICE_TYPE_DICT.keys(), isIn=True, httpError=HTTPNotAcceptable, msgOnFail=s.Services_GET_NotAcceptableResponseSchema.description, - content={u'service_type': str(service_type_filter)}, contentType=JSON_TYPE) + content={u"service_type": str(service_type_filter)}, contentType=CONTENT_TYPE_JSON) service_types = [service_type_filter] for service_type in service_types: @@ -57,43 +58,43 @@ def get_services_runner(request): for service in services: json_response[service_type][service.resource_name] = sf.format_service(service, show_private_url=True) - return ax.valid_http(httpSuccess=HTTPOk, content={u'services': json_response}, + return ax.valid_http(httpSuccess=HTTPOk, content={u"services": json_response}, detail=s.Services_GET_OkResponseSchema.description) @s.ServicesAPI.post(schema=s.Services_POST_RequestBodySchema(), tags=[s.ServicesTag], response_schemas=s.Services_POST_responses) -@view_config(route_name=s.ServicesAPI.name, request_method='POST') +@view_config(route_name=s.ServicesAPI.name, request_method="POST") def register_service_view(request): """Registers a new service.""" - service_name = ar.get_value_multiformat_post_checked(request, 'service_name') - service_url = ar.get_value_multiformat_post_checked(request, 'service_url') - service_type = ar.get_value_multiformat_post_checked(request, 'service_type') - service_push = asbool(ar.get_multiformat_post(request, 'service_push')) - ax.verify_param(service_type, isIn=True, paramCompare=service_type_dict.keys(), + service_name = ar.get_value_multiformat_post_checked(request, "service_name") + service_url = ar.get_value_multiformat_post_checked(request, "service_url") + service_type = ar.get_value_multiformat_post_checked(request, "service_type") + service_push = asbool(ar.get_multiformat_post(request, "service_push")) + ax.verify_param(service_type, isIn=True, paramCompare=SERVICE_TYPE_DICT.keys(), httpError=HTTPBadRequest, msgOnFail=s.Services_POST_BadRequestResponseSchema.description) ax.verify_param(models.Service.by_service_name(service_name, db_session=request.db), isNone=True, httpError=HTTPConflict, msgOnFail=s.Services_POST_ConflictResponseSchema.description, - content={u'service_name': str(service_name)}, paramName=u'service_name') + content={u"service_name": str(service_name)}, paramName=u"service_name") return su.create_service(service_name, service_type, service_url, service_push, db_session=request.db) @s.ServiceAPI.put(schema=s.Service_PUT_RequestBodySchema(), tags=[s.ServicesTag], response_schemas=s.Service_PUT_responses) -@view_config(route_name=s.ServiceAPI.name, request_method='PUT') +@view_config(route_name=s.ServiceAPI.name, request_method="PUT") def update_service_view(request): """Update a service information.""" service = ar.get_service_matchdict_checked(request) - service_push = asbool(ar.get_multiformat_post(request, 'service_push', default=False)) + service_push = asbool(ar.get_multiformat_post(request, "service_push", default=False)) def select_update(new_value, old_value): - return new_value if new_value is not None and not new_value == '' else old_value + return new_value if new_value is not None and not new_value == "" else old_value # None/Empty values are accepted in case of unspecified - svc_name = select_update(ar.get_multiformat_post(request, 'service_name'), service.resource_name) - svc_url = select_update(ar.get_multiformat_post(request, 'service_url'), service.url) - ax.verify_param(svc_name, paramCompare='types', notEqual=True, - paramName='service_name', httpError=HTTPBadRequest, + svc_name = select_update(ar.get_multiformat_post(request, "service_name"), service.resource_name) + svc_url = select_update(ar.get_multiformat_post(request, "service_url"), service.url) + ax.verify_param(svc_name, paramCompare="types", notEqual=True, + paramName="service_name", httpError=HTTPBadRequest, msgOnFail=s.Service_PUT_BadRequestResponseSchema_ReservedKeyword.description) ax.verify_param(svc_name == service.resource_name and svc_url == service.url, notEqual=True, paramCompare=True, paramName="service_name/service_url", @@ -101,34 +102,34 @@ def select_update(new_value, old_value): if svc_name != service.resource_name: all_svc_names = list() - for svc_type in service_type_dict: + for svc_type in SERVICE_TYPE_DICT: for svc in su.get_services_by_type(svc_type, db_session=request.db): all_svc_names.append(svc.resource_name) ax.verify_param(svc_name, notIn=True, paramCompare=all_svc_names, httpError=HTTPConflict, msgOnFail=s.Service_PUT_ConflictResponseSchema.description, - content={u'service_name': str(svc_name)}) + content={u"service_name": str(svc_name)}) def update_service_magpie_and_phoenix(_svc, new_name, new_url, svc_push, db_session): _svc.resource_name = new_name _svc.url = new_url - has_getcap = 'getcapabilities' in service_type_dict[_svc.type].permission_names + has_getcap = Permission.GET_CAPABILITIES in SERVICE_TYPE_DICT[_svc.type].permissions if svc_push and svc.type in SERVICES_PHOENIX_ALLOWED and has_getcap: # (re)apply getcapabilities to updated service to ensure updated push su.add_service_getcapabilities_perms(_svc, db_session) sync_services_phoenix(db_session.query(models.Service)) # push all services old_svc_content = sf.format_service(service, show_private_url=True) - err_svc_content = {u'service': old_svc_content, u'new_service_name': svc_name, u'new_service_url': svc_url} + err_svc_content = {u"service": old_svc_content, u"new_service_name": svc_name, u"new_service_url": svc_url} ax.evaluate_call(lambda: update_service_magpie_and_phoenix(service, svc_name, svc_url, service_push, request.db), fallback=lambda: request.db.rollback(), httpError=HTTPForbidden, msgOnFail=s.Service_PUT_ForbiddenResponseSchema.description, content=err_svc_content) return ax.valid_http(httpSuccess=HTTPOk, detail=s.Service_PUT_OkResponseSchema.description, - content={u'service': sf.format_service(service, show_private_url=True)}) + content={u"service": sf.format_service(service, show_private_url=True)}) @s.ServiceAPI.get(tags=[s.ServicesTag], response_schemas=s.Service_GET_responses) -@view_config(route_name=s.ServiceAPI.name, request_method='GET') +@view_config(route_name=s.ServiceAPI.name, request_method="GET") def get_service_view(request): """Get a service information.""" service = ar.get_service_matchdict_checked(request) @@ -139,11 +140,11 @@ def get_service_view(request): @s.ServiceAPI.delete(schema=s.Service_DELETE_RequestSchema(), tags=[s.ServicesTag], response_schemas=s.Service_DELETE_responses) -@view_config(route_name=s.ServiceAPI.name, request_method='DELETE') +@view_config(route_name=s.ServiceAPI.name, request_method="DELETE") def unregister_service_view(request): """Unregister a service.""" service = ar.get_service_matchdict_checked(request) - service_push = asbool(ar.get_multiformat_delete(request, 'service_push', default=False)) + service_push = asbool(ar.get_multiformat_delete(request, "service_push", default=False)) svc_content = sf.format_service(service, show_private_url=True) svc_res_id = service.resource_id ax.evaluate_call(lambda: models.resource_tree_service.delete_branch(resource_id=svc_res_id, db_session=request.db), @@ -167,7 +168,7 @@ def get_service_permissions_view(request): """List all applicable permissions for a service.""" service = ar.get_service_matchdict_checked(request) svc_content = sf.format_service(service, show_private_url=True) - svc_perms = ax.evaluate_call(lambda: service_type_dict[service.type].permission_names, + svc_perms = ax.evaluate_call(lambda: SERVICE_TYPE_DICT[service.type].permission_names, fallback=request.db.rollback(), httpError=HTTPNotAcceptable, content=svc_content, msgOnFail=s.ServicePermissions_GET_NotAcceptableResponseSchema.description) return ax.valid_http(httpSuccess=HTTPOk, detail=s.ServicePermissions_GET_OkResponseSchema.description, @@ -176,33 +177,33 @@ def get_service_permissions_view(request): @s.ServiceResourceAPI.delete(schema=s.ServiceResource_DELETE_RequestSchema(), tags=[s.ServicesTag], response_schemas=s.ServiceResource_DELETE_responses) -@view_config(route_name=s.ServiceResourceAPI.name, request_method='DELETE') +@view_config(route_name=s.ServiceResourceAPI.name, request_method="DELETE") def delete_service_resource_view(request): """Unregister a resource.""" return delete_resource(request) @s.ServiceResourcesAPI.get(tags=[s.ServicesTag], response_schemas=s.ServiceResources_GET_responses) -@view_config(route_name=s.ServiceResourcesAPI.name, request_method='GET') +@view_config(route_name=s.ServiceResourcesAPI.name, request_method="GET") def get_service_resources_view(request): """List all resources registered under a service.""" service = ar.get_service_matchdict_checked(request) svc_res_json = sf.format_service_resources(service, db_session=request.db, show_all_children=True, show_private_url=True) - return ax.valid_http(httpSuccess=HTTPOk, content={svc_res_json['service_name']: svc_res_json}, + return ax.valid_http(httpSuccess=HTTPOk, content={svc_res_json["service_name"]: svc_res_json}, detail=s.ServiceResources_GET_OkResponseSchema.description) @s.ServiceResourcesAPI.post(schema=s.ServiceResources_POST_RequestSchema, tags=[s.ServicesTag], response_schemas=s.ServiceResources_POST_responses) -@view_config(route_name=s.ServiceResourcesAPI.name, request_method='POST') +@view_config(route_name=s.ServiceResourcesAPI.name, request_method="POST") def create_service_direct_resource_view(request): """Register a new resource directly under a service.""" service = ar.get_service_matchdict_checked(request) - resource_name = ar.get_multiformat_post(request, 'resource_name') - resource_display_name = ar.get_multiformat_post(request, 'resource_display_name', default=resource_name) - resource_type = ar.get_multiformat_post(request, 'resource_type') - parent_id = ar.get_multiformat_post(request, 'parent_id') # no check because None/empty is allowed + resource_name = ar.get_multiformat_post(request, "resource_name") + resource_display_name = ar.get_multiformat_post(request, "resource_display_name", default=resource_name) + resource_type = ar.get_multiformat_post(request, "resource_type") + parent_id = ar.get_multiformat_post(request, "parent_id") # no check because None/empty is allowed if not parent_id: parent_id = service.resource_id return create_resource(resource_name, resource_display_name, resource_type, @@ -210,34 +211,34 @@ def create_service_direct_resource_view(request): @s.ServiceTypeResourcesAPI.get(tags=[s.ServicesTag], response_schemas=s.ServiceTypeResources_GET_responses) -@view_config(route_name=s.ServiceTypeResourcesAPI.name, request_method='GET') +@view_config(route_name=s.ServiceTypeResourcesAPI.name, request_method="GET") def get_service_type_resources_view(request): """List details of resource types supported under a specific service type.""" def _get_resource_types_info(res_type_names): - res_type_classes = [r for rt, r in models.resource_type_dict.items() if rt in res_type_names] - return [sf.format_service_resource_type(r, service_type_dict[service_type]) for r in res_type_classes] + res_type_classes = [r for rt, r in models.RESOURCE_TYPE_DICT.items() if rt in res_type_names] + return [sf.format_service_resource_type(r, SERVICE_TYPE_DICT[service_type]) for r in res_type_classes] - service_type = ar.get_value_matchdict_checked(request, 'service_type') - ax.verify_param(service_type, paramCompare=service_type_dict.keys(), isIn=True, httpError=HTTPNotFound, + service_type = ar.get_value_matchdict_checked(request, "service_type") + ax.verify_param(service_type, paramCompare=SERVICE_TYPE_DICT.keys(), isIn=True, httpError=HTTPNotFound, msgOnFail=s.ServiceTypeResources_GET_NotFoundResponseSchema.description) resource_types_names = ax.evaluate_call( - lambda: service_type_dict[service_type].resource_types, - httpError=HTTPForbidden, content={u'service_type': str(service_type)}, + lambda: SERVICE_TYPE_DICT[service_type].resource_types, + httpError=HTTPForbidden, content={u"service_type": str(service_type)}, msgOnFail=s.ServiceTypeResourceTypes_GET_ForbiddenResponseSchema.description) return ax.valid_http(httpSuccess=HTTPOk, detail=s.ServiceTypeResourceTypes_GET_OkResponseSchema.description, - content={u'resource_types': _get_resource_types_info(resource_types_names)}) + content={u"resource_types": _get_resource_types_info(resource_types_names)}) @s.ServiceTypeResourceTypesAPI.get(tags=[s.ServicesTag], response_schemas=s.ServiceTypeResourceTypes_GET_responses) -@view_config(route_name=s.ServiceTypeResourceTypesAPI.name, request_method='GET') +@view_config(route_name=s.ServiceTypeResourceTypesAPI.name, request_method="GET") def get_service_type_resource_types_view(request): """List all resource types supported under a specific service type.""" - service_type = ar.get_value_matchdict_checked(request, 'service_type') - ax.verify_param(service_type, paramCompare=service_type_dict.keys(), isIn=True, httpError=HTTPNotFound, + service_type = ar.get_value_matchdict_checked(request, "service_type") + ax.verify_param(service_type, paramCompare=SERVICE_TYPE_DICT.keys(), isIn=True, httpError=HTTPNotFound, msgOnFail=s.ServiceTypeResourceTypes_GET_NotFoundResponseSchema.description) - resource_types = ax.evaluate_call(lambda: service_type_dict[service_type].resource_types, - httpError=HTTPForbidden, content={u'service_type': str(service_type)}, + resource_types = ax.evaluate_call(lambda: SERVICE_TYPE_DICT[service_type].resource_types, + httpError=HTTPForbidden, content={u"service_type": str(service_type)}, msgOnFail=s.ServiceTypeResourceTypes_GET_ForbiddenResponseSchema.description) return ax.valid_http(httpSuccess=HTTPOk, detail=s.ServiceTypeResourceTypes_GET_OkResponseSchema.description, - content={u'resource_types': resource_types}) + content={u"resource_types": resource_types}) diff --git a/magpie/api/management/user/__init__.py b/magpie/api/management/user/__init__.py index 334174bde..f8b750cf3 100644 --- a/magpie/api/management/user/__init__.py +++ b/magpie/api/management/user/__init__.py @@ -1,5 +1,5 @@ from magpie.api import api_rest_schemas as s -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) diff --git a/magpie/api/management/user/user_utils.py b/magpie/api/management/user/user_utils.py index 18db8800a..4a8230716 100644 --- a/magpie/api/management/user/user_utils.py +++ b/magpie/api/management/user/user_utils.py @@ -1,6 +1,6 @@ from magpie.api import api_except as ax, api_rest_schemas as s from magpie.api.management.service.service_formats import format_service -from magpie.api.management.resource.resource_utils import check_valid_service_resource_permission +from magpie.api.management.resource.resource_utils import check_valid_service_or_resource_permission from magpie.api.management.user import user_formats as uf from magpie.constants import get_constant from magpie.definitions.ziggurat_definitions import ( @@ -22,14 +22,14 @@ from magpie import models from typing import TYPE_CHECKING if TYPE_CHECKING: - from magpie.services import ResourcePermissionType, ServiceI # noqa: F401 + from magpie.services import ResourcePermissionType, ServiceInterface # noqa: F401 from magpie.definitions.pyramid_definitions import Request, HTTPException # noqa: F401 from magpie.definitions.sqlalchemy_definitions import Session # noqa: F401 - from magpie.definitions.typedefs import Any, Str, Dict, List, Optional, Union, UserServicesType # noqa: F401 + from magpie.definitions.typedefs import Any, Str, Dict, List, Optional, UserServicesType # noqa: F401 def create_user(user_name, password, email, group_name, db_session): - # type: (Str, Union[Str, None], Str, Str, Session) -> HTTPException + # type: (Str, Optional[Str], Str, Str, Session) -> HTTPException """ Creates a user if it is permitted and not conflicting. Password must be set to `None` if using external identity. @@ -68,7 +68,7 @@ def create_user(user_name, password, email, group_name, db_session): httpError=HTTPForbidden, msgOnFail=s.UserGroup_GET_ForbiddenResponseSchema.description) return ax.valid_http(httpSuccess=HTTPCreated, detail=s.Users_POST_CreatedResponseSchema.description, - content={u'user': uf.format_user(new_user, [group_name])}) + content={u"user": uf.format_user(new_user, [group_name])}) def create_user_resource_permission(permission_name, resource, user, db_session): @@ -77,19 +77,19 @@ def create_user_resource_permission(permission_name, resource, user, db_session) Creates a permission on a user/resource combination if it is permitted and not conflicting. :returns: corresponding HTTP response according to the encountered situation. """ - check_valid_service_resource_permission(permission_name, resource, db_session) + check_valid_service_or_resource_permission(permission_name, resource, db_session) resource_id = resource.resource_id existing_perm = UserResourcePermissionService.by_resource_user_and_perm( user_id=user.id, resource_id=resource_id, perm_name=permission_name, db_session=db_session) ax.verify_param(existing_perm, isNone=True, httpError=HTTPConflict, - content={u'resource_id': resource_id, u'user_id': user.id, u'permission_name': permission_name}, + content={u"resource_id": resource_id, u"user_id": user.id, u"permission_name": permission_name}, msgOnFail=s.UserResourcePermissions_POST_ConflictResponseSchema.description) # noinspection PyArgumentList new_perm = models.UserResourcePermission(resource_id=resource_id, user_id=user.id, perm_name=permission_name) - usr_res_data = {u'resource_id': resource_id, u'user_id': user.id, u'permission_name': permission_name} + usr_res_data = {u"resource_id": resource_id, u"user_id": user.id, u"permission_name": permission_name} ax.verify_param(new_perm, notNone=True, httpError=HTTPNotAcceptable, - content={u'resource_id': resource_id, u'user_id': user.id}, + content={u"resource_id": resource_id, u"user_id": user.id}, msgOnFail=s.UserResourcePermissions_POST_NotAcceptableResponseSchema.description) ax.evaluate_call(lambda: db_session.add(new_perm), fallback=lambda: db_session.rollback(), httpError=HTTPForbidden, content=usr_res_data, @@ -100,18 +100,18 @@ def create_user_resource_permission(permission_name, resource, user, db_session) def delete_user_resource_permission(permission_name, resource, user, db_session): # type: (Str, models.Resource, models.User, Session) -> HTTPException - check_valid_service_resource_permission(permission_name, resource, db_session) + check_valid_service_or_resource_permission(permission_name, resource, db_session) resource_id = resource.resource_id del_perm = UserResourcePermissionService.get(user.id, resource_id, permission_name, db_session) ax.evaluate_call(lambda: db_session.delete(del_perm), fallback=lambda: db_session.rollback(), httpError=HTTPNotFound, msgOnFail=s.UserResourcePermissions_DELETE_NotFoundResponseSchema.description, - content={u'resource_id': resource_id, u'user_id': user.id, u'permission_name': permission_name}) + content={u"resource_id": resource_id, u"user_id": user.id, u"permission_name": permission_name}) return ax.valid_http(httpSuccess=HTTPOk, detail=s.UserResourcePermissions_DELETE_OkResponseSchema.description) def get_resource_root_service(resource, request): - # type: (models.Resource, Request) -> ServiceI + # type: (models.Resource, Request) -> ServiceInterface """Retrieves the service class corresponding to the specified resource's root service-resource.""" if resource.resource_type == models.Service.resource_type_name: res_root_svc = resource @@ -135,7 +135,7 @@ def get_user_resource_permissions(user, resource, request, Alternatively retrieves the effective user resource permissions, where group permissions are implied as `True`. """ if resource.owner_user_id == user.id: - permission_names = models.resource_type_dict[resource.type].permission_names + permission_names = [p.value for p in models.RESOURCE_TYPE_DICT[resource.type].permissions] else: db_session = request.db if effective_permissions: @@ -151,7 +151,7 @@ def get_user_resource_permissions(user, resource, request, def get_user_services(user, request, cascade_resources=False, inherit_groups_permissions=False, format_as_list=False): - # type: (models.User, Request, Optional[bool], Optional[bool], Optional[bool]) -> UserServicesType + # type: (models.User, Request, bool, bool, bool) -> UserServicesType """ Returns services by type with corresponding services by name containing sub-dict information. @@ -171,16 +171,16 @@ def get_user_services(user, request, cascade_resources=False, unless `format_as_dict` is `True` """ db_session = request.db - resource_type = None if cascade_resources else ['service'] + resource_type = None if cascade_resources else [models.Service.resource_type] res_perm_dict = get_user_resources_permissions_dict(user, resource_types=resource_type, request=request, inherit_groups_permissions=inherit_groups_permissions) services = {} for resource_id, perms in res_perm_dict.items(): svc = ResourceService.by_resource_id(resource_id=resource_id, db_session=db_session) - if svc.resource_type != 'service' and cascade_resources: + if svc.resource_type != models.Service.resource_type and cascade_resources: svc = get_resource_root_service(svc, request) - perms = svc.permission_names + perms = svc.permissions if svc.type not in services: services[svc.type] = {} if svc.resource_name not in services[svc.type]: @@ -197,9 +197,9 @@ def get_user_services(user, request, cascade_resources=False, def get_user_service_permissions(user, service, request, inherit_groups_permissions=True): - # type: (models.User, models.Service, Request, Optional[bool]) -> List[Str] + # type: (models.User, models.Service, Request, bool) -> List[Str] if service.owner_user_id == user.id: - permission_names = service_factory(service, request).permission_names + permission_names = [p.value for p in service_factory(service, request).permissions] else: svc_perm_tuple_list = ResourceService.perms_for_user(service, user, db_session=request.db) if not inherit_groups_permissions: @@ -210,7 +210,7 @@ def get_user_service_permissions(user, service, request, inherit_groups_permissi def get_user_resources_permissions_dict(user, request, resource_types=None, resource_ids=None, inherit_groups_permissions=True): - # type: (models.User, Request, Optional[List[Str]], Optional[List[int]], Optional[bool]) -> Dict[Str, Any] + # type: (models.User, Request, Optional[List[Str]], Optional[List[int]], bool) -> Dict[Str, Any] """ Creates a dictionary of resources by id with corresponding permissions of the user. @@ -255,19 +255,19 @@ def get_user_service_resources_permissions_dict(user, service, request, inherit_ def check_user_info(user_name, email, password, group_name): # type: (Str, Str, Str, Str) -> None ax.verify_param(user_name, notNone=True, notEmpty=True, httpError=HTTPBadRequest, - paramName=u'user_name', msgOnFail=s.Users_CheckInfo_Name_BadRequestResponseSchema.description) + paramName=u"user_name", msgOnFail=s.Users_CheckInfo_Name_BadRequestResponseSchema.description) ax.verify_param(len(user_name), isIn=True, httpError=HTTPBadRequest, - paramName=u'user_name', paramCompare=range(1, 1 + get_constant('MAGPIE_USER_NAME_MAX_LENGTH')), + paramName=u"user_name", paramCompare=range(1, 1 + get_constant("MAGPIE_USER_NAME_MAX_LENGTH")), msgOnFail=s.Users_CheckInfo_Size_BadRequestResponseSchema.description) - ax.verify_param(user_name, paramCompare=get_constant('MAGPIE_LOGGED_USER'), notEqual=True, - paramName=u'user_name', httpError=HTTPBadRequest, + ax.verify_param(user_name, paramCompare=get_constant("MAGPIE_LOGGED_USER"), notEqual=True, + paramName=u"user_name", httpError=HTTPBadRequest, msgOnFail=s.Users_CheckInfo_ReservedKeyword_BadRequestResponseSchema.description) ax.verify_param(email, notNone=True, notEmpty=True, httpError=HTTPBadRequest, - paramName=u'email', msgOnFail=s.Users_CheckInfo_Email_BadRequestResponseSchema.description) + paramName=u"email", msgOnFail=s.Users_CheckInfo_Email_BadRequestResponseSchema.description) ax.verify_param(password, notNone=True, notEmpty=True, httpError=HTTPBadRequest, - paramName=u'password', msgOnFail=s.Users_CheckInfo_Password_BadRequestResponseSchema.description) + paramName=u"password", msgOnFail=s.Users_CheckInfo_Password_BadRequestResponseSchema.description) ax.verify_param(group_name, notNone=True, notEmpty=True, httpError=HTTPBadRequest, - paramName=u'group_name', msgOnFail=s.Users_CheckInfo_GroupName_BadRequestResponseSchema.description) + paramName=u"group_name", msgOnFail=s.Users_CheckInfo_GroupName_BadRequestResponseSchema.description) def get_user_groups_checked(request, user): diff --git a/magpie/api/management/user/user_views.py b/magpie/api/management/user/user_views.py index 11d2bd3e5..96ca946ee 100644 --- a/magpie/api/management/user/user_views.py +++ b/magpie/api/management/user/user_views.py @@ -15,7 +15,7 @@ ) from magpie.definitions.ziggurat_definitions import UserService, GroupService from magpie.constants import get_constant -from magpie.common import get_logger +from magpie.utils import get_logger from magpie import models LOGGER = get_logger(__name__) diff --git a/magpie/app.py b/magpie/app.py index 0951a4ee7..87b356d9c 100644 --- a/magpie/app.py +++ b/magpie/app.py @@ -5,7 +5,6 @@ Magpie is a service for AuthN and AuthZ based on Ziggurat-Foundations """ -from magpie.common import print_log, get_logger from magpie.constants import get_constant from magpie.definitions.pyramid_definitions import asbool from magpie.helpers.register_default_users import register_default_users @@ -14,7 +13,7 @@ magpie_register_permissions_from_config, ) from magpie.security import auth_config_from_settings -from magpie.utils import patch_magpie_url +from magpie.utils import patch_magpie_url, print_log, get_logger from magpie import db, constants import os import sys diff --git a/magpie/constants.py b/magpie/constants.py index 639b83176..14b7ef4e6 100644 --- a/magpie/constants.py +++ b/magpie/constants.py @@ -1,14 +1,15 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +""" +Constant settings for Magpie application. +""" +from magpie.definitions.pyramid_definitions import asbool +from typing import TYPE_CHECKING import os import shutil -# noinspection PyPackageRequirements import dotenv import logging import warnings -from magpie.common import raise_log, print_log, get_settings_from_config_ini -from magpie.definitions.pyramid_definitions import asbool -from typing import TYPE_CHECKING if TYPE_CHECKING: from magpie.definitions.typedefs import Str, Optional, SettingValue, SettingsContainer @@ -18,20 +19,20 @@ MAGPIE_MODULE_DIR = os.path.abspath(os.path.dirname(__file__)) MAGPIE_ROOT = os.path.dirname(MAGPIE_MODULE_DIR) MAGPIE_CONFIG_DIR = os.getenv( - 'MAGPIE_CONFIG_DIR', os.path.join(MAGPIE_ROOT, 'config')) + "MAGPIE_CONFIG_DIR", os.path.join(MAGPIE_ROOT, "config")) MAGPIE_PROVIDERS_CONFIG_PATH = os.getenv( - 'MAGPIE_PROVIDERS_CONFIG_PATH', '{}/providers.cfg'.format(MAGPIE_CONFIG_DIR)) + "MAGPIE_PROVIDERS_CONFIG_PATH", "{}/providers.cfg".format(MAGPIE_CONFIG_DIR)) MAGPIE_PERMISSIONS_CONFIG_PATH = os.getenv( - 'MAGPIE_PERMISSIONS_CONFIG_PATH', '{}/permissions.cfg'.format(MAGPIE_CONFIG_DIR)) + "MAGPIE_PERMISSIONS_CONFIG_PATH", "{}/permissions.cfg".format(MAGPIE_CONFIG_DIR)) MAGPIE_INI_FILE_PATH = os.getenv( - 'MAGPIE_INI_FILE_PATH', '{}/magpie.ini'.format(MAGPIE_MODULE_DIR)) + "MAGPIE_INI_FILE_PATH", "{}/magpie.ini".format(MAGPIE_MODULE_DIR)) MAGPIE_ALEMBIC_INI_FILE_PATH = os.getenv( - 'MAGPIE_ALEMBIC_INI_FILE_PATH', '{}/alembic/alembic.ini'.format(MAGPIE_MODULE_DIR)) + "MAGPIE_ALEMBIC_INI_FILE_PATH", "{}/alembic/alembic.ini".format(MAGPIE_MODULE_DIR)) # allow custom location of env files directory to avoid # loading from installed magpie in python site-packages -MAGPIE_ENV_DIR = os.getenv('MAGPIE_ENV_DIR', os.path.join(MAGPIE_ROOT, 'env')) -MAGPIE_ENV_FILE = os.path.join(MAGPIE_ENV_DIR, 'magpie.env') -MAGPIE_POSTGRES_ENV_FILE = os.path.join(MAGPIE_ENV_DIR, 'postgres.env') +MAGPIE_ENV_DIR = os.getenv("MAGPIE_ENV_DIR", os.path.join(MAGPIE_ROOT, "env")) +MAGPIE_ENV_FILE = os.path.join(MAGPIE_ENV_DIR, "magpie.env") +MAGPIE_POSTGRES_ENV_FILE = os.path.join(MAGPIE_ENV_DIR, "postgres.env") # create .env from .env.example if not present and load variables into environment # if files still cannot be found at 'MAGPIE_ENV_DIR' and variables are still not set, @@ -52,61 +53,67 @@ warnings.warn("Failed to open environment files [MAGPIE_ENV_DIR={}].".format(MAGPIE_ENV_DIR), RuntimeWarning) pass -# get default configurations from ini file -_default_log_lvl = 'INFO' -# noinspection PyBroadException -try: - _settings = get_settings_from_config_ini(MAGPIE_INI_FILE_PATH, ini_main_section_name='logger_magpie') - _default_log_lvl = _settings.get('level', _default_log_lvl) -except Exception: - pass + +def _get_default_log_level(): + """Get default configurations from ini file.""" + _default_log_lvl = "INFO" + # noinspection PyBroadException + try: + import magpie.utils + _settings = magpie.utils.get_settings_from_config_ini(MAGPIE_INI_FILE_PATH, + ini_main_section_name="logger_magpie") + _default_log_lvl = _settings.get("level", _default_log_lvl) + except Exception: + pass + # =========================== # variables from magpie.env # =========================== -MAGPIE_URL = os.getenv('MAGPIE_URL', None) -MAGPIE_SECRET = os.getenv('MAGPIE_SECRET', 'seekrit') -MAGPIE_COOKIE_NAME = os.getenv('MAGPIE_COOKIE_NAME', 'auth_tkt') -MAGPIE_COOKIE_EXPIRE = os.getenv('MAGPIE_COOKIE_EXPIRE', None) -MAGPIE_ADMIN_USER = os.getenv('MAGPIE_ADMIN_USER', 'admin') -MAGPIE_ADMIN_PASSWORD = os.getenv('MAGPIE_ADMIN_PASSWORD', 'qwerty') -MAGPIE_ADMIN_EMAIL = '{}@mail.com'.format(MAGPIE_ADMIN_USER) -MAGPIE_ADMIN_GROUP = os.getenv('MAGPIE_ADMIN_GROUP', 'administrators') -MAGPIE_ANONYMOUS_USER = os.getenv('MAGPIE_ANONYMOUS_USER', 'anonymous') +MAGPIE_URL = os.getenv("MAGPIE_URL", None) +MAGPIE_SECRET = os.getenv("MAGPIE_SECRET", "seekrit") +MAGPIE_COOKIE_NAME = os.getenv("MAGPIE_COOKIE_NAME", "auth_tkt") +MAGPIE_COOKIE_EXPIRE = os.getenv("MAGPIE_COOKIE_EXPIRE", None) +MAGPIE_ADMIN_USER = os.getenv("MAGPIE_ADMIN_USER", "admin") +MAGPIE_ADMIN_PASSWORD = os.getenv("MAGPIE_ADMIN_PASSWORD", "qwerty") +MAGPIE_ADMIN_EMAIL = "{}@mail.com".format(MAGPIE_ADMIN_USER) +MAGPIE_ADMIN_GROUP = os.getenv("MAGPIE_ADMIN_GROUP", "administrators") +MAGPIE_ANONYMOUS_USER = os.getenv("MAGPIE_ANONYMOUS_USER", "anonymous") MAGPIE_ANONYMOUS_PASSWORD = MAGPIE_ANONYMOUS_USER -MAGPIE_ANONYMOUS_EMAIL = '{}@mail.com'.format(MAGPIE_ANONYMOUS_USER) +MAGPIE_ANONYMOUS_EMAIL = "{}@mail.com".format(MAGPIE_ANONYMOUS_USER) MAGPIE_ANONYMOUS_GROUP = MAGPIE_ANONYMOUS_USER -MAGPIE_EDITOR_GROUP = os.getenv('MAGPIE_EDITOR_GROUP', 'editors') -MAGPIE_USERS_GROUP = os.getenv('MAGPIE_USERS_GROUP', 'users') -MAGPIE_CRON_LOG = os.getenv('MAGPIE_CRON_LOG', '~/magpie-cron.log') -MAGPIE_DB_MIGRATION = asbool(os.getenv('MAGPIE_DB_MIGRATION', True)) -MAGPIE_DB_MIGRATION_ATTEMPTS = int(os.getenv('MAGPIE_DB_MIGRATION_ATTEMPTS', 5)) -MAGPIE_LOG_LEVEL = os.getenv('MAGPIE_LOG_LEVEL', _default_log_lvl) -MAGPIE_LOG_REQUEST = asbool(os.getenv('MAGPIE_LOG_REQUEST', True)) -MAGPIE_LOG_EXCEPTION = asbool(os.getenv('MAGPIE_LOG_EXCEPTION', True)) -PHOENIX_USER = os.getenv('PHOENIX_USER', 'phoenix') -PHOENIX_PASSWORD = os.getenv('PHOENIX_PASSWORD', 'qwerty') -PHOENIX_PORT = int(os.getenv('PHOENIX_PORT', 8443)) -PHOENIX_PUSH = asbool(os.getenv('PHOENIX_PUSH', True)) -TWITCHER_PROTECTED_PATH = os.getenv('TWITCHER_PROTECTED_PATH', '/ows/proxy') -TWITCHER_PROTECTED_URL = os.getenv('TWITCHER_PROTECTED_URL', None) +MAGPIE_EDITOR_GROUP = os.getenv("MAGPIE_EDITOR_GROUP", "editors") +MAGPIE_USERS_GROUP = os.getenv("MAGPIE_USERS_GROUP", "users") +MAGPIE_CRON_LOG = os.getenv("MAGPIE_CRON_LOG", "~/magpie-cron.log") +MAGPIE_DB_MIGRATION = asbool(os.getenv("MAGPIE_DB_MIGRATION", True)) +MAGPIE_DB_MIGRATION_ATTEMPTS = int(os.getenv("MAGPIE_DB_MIGRATION_ATTEMPTS", 5)) +MAGPIE_LOG_LEVEL = os.getenv("MAGPIE_LOG_LEVEL", _get_default_log_level()) +MAGPIE_LOG_REQUEST = asbool(os.getenv("MAGPIE_LOG_REQUEST", True)) +MAGPIE_LOG_EXCEPTION = asbool(os.getenv("MAGPIE_LOG_EXCEPTION", True)) +MAGPIE_UI_ENABLED = asbool(os.getenv("MAGPIE_UI_ENABLED", True)) +PHOENIX_USER = os.getenv("PHOENIX_USER", "phoenix") +PHOENIX_PASSWORD = os.getenv("PHOENIX_PASSWORD", "qwerty") +PHOENIX_PORT = int(os.getenv("PHOENIX_PORT", 8443)) +PHOENIX_PUSH = asbool(os.getenv("PHOENIX_PUSH", True)) +TWITCHER_PROTECTED_PATH = os.getenv("TWITCHER_PROTECTED_PATH", "/ows/proxy") +TWITCHER_PROTECTED_URL = os.getenv("TWITCHER_PROTECTED_URL", None) # =========================== # variables from postgres.env # =========================== -MAGPIE_POSTGRES_USER = os.getenv('MAGPIE_POSTGRES_USER', 'magpie') -MAGPIE_POSTGRES_PASSWORD = os.getenv('MAGPIE_POSTGRES_PASSWORD', 'qwerty') -MAGPIE_POSTGRES_HOST = os.getenv('MAGPIE_POSTGRES_HOST', 'postgres') -MAGPIE_POSTGRES_PORT = int(os.getenv('MAGPIE_POSTGRES_PORT', 5432)) -MAGPIE_POSTGRES_DB = os.getenv('MAGPIE_POSTGRES_DB', 'magpie') +MAGPIE_POSTGRES_USER = os.getenv("MAGPIE_POSTGRES_USER", "magpie") +MAGPIE_POSTGRES_PASSWORD = os.getenv("MAGPIE_POSTGRES_PASSWORD", "qwerty") +MAGPIE_POSTGRES_HOST = os.getenv("MAGPIE_POSTGRES_HOST", "postgres") +MAGPIE_POSTGRES_PORT = int(os.getenv("MAGPIE_POSTGRES_PORT", 5432)) +MAGPIE_POSTGRES_DB = os.getenv("MAGPIE_POSTGRES_DB", "magpie") # =========================== # other constants # =========================== -MAGPIE_ADMIN_PERMISSION = 'admin' +MAGPIE_ADMIN_PERMISSION = "admin" # MAGPIE_ADMIN_PERMISSION = NO_PERMISSION_REQUIRED -MAGPIE_LOGGED_USER = 'current' -MAGPIE_DEFAULT_PROVIDER = 'ziggurat' +MAGPIE_LOGGED_USER = "current" +MAGPIE_DEFAULT_PROVIDER = "ziggurat" # above this length is considered a token, # refuse longer username creation @@ -136,7 +143,7 @@ def get_constant(name, settings_container=None, settings_name=None, default_valu :returns: found value or `default_value` :raises: according message based on options (by default raise missing/`None` value) """ - from magpie.utils import get_settings + from magpie.utils import get_settings, raise_log, print_log magpie_globals = globals() missing = True diff --git a/magpie/db.py b/magpie/db.py index 04fa714c9..77cc8299f 100644 --- a/magpie/db.py +++ b/magpie/db.py @@ -1,13 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from magpie.constants import get_constant -from magpie.common import get_settings_from_config_ini, print_log, raise_log, get_logger from magpie.definitions.alembic_definitions import alembic from magpie.definitions.sqlalchemy_definitions import ( register, sessionmaker, engine_from_config, ZopeTransactionExtension, configure_mappers, select, Inspector, Session, sa_exc ) from magpie.definitions.pyramid_definitions import asbool +from magpie.utils import get_settings_from_config_ini, print_log, raise_log, get_logger from typing import TYPE_CHECKING import transaction import inspect diff --git a/magpie/definitions/__init__.py b/magpie/definitions/__init__.py index 49090d05e..e43a87ced 100644 --- a/magpie/definitions/__init__.py +++ b/magpie/definitions/__init__.py @@ -1,5 +1,5 @@ # noinspection PyUnusedLocal def includeme(config): - from magpie.common import get_logger + from magpie.utils import get_logger logger = get_logger(__name__) logger.info('Adding definitions...') diff --git a/magpie/definitions/typedefs.py b/magpie/definitions/typedefs.py index 994d7db00..acfc86d31 100644 --- a/magpie/definitions/typedefs.py +++ b/magpie/definitions/typedefs.py @@ -7,6 +7,7 @@ ) if TYPE_CHECKING: from magpie.definitions.sqlalchemy_definitions import Session + from magpie.models import GroupPermission, UserPermission from webob.headers import ResponseHeaders, EnvironHeaders from webob.response import Response as WebobResponse from webtest.response import TestResponse @@ -28,25 +29,26 @@ Str = _AnyStr AnyStr = Str - SettingValue = Union[Str, int, float, bool, None] + Number = Union[int, float] + SettingValue = Union[Str, Number, bool, None] SettingsType = Dict[Str, SettingValue] - SettingsContainer = Union[Configurator, Registry, Request, SettingsType] + ParamsType = Dict[Str, Any] CookiesType = Union[Dict[Str, Str], List[Tuple[Str, Str]]] HeadersType = Union[Dict[Str, Str], List[Tuple[Str, Str]]] OptionalHeaderCookiesType = Union[Tuple[None, None], Tuple[HeadersType, CookiesType]] AnyHeadersType = Union[HeadersType, ResponseHeaders, EnvironHeaders, CaseInsensitiveDict] AnyResponseType = Union[WebobResponse, PyramidResponse, TestResponse] - CookiesOrSessionType = Union[RequestsCookieJar, Session] - JsonField = Union[Str, int, float, bool, None] - JsonBody = Dict[Str, Union[JsonField, Dict[Str, Any], List[Any]]] - - ParamKWArgs = Dict[Str, Any] + AnyKey = Union[Str, int] + AnyValue = Union[Str, Number, bool, None] + BaseJSON = Union[AnyValue, List["BaseJSON"], Dict[AnyKey, "BaseJSON"]] + JSON = Dict[AnyKey, BaseJSON] UserServicesType = Union[Dict[Str, Dict[Str, Any]], List[Dict[Str, Any]]] + ResourcePermissionType = Union[GroupPermission, UserPermission] TestAppOrUrlType = Union[Str, TestApp] AnyMagpieTestType = Union[Type[Base_Magpie_TestCase], Base_Magpie_TestCase, TestAppOrUrlType] diff --git a/magpie/helpers/register_default_users.py b/magpie/helpers/register_default_users.py index 872fadfc2..6c57ab404 100644 --- a/magpie/helpers/register_default_users.py +++ b/magpie/helpers/register_default_users.py @@ -1,7 +1,7 @@ from magpie import constants, db, models -from magpie.common import print_log, raise_log, get_logger from magpie.definitions.sqlalchemy_definitions import Session from magpie.definitions.ziggurat_definitions import GroupService, UserService +from magpie.utils import print_log, raise_log, get_logger from typing import TYPE_CHECKING import transaction import logging diff --git a/magpie/helpers/sync_resources.py b/magpie/helpers/sync_resources.py index af1242643..addc75e69 100644 --- a/magpie/helpers/sync_resources.py +++ b/magpie/helpers/sync_resources.py @@ -15,7 +15,7 @@ from magpie import db, models, constants from magpie.helpers import sync_services -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) diff --git a/magpie/helpers/sync_services.py b/magpie/helpers/sync_services.py index 9644fa1f8..047f4aca5 100644 --- a/magpie/helpers/sync_services.py +++ b/magpie/helpers/sync_services.py @@ -1,7 +1,6 @@ -from magpie.common import JSON_TYPE -import abc +from magpie.utils import CONTENT_TYPE_JSON from collections import OrderedDict - +import abc import requests import threddsclient @@ -61,7 +60,7 @@ def get_resources(self): # Only workspaces are fetched for now resource_type = "route" workspaces_url = "{}/{}".format(self.url, "workspaces") - resp = requests.get(workspaces_url, headers={"Accept": JSON_TYPE}) + resp = requests.get(workspaces_url, headers={"Accept": CONTENT_TYPE_JSON}) resp.raise_for_status() workspaces_list = resp.json().get("workspaces", {}).get("workspace", {}) diff --git a/magpie/models.py b/magpie/models.py index 630f54e7f..e4f193221 100644 --- a/magpie/models.py +++ b/magpie/models.py @@ -19,7 +19,7 @@ UserResourcePermissionMixin, UserService, ) -from magpie import permissions as p +from magpie.permissions import Permission from typing import TYPE_CHECKING if TYPE_CHECKING: from magpie.definitions.typedefs import Str # noqa: F401 @@ -57,14 +57,14 @@ class GroupResourcePermission(GroupResourcePermissionMixin, Base): class ResourceMeta(type): @property def resource_type_name(cls): - # type: (...) -> Str + # type: () -> Str """Generic resource type identifier.""" raise NotImplemented("Resource implementation must define unique type representation" - "and must be added to `resource_type_dict`.") + "and must be added to 'RESOURCE_TYPE_DICT'.") class Resource(ResourceMixin, Base): - permission_names = [] + permissions = [] child_resource_allowed = True resource_display_name = sa.Column(sa.Unicode(100), nullable=True) @@ -73,9 +73,9 @@ class Resource(ResourceMixin, Base): @declared_attr def root_service_id(self): return sa.Column(sa.Integer, - sa.ForeignKey('services.resource_id', - onupdate='CASCADE', - ondelete='SET NULL'), index=True) + sa.ForeignKey("services.resource_id", + onupdate="CASCADE", + ondelete="SET NULL"), index=True) @property def __acl__(self): @@ -119,21 +119,19 @@ def __init__(self, request): # application like CMS, forum or other permission based solution class Service(Resource): - """ - Resource of `service` type - """ + """Resource of `service` type.""" - __tablename__ = u'services' + __tablename__ = u"services" resource_id = sa.Column(sa.Integer(), - sa.ForeignKey('resources.resource_id', - onupdate='CASCADE', - ondelete='CASCADE', ), + sa.ForeignKey("resources.resource_id", + onupdate="CASCADE", + ondelete="CASCADE", ), primary_key=True, ) - resource_type_name = u'service' - __mapper_args__ = {u'polymorphic_identity': resource_type_name, - u'inherit_condition': resource_id == Resource.resource_id} + resource_type_name = u"service" + __mapper_args__ = {u"polymorphic_identity": resource_type_name, + u"inherit_condition": resource_id == Resource.resource_id} # ... your own properties.... @@ -172,54 +170,54 @@ def extend_acl(self, resource, user): class Path(object): - permission_names = [ - p.PERMISSION_READ, - p.PERMISSION_WRITE, - p.PERMISSION_GET_CAPABILITIES, - p.PERMISSION_GET_MAP, - p.PERMISSION_GET_FEATURE_INFO, - p.PERMISSION_GET_LEGEND_GRAPHIC, - p.PERMISSION_GET_METADATA, + permissions = [ + Permission.READ, + Permission.WRITE, + Permission.GET_CAPABILITIES, + Permission.GET_MAP, + Permission.GET_FEATURE_INFO, + Permission.GET_LEGEND_GRAPHIC, + Permission.GET_METADATA, ] class File(Resource, Path): child_resource_allowed = False - resource_type_name = u'file' - __mapper_args__ = {u'polymorphic_identity': resource_type_name} + resource_type_name = u"file" + __mapper_args__ = {u"polymorphic_identity": resource_type_name} class Directory(Resource, Path): - resource_type_name = u'directory' - __mapper_args__ = {u'polymorphic_identity': resource_type_name} + resource_type_name = u"directory" + __mapper_args__ = {u"polymorphic_identity": resource_type_name} class Workspace(Resource): - resource_type_name = u'workspace' - __mapper_args__ = {u'polymorphic_identity': resource_type_name} - - permission_names = [ - p.PERMISSION_GET_CAPABILITIES, - p.PERMISSION_GET_MAP, - p.PERMISSION_GET_FEATURE_INFO, - p.PERMISSION_GET_LEGEND_GRAPHIC, - p.PERMISSION_GET_METADATA, - p.PERMISSION_GET_FEATURE, - p.PERMISSION_DESCRIBE_FEATURE_TYPE, - p.PERMISSION_LOCK_FEATURE, - p.PERMISSION_TRANSACTION, + resource_type_name = u"workspace" + __mapper_args__ = {u"polymorphic_identity": resource_type_name} + + permissions = [ + Permission.GET_CAPABILITIES, + Permission.GET_MAP, + Permission.GET_FEATURE_INFO, + Permission.GET_LEGEND_GRAPHIC, + Permission.GET_METADATA, + Permission.GET_FEATURE, + Permission.DESCRIBE_FEATURE_TYPE, + Permission.LOCK_FEATURE, + Permission.TRANSACTION, ] class Route(Resource): - resource_type_name = u'route' - __mapper_args__ = {u'polymorphic_identity': resource_type_name} - - permission_names = [ - p.PERMISSION_READ, # access with inheritance (this route and all under it) - p.PERMISSION_WRITE, # access with inheritance (this route and all under it) - p.PERMISSION_READ_MATCH, # access without inheritance (only on this specific route) - p.PERMISSION_WRITE_MATCH, # access without inheritance (only on this specific route) + resource_type_name = u"route" + __mapper_args__ = {u"polymorphic_identity": resource_type_name} + + permissions = [ + Permission.READ, # access with inheritance (this route and all under it) + Permission.WRITE, # access with inheritance (this route and all under it) + Permission.READ_MATCH, # access without inheritance (only on this specific route) + Permission.WRITE_MATCH, # access without inheritance (only on this specific route) ] @@ -231,15 +229,15 @@ class RemoteResource(BaseModel, Base): resource_id = sa.Column(sa.Integer(), primary_key=True, nullable=False, autoincrement=True) service_id = sa.Column(sa.Integer(), - sa.ForeignKey('services.resource_id', - onupdate='CASCADE', - ondelete='CASCADE'), + sa.ForeignKey("services.resource_id", + onupdate="CASCADE", + ondelete="CASCADE"), index=True, nullable=False) parent_id = sa.Column(sa.Integer(), - sa.ForeignKey('remote_resources.resource_id', - onupdate='CASCADE', - ondelete='SET NULL'), + sa.ForeignKey("remote_resources.resource_id", + onupdate="CASCADE", + ondelete="SET NULL"), nullable=True) ordering = sa.Column(sa.Integer(), default=0, nullable=False) resource_name = sa.Column(sa.Unicode(100), nullable=False) @@ -248,7 +246,7 @@ class RemoteResource(BaseModel, Base): def __repr__(self): info = self.resource_type, self.resource_name, self.resource_id, self.ordering, self.parent_id - return '' % info + return "" % info class RemoteResourcesSyncInfo(BaseModel, Base): @@ -256,15 +254,15 @@ class RemoteResourcesSyncInfo(BaseModel, Base): id = sa.Column(sa.Integer(), primary_key=True, nullable=False, autoincrement=True) service_id = sa.Column(sa.Integer(), - sa.ForeignKey('services.resource_id', - onupdate='CASCADE', - ondelete='CASCADE'), + sa.ForeignKey("services.resource_id", + onupdate="CASCADE", + ondelete="CASCADE"), index=True, nullable=False) service = relationship("Service", foreign_keys=[service_id]) remote_resource_id = sa.Column(sa.Integer(), - sa.ForeignKey('remote_resources.resource_id', onupdate='CASCADE', - ondelete='CASCADE')) + sa.ForeignKey("remote_resources.resource_id", onupdate="CASCADE", + ondelete="CASCADE")) last_sync = sa.Column(sa.DateTime(), nullable=True) @staticmethod @@ -276,7 +274,7 @@ def by_service_id(service_id, session): def __repr__(self): last_modified = self.last_sync.strftime("%Y-%m-%dT%H:%M:%S") if self.last_sync else None info = self.service_id, last_modified, self.id - return '' % info + return "" % info class RemoteResourceTreeService(ResourceTreeService): @@ -302,7 +300,7 @@ class RemoteResourceTreeServicePostgresSQL(ResourceTreeServicePostgreSQL): resource_tree_service = ResourceTreeService(ResourceTreeServicePostgreSQL) remote_resource_tree_service = RemoteResourceTreeService(RemoteResourceTreeServicePostgresSQL) -resource_type_dict = { +RESOURCE_TYPE_DICT = { Service.resource_type_name: Service, # noqa: E241 Directory.resource_type_name: Directory, # noqa: E241 File.resource_type_name: File, # noqa: E241 @@ -312,19 +310,12 @@ class RemoteResourceTreeServicePostgresSQL(ResourceTreeServicePostgreSQL): def resource_factory(**kwargs): - resource_type = evaluate_call(lambda: kwargs['resource_type'], httpError=HTTPInternalServerError, - msgOnFail="kwargs do not contain required `resource_type`", - content={u'kwargs': repr(kwargs)}) - return evaluate_call(lambda: resource_type_dict[resource_type](**kwargs), httpError=HTTPInternalServerError, - msgOnFail="kwargs unpacking failed from specified `resource_type` and `resource_type_dict`", - content={u'kwargs': repr(kwargs), u'resource_type_dict': repr(resource_type_dict)}) - - -def get_all_resource_permission_names(): - all_permission_names_list = set() - for service_type in resource_type_dict.keys(): - all_permission_names_list.update(resource_type_dict[service_type].permission_names) - return all_permission_names_list + resource_type = evaluate_call(lambda: kwargs["resource_type"], httpError=HTTPInternalServerError, + msgOnFail="kwargs do not contain required 'resource_type'", + content={u"kwargs": repr(kwargs)}) + return evaluate_call(lambda: RESOURCE_TYPE_DICT[resource_type](**kwargs), httpError=HTTPInternalServerError, + msgOnFail="kwargs unpacking failed from specified 'resource_type' and 'RESOURCE_TYPE_DICT'", + content={u"kwargs": repr(kwargs), u"RESOURCE_TYPE_DICT": repr(RESOURCE_TYPE_DICT)}) def find_children_by_name(child_name, parent_id, db_session): diff --git a/magpie/owsrequest.py b/magpie/owsrequest.py index 6fd2d4e96..01668d2ff 100644 --- a/magpie/owsrequest.py +++ b/magpie/owsrequest.py @@ -6,7 +6,7 @@ """ from magpie.api.api_except import raise_http -from magpie.common import get_logger, get_header, JSON_TYPE, PLAIN_TYPE +from magpie.utils import get_logger, get_header, CONTENT_TYPE_JSON, CONTENT_TYPE_PLAIN from pyramid.httpexceptions import HTTPMethodNotAllowed from typing import TYPE_CHECKING # noinspection PyUnresolvedReferences @@ -24,23 +24,23 @@ def ows_parser_factory(request): Default to JSON if no ``Content-Type`` is specified or if it is 'text/plain' but can be parsed as JSON. Otherwise, use the GET/POST WPS parsers. """ - content_type = get_header('Content-Type', request.headers, default=JSON_TYPE, split=';,') - if content_type == PLAIN_TYPE: + content_type = get_header("Content-Type", request.headers, default=CONTENT_TYPE_JSON, split=";,") + if content_type == CONTENT_TYPE_PLAIN: try: # noinspection PyUnresolvedReferences if request.body: # raises if parsing fails # noinspection PyUnresolvedReferences json.loads(request.body) - content_type = JSON_TYPE + content_type = CONTENT_TYPE_JSON except ValueError: pass - if content_type == JSON_TYPE: + if content_type == CONTENT_TYPE_JSON: return JSONParser(request) else: - if request.method == 'GET': + if request.method == "GET": return WPSGet(request) - elif request.method == 'POST': + elif request.method == "POST": return WPSPost(request) # method not supported, raise using the specified content type header @@ -85,11 +85,11 @@ def _get_param_value(self, param): def lxml_strip_ns(tree): for node in tree.iter(): try: - has_namespace = node.tag.startswith('{') + has_namespace = node.tag.startswith("{") except AttributeError: continue # node.tag is not a string (node is a comment or similar) if has_namespace: - node.tag = node.tag.split('}', 1)[1] + node.tag = node.tag.split("}", 1)[1] class WPSPost(OWSParser): @@ -103,7 +103,7 @@ def __init__(self, request): def _get_param_value(self, param): if param in self.document.attrib: return self.document.attrib[param].lower() - elif param == 'request': + elif param == "request": return self.document.tag.lower() else: return None diff --git a/magpie/permissions.py b/magpie/permissions.py index a4145eed8..6be94a445 100644 --- a/magpie/permissions.py +++ b/magpie/permissions.py @@ -1,36 +1,22 @@ -PERMISSION_READ = u'read' -PERMISSION_READ_MATCH = u'read-match' -PERMISSION_WRITE = u'write' -PERMISSION_WRITE_MATCH = u'write-match' -PERMISSION_ACCESS = u'access' +from enum import Enum -PERMISSION_GET_CAPABILITIES = u'getcapabilities' -PERMISSION_GET_MAP = u'getmap' -PERMISSION_GET_FEATURE_INFO = u'getfeatureinfo' -PERMISSION_GET_LEGEND_GRAPHIC = u'getlegendgraphic' -PERMISSION_GET_METADATA = u'getmetadata' -PERMISSION_GET_FEATURE = u'getfeature' -PERMISSION_DESCRIBE_FEATURE_TYPE = u'describefeaturetype' -PERMISSION_DESCRIBE_PROCESS = u'describeprocess' -PERMISSION_EXECUTE = u'execute' -PERMISSION_LOCK_FEATURE = u'lockfeature' -PERMISSION_TRANSACTION = u'transaction' -permissions_supported = frozenset([ - PERMISSION_READ, - PERMISSION_READ_MATCH, - PERMISSION_WRITE, - PERMISSION_WRITE_MATCH, - PERMISSION_ACCESS, - PERMISSION_GET_CAPABILITIES, - PERMISSION_GET_MAP, - PERMISSION_GET_FEATURE_INFO, - PERMISSION_GET_LEGEND_GRAPHIC, - PERMISSION_GET_METADATA, - PERMISSION_GET_FEATURE, - PERMISSION_DESCRIBE_FEATURE_TYPE, - PERMISSION_DESCRIBE_PROCESS, - PERMISSION_EXECUTE, - PERMISSION_LOCK_FEATURE, - PERMISSION_TRANSACTION, -]) +class Permission(Enum): + # file/dir permissions + READ = u'read' + READ_MATCH = u'read-match' + WRITE = u'write' + WRITE_MATCH = u'write-match' + ACCESS = u'access' + # WPS permissions + GET_CAPABILITIES = u'getcapabilities' + GET_MAP = u'getmap' + GET_FEATURE_INFO = u'getfeatureinfo' + GET_LEGEND_GRAPHIC = u'getlegendgraphic' + GET_METADATA = u'getmetadata' + GET_FEATURE = u'getfeature' + DESCRIBE_FEATURE_TYPE = u'describefeaturetype' + DESCRIBE_PROCESS = u'describeprocess' + EXECUTE = u'execute' + LOCK_FEATURE = u'lockfeature' + TRANSACTION = u'transaction' diff --git a/magpie/register.py b/magpie/register.py index 2b9737262..3cddd17d7 100644 --- a/magpie/register.py +++ b/magpie/register.py @@ -9,7 +9,6 @@ GroupResourcePermissionsAPI, UserResourcePermissionsAPI, ) -from magpie.common import make_dirs, print_log, raise_log, bool2str, islambda, get_logger, get_json from magpie.constants import get_constant from magpie.definitions.ziggurat_definitions import ( ResourceService, @@ -19,10 +18,13 @@ ) from magpie.definitions.sqlalchemy_definitions import Session from magpie.definitions.pyramid_definitions import HTTPException -from magpie.permissions import permissions_supported -from magpie.services import service_type_dict +from magpie.permissions import Permission +from magpie.services import SERVICE_TYPE_DICT, ServiceWPS from magpie import models -from magpie.utils import get_twitcher_protected_service_url, get_phoenix_url, get_magpie_url, get_admin_cookies +from magpie.utils import ( + get_twitcher_protected_service_url, get_phoenix_url, get_magpie_url, get_admin_cookies, + make_dirs, print_log, raise_log, bool2str, islambda, get_logger, get_json +) from typing import TYPE_CHECKING import os import six @@ -34,7 +36,7 @@ import logging if TYPE_CHECKING: from magpie.definitions.typedefs import ( # noqa: F401 - Str, Dict, List, JsonBody, Optional, Tuple, Union, CookiesOrSessionType + Str, Dict, List, JSON, Optional, Tuple, Union, CookiesOrSessionType ) LOGGER = get_logger(__name__) @@ -47,9 +49,9 @@ GETCAPABILITIES_ATTEMPTS = 12 # max attempts for 'GetCapabilities' validations # controls -SERVICES_MAGPIE = 'MAGPIE' -SERVICES_PHOENIX = 'PHOENIX' -SERVICES_PHOENIX_ALLOWED = ['wps'] +SERVICES_MAGPIE = "MAGPIE" +SERVICES_PHOENIX = "PHOENIX" +SERVICES_PHOENIX_ALLOWED = [ServiceWPS.service_type] if TYPE_CHECKING: ConfigItem = Dict[Str, Str] @@ -57,12 +59,12 @@ ConfigDict = Dict[Str, Union[ConfigItem, ConfigList]] -def login_loop(login_url, cookies_file, data=None, message='Login response'): +def login_loop(login_url, cookies_file, data=None, message="Login response"): make_dirs(cookies_file) - data_str = '' + data_str = "" if data is not None and type(data) is dict: for key in data: - data_str = data_str + '&' + str(key) + '=' + str(data[key]) + data_str = data_str + "&" + str(key) + "=" + str(data[key]) if type(data) is str: data_str = data attempt = 0 @@ -73,10 +75,10 @@ def login_loop(login_url, cookies_file, data=None, message='Login response'): time.sleep(LOGIN_TIMEOUT) attempt += 1 if attempt >= LOGIN_ATTEMPT: - raise Exception('Cannot log in to {0}'.format(login_url)) + raise Exception("Cannot log in to {0}".format(login_url)) -def request_curl(url, cookie_jar=None, cookies=None, form_params=None, msg='Response'): +def request_curl(url, cookie_jar=None, cookies=None, form_params=None, msg="Response"): # type: (Str, Optional[Str], Optional[Str], Optional[Str], Optional[Str]) -> Tuple[int, int] """Executes a request using cURL. @@ -87,15 +89,15 @@ def request_curl(url, cookie_jar=None, cookies=None, form_params=None, msg='Resp # curl_cmd = 'curl -k -L -s -o /dev/null -w "{msg_out} : %{{http_code}}\\n" {params} {url}' # curl_cmd = curl_cmd.format(msg_out=msg, params=params, url=url) msg_sep = msg + ": " - params = ['curl', '-k', '-L', '-s', '-o', '/dev/null', '-w', msg_sep + '%{http_code}'] + params = ["curl", "-k", "-L", "-s", "-o", "/dev/null", "-w", msg_sep + "%{http_code}"] if cookie_jar is not None and cookies is not None: raise ValueError("CookiesType and Cookie_Jar cannot be both set simultaneously") if cookie_jar is not None: - params.extend(['--cookie-jar', cookie_jar]) # save cookies + params.extend(["--cookie-jar", cookie_jar]) # save cookies if cookies is not None: - params.extend(['--cookie', cookies]) # use cookies + params.extend(["--cookie", cookies]) # use cookies if form_params is not None: - params.extend(['--data', form_params]) + params.extend(["--data", form_params]) params.extend([url]) curl_out = subprocess.Popen(params, stdout=subprocess.PIPE) curl_msg = curl_out.communicate()[0] # type: Str @@ -117,11 +119,11 @@ def phoenix_update_services(services_dict): def phoenix_login(cookies): - phoenix_pwd = get_constant('PHOENIX_PASSWORD') + phoenix_pwd = get_constant("PHOENIX_PASSWORD") phoenix_url = get_phoenix_url() - login_url = phoenix_url + '/account/login/phoenix' - login_data = {'password': phoenix_pwd, 'submit': 'submit'} - login_loop(login_url, cookies, login_data, 'Phoenix login response') + login_url = phoenix_url + "/account/login/phoenix" + login_data = {"password": phoenix_pwd, "submit": "submit"} + login_loop(login_url, cookies, login_data, "Phoenix login response") return phoenix_login_check(cookies) @@ -132,28 +134,28 @@ def phoenix_login_check(cookies): :return: status indicating if login access was granted with defined credentials. """ no_access_error = "Unauthorized: Services failed permission check" - svc_url = get_phoenix_url() + '/services' - curl_process = subprocess.Popen(['curl', '-s', '--cookie', cookies, svc_url], stdout=subprocess.PIPE) + svc_url = get_phoenix_url() + "/services" + curl_process = subprocess.Popen(["curl", "-s", "--cookie", cookies, svc_url], stdout=subprocess.PIPE) curl_http_resp = curl_process.communicate() has_access = no_access_error not in curl_http_resp[0] return has_access def phoenix_remove_services(): - # type: (...) -> bool + # type: () -> bool """Removes the Phoenix services using temporary cookies retrieved from login with defined `PHOENIX` constants. :returns: success status of the procedure. """ - phoenix_cookies = os.path.join(LOGIN_TMP_DIR, 'login_cookie_phoenix') + phoenix_cookies = os.path.join(LOGIN_TMP_DIR, "login_cookie_phoenix") error = 0 try: if not phoenix_login(phoenix_cookies): print_log("Login unsuccessful from post-login check, aborting...", logger=LOGGER) return False phoenix_url = get_phoenix_url() - remove_services_url = phoenix_url + '/clear_services' - error, http_code = request_curl(remove_services_url, cookies=phoenix_cookies, msg='Phoenix remove services') + remove_services_url = phoenix_url + "/clear_services" + error, http_code = request_curl(remove_services_url, cookies=phoenix_cookies, msg="Phoenix remove services") except Exception as e: print_log("Exception during phoenix remove services: [{!r}]".format(e), logger=LOGGER) finally: @@ -163,7 +165,7 @@ def phoenix_remove_services(): def phoenix_register_services(services_dict, allowed_service_types=None): - phoenix_cookies = os.path.join(LOGIN_TMP_DIR, 'login_cookie_phoenix') + phoenix_cookies = os.path.join(LOGIN_TMP_DIR, "login_cookie_phoenix") success = False statuses = dict() try: @@ -176,13 +178,13 @@ def phoenix_register_services(services_dict, allowed_service_types=None): # Filter specific services to push filtered_services_dict = {} for svc in services_dict: - if str(services_dict[svc].get('type')).upper() in allowed_service_types: + if str(services_dict[svc].get("type")).upper() in allowed_service_types: filtered_services_dict[svc] = services_dict[svc] - filtered_services_dict[svc]['type'] = filtered_services_dict[svc]['type'].upper() + filtered_services_dict[svc]["type"] = filtered_services_dict[svc]["type"].upper() # Register services success, statuses = register_services(SERVICES_PHOENIX, filtered_services_dict, - phoenix_cookies, 'Phoenix register service') + phoenix_cookies, "Phoenix register service") except Exception as e: print_log("Exception during phoenix register services: [{!r}]".format(e), logger=LOGGER, level=logging.ERROR) finally: @@ -194,7 +196,7 @@ def phoenix_register_services(services_dict, allowed_service_types=None): def register_services(where, # type: Optional[Str] services_dict, # type: Dict[Str, Dict[Str, Str]] cookies, # type: Str - message='Register response', # type: Optional[Str] + message="Register response", # type: Optional[Str] ): # type: (...) -> Tuple[bool, Dict[Str, int]] """ Registers services on desired location using provided configurations and access cookies. @@ -206,31 +208,31 @@ def register_services(where, # type: Optional[Str] statuses = dict() register_service_url = None if where == SERVICES_MAGPIE: - svc_url_tag = 'service_url' + svc_url_tag = "service_url" get_magpie_url() + ServicesAPI.path elif where == SERVICES_PHOENIX: - svc_url_tag = 'url' - register_service_url = get_phoenix_url() + '/services/register' + svc_url_tag = "url" + register_service_url = get_phoenix_url() + "/services/register" else: raise ValueError("Unknown location for service registration", where) for service_name in services_dict: cfg = services_dict[service_name] - cfg['public'] = bool2str(cfg.get('public')) - cfg['c4i'] = bool2str(cfg.get('c4i')) - cfg['url'] = os.path.expandvars(cfg.get('url')) + cfg["public"] = bool2str(cfg.get("public")) + cfg["c4i"] = bool2str(cfg.get("c4i")) + cfg["url"] = os.path.expandvars(cfg.get("url")) if where == SERVICES_MAGPIE: - svc_url = cfg['url'] + svc_url = cfg["url"] elif where == SERVICES_PHOENIX: svc_url = get_twitcher_protected_service_url(service_name) - params = 'service_name={name}&' \ - '{svc_url_tag}={svc_url}&' \ - 'service_title={cfg[title]}&' \ - 'public={cfg[public]}&' \ - 'c4i={cfg[c4i]}&' \ - 'service_type={cfg[type]}&' \ - 'register=register' \ + params = "service_name={name}&" \ + "{svc_url_tag}={svc_url}&" \ + "service_title={cfg[title]}&" \ + "public={cfg[public]}&" \ + "c4i={cfg[c4i]}&" \ + "service_type={cfg[type]}&" \ + "register=register" \ .format(name=service_name, cfg=cfg, svc_url_tag=svc_url_tag, svc_url=svc_url) - service_msg = '{msg} ({svc}) [{url}]'.format(msg=message, svc=service_name, url=svc_url) + service_msg = "{msg} ({svc}) [{url}]".format(msg=message, svc=service_name, url=svc_url) error, http_code = request_curl(register_service_url, cookies=cookies, form_params=params, msg=service_msg) statuses[service_name] = http_code success = success and not error and ((where == SERVICES_PHOENIX and http_code == 200) or @@ -252,46 +254,46 @@ def sync_services_phoenix(services_object_dict, services_as_dicts=False): for svc in services_object_dict: if services_as_dicts: svc_dict = services_object_dict[svc] - services_dict[svc] = {'url': svc_dict['public_url'], 'title': svc_dict['service_name'], - 'type': svc_dict['service_type'], 'c4i': False, 'public': True} + services_dict[svc] = {"url": svc_dict["public_url"], "title": svc_dict["service_name"], + "type": svc_dict["service_type"], "c4i": False, "public": True} else: - services_dict[svc.resource_name] = {'url': svc.url, 'title': svc.resource_name, - 'type': svc.type, 'c4i': False, 'public': True} + services_dict[svc.resource_name] = {"url": svc.url, "title": svc.resource_name, + "type": svc.type, "c4i": False, "public": True} return phoenix_update_services(services_dict) def magpie_add_register_services_perms(services, statuses, curl_cookies, request_cookies, disable_getcapabilities): magpie_url = get_magpie_url() - login_usr = get_constant('MAGPIE_ANONYMOUS_USER') + login_usr = get_constant("MAGPIE_ANONYMOUS_USER") for service_name in services: - svc_available_perms_url = '{magpie}/services/{svc}/permissions' \ + svc_available_perms_url = "{magpie}/services/{svc}/permissions" \ .format(magpie=magpie_url, svc=service_name) resp_available_perms = requests.get(svc_available_perms_url, cookies=request_cookies) if resp_available_perms.status_code == 401: raise_log("Invalid credentials, cannot update service permissions", exception=ValueError, logger=LOGGER) - available_perms = get_json(resp_available_perms).get('permission_names', []) - # only applicable to services supporting 'GetCapabilities' request - if resp_available_perms.status_code and 'getcapabilities' in available_perms: + available_perms = get_json(resp_available_perms).get("permission_names", []) + # only applicable to services supporting "GetCapabilities" request + if resp_available_perms.status_code and Permission.GET_CAPABILITIES.value in available_perms: # enforce 'getcapabilities' permission if available for service just updated (200) or created (201) # update 'getcapabilities' permission when the service existed and it allowed if (not disable_getcapabilities and statuses[service_name] == 409) \ or statuses[service_name] == 200 or statuses[service_name] == 201: # noqa - svc_anonym_add_perms_url = '{magpie}/users/{usr}/services/{svc}/permissions' \ + svc_anonym_add_perms_url = "{magpie}/users/{usr}/services/{svc}/permissions" \ .format(magpie=magpie_url, usr=login_usr, svc=service_name) - svc_anonym_perm_data = {'permission_name': 'getcapabilities'} + svc_anonym_perm_data = {"permission_name": Permission.GET_CAPABILITIES.value} requests.post(svc_anonym_add_perms_url, data=svc_anonym_perm_data, cookies=request_cookies) # check service response so Phoenix doesn't refuse registration # try with both the 'direct' URL and the 'GetCapabilities' URL attempt = 0 - service_info_url = '{magpie}/services/{svc}'.format(magpie=magpie_url, svc=service_name) + service_info_url = "{magpie}/services/{svc}".format(magpie=magpie_url, svc=service_name) service_info_resp = requests.get(service_info_url, cookies=request_cookies) - service_url = get_json(service_info_resp).get(service_name).get('service_url') - svc_getcap_url = '{svc_url}/wps?service=WPS&version=1.0.0&request=GetCapabilities' \ + service_url = get_json(service_info_resp).get(service_name).get("service_url") + svc_getcap_url = "{svc_url}/wps?service=WPS&version=1.0.0&request=GetCapabilities" \ .format(svc_url=service_url) while True: service_msg_direct = "Service response ({svc})".format(svc=service_name) @@ -320,13 +322,13 @@ def magpie_update_services_conflict(conflict_services, services_dict, request_co statuses = dict() for svc_name in conflict_services: statuses[svc_name] = 409 - svc_url_new = services_dict[svc_name]['url'] - svc_url_db = '{magpie}/services/{svc}'.format(magpie=magpie_url, svc=svc_name) + svc_url_new = services_dict[svc_name]["url"] + svc_url_db = "{magpie}/services/{svc}".format(magpie=magpie_url, svc=svc_name) svc_resp = requests.get(svc_url_db, cookies=request_cookies) svc_info = get_json(svc_resp).get(svc_name) - svc_url_old = svc_info['service_url'] + svc_url_old = svc_info["service_url"] if svc_url_old != svc_url_new: - svc_info['service_url'] = svc_url_new + svc_info["service_url"] = svc_url_new res_svc_put = requests.put(svc_url_db, data=svc_info, cookies=request_cookies) statuses[svc_name] = res_svc_put.status_code print_log("[{url_old}] => [{url_new}] Service URL update ({svc}): {resp}" @@ -351,23 +353,23 @@ def magpie_register_services_with_requests(services_dict, push_to_phoenix, usern :return: successful operation status """ magpie_url = get_magpie_url() - curl_cookies = os.path.join(LOGIN_TMP_DIR, 'login_cookie_magpie') + curl_cookies = os.path.join(LOGIN_TMP_DIR, "login_cookie_magpie") session = requests.Session() success = False try: # Need to login first as admin login_url = magpie_url + SigninAPI.path - login_data = {'user_name': username, 'password': password, 'provider_name': provider} - login_loop(login_url, curl_cookies, login_data, 'Magpie login response') + login_data = {"user_name": username, "password": password, "provider_name": provider} + login_loop(login_url, curl_cookies, login_data, "Magpie login response") login_resp = session.post(login_url, data=login_data) if login_resp.status_code != 200: - raise_log('Failed login with specified credentials', logger=LOGGER) + raise_log("Failed login with specified credentials", logger=LOGGER) request_cookies = login_resp.cookies # Register services # Magpie will not overwrite existing services by default, 409 Conflict instead of 201 Created success, statuses_register = register_services(SERVICES_MAGPIE, services_dict, - curl_cookies, 'Magpie register service') + curl_cookies, "Magpie register service") # Service URL update if conflicting and requested if force_update and not success: conflict_services = [svc_name for svc_name, http_code in statuses_register.items() if http_code == 409] @@ -397,14 +399,14 @@ def magpie_register_services_with_db_session(services_dict, db_session, push_to_ force_update=False, update_getcapabilities_permissions=False): db_session.begin(subtransactions=True) existing_services_names = [n[0] for n in db_session.query(models.Service.resource_name)] - magpie_anonymous_user = get_constant('MAGPIE_ANONYMOUS_USER') + magpie_anonymous_user = get_constant("MAGPIE_ANONYMOUS_USER") anonymous_user = UserService.by_user_name(magpie_anonymous_user, db_session=db_session) for svc_name, svc_values in services_dict.items(): - svc_new_url = os.path.expandvars(svc_values['url']) - svc_type = svc_values['type'] + svc_new_url = os.path.expandvars(svc_values["url"]) + svc_type = svc_values["type"] - svc_sync_type = svc_values.get('sync_type') + svc_sync_type = svc_values.get("sync_type") if force_update and svc_name in existing_services_names: svc = models.Service.by_service_name(svc_name, db_session=db_session) if svc.url == svc_new_url: @@ -427,20 +429,25 @@ def magpie_register_services_with_db_session(services_dict, db_session, push_to_ sync_type=svc_sync_type) db_session.add(svc) + getcap_perm_name = Permission.GET_CAPABILITIES.value if update_getcapabilities_permissions and anonymous_user is None: print_log("Cannot update 'getcapabilities' permission of non existing anonymous user", level=logging.WARN, logger=LOGGER) - elif update_getcapabilities_permissions and 'getcapabilities' in service_type_dict[svc_type].permission_names: + elif update_getcapabilities_permissions and getcap_perm_name in SERVICE_TYPE_DICT[svc_type].permission_names: svc = db_session.query(models.Service.resource_id).filter_by(resource_name=svc_name).first() svc_perm_getcapabilities = UserResourcePermissionService.by_resource_user_and_perm( - user_id=anonymous_user.id, perm_name='getcapabilities', - resource_id=svc.resource_id, db_session=db_session + user_id=anonymous_user.id, + perm_name=getcap_perm_name, + resource_id=svc.resource_id, + db_session=db_session ) if svc_perm_getcapabilities is None: - print_log("Adding 'getcapabilities' permission to anonymous user", logger=LOGGER) + print_log("Adding '{}' permission to anonymous user.".format(getcap_perm_name), logger=LOGGER) # noinspection PyArgumentList svc_perm_getcapabilities = models.UserResourcePermission( - user_id=anonymous_user.id, perm_name='getcapabilities', resource_id=svc.resource_id + user_id=anonymous_user.id, + perm_name=getcap_perm_name, + resource_id=svc.resource_id ) db_session.add(svc_perm_getcapabilities) @@ -474,16 +481,17 @@ def magpie_register_services_from_config(service_config_file_path, push_to_phoen Uses the provided DB session to directly update service definitions, or uses API request routes as admin. Optionally pushes updates to Phoenix. """ - services = _load_config(service_config_file_path, 'providers') + services = _load_config(service_config_file_path, "providers") if not services: LOGGER.warning("Services configuration are empty.") return # register services using API POSTs if db_session is None: - admin_usr = get_constant('MAGPIE_ADMIN_USER') - admin_pwd = get_constant('MAGPIE_ADMIN_PASSWORD') - magpie_register_services_with_requests(services, push_to_phoenix, admin_usr, admin_pwd, 'ziggurat', + admin_usr = get_constant("MAGPIE_ADMIN_USER") + admin_pwd = get_constant("MAGPIE_ADMIN_PASSWORD") + local_provider = get_constant("MAGPIE_DEFAULT_PROVIDER") + magpie_register_services_with_requests(services, push_to_phoenix, admin_usr, admin_pwd, local_provider, force_update=force_update, disable_getcapabilities=disable_getcapabilities) @@ -498,8 +506,8 @@ def warn_permission(msg, _i, trail=", skipping...", detail=None, permission=None if detail: trail = "{}\nDetail: [{!s}]".format(trail, detail) if permission: - permission = ' [{!s}]' - LOGGER.log(level, "{!s} [permission #{}]{}{}".format(msg, _i, permission or '', trail or '')) + permission = " [{!s}]" + LOGGER.log(level, "{!s} [permission #{}]{}{}".format(msg, _i, permission or "", trail or "")) def use_request(cookies_or_session): @@ -511,7 +519,7 @@ def parse_resource_path(permission_config_entry, # type: ConfigItem service_info, # type: ConfigItem cookies_or_session=None, # type: CookiesOrSessionType magpie_url=None, # type: Optional[Str] - ): # type: (...) -> Tuple[Union[int, None], bool] + ): # type: (...) -> Tuple[Optional[int], bool] """ Parses the `resource` field of a permission config entry and retrieves the final resource id. Creates missing resources as necessary if they can be automatically resolved. @@ -525,37 +533,37 @@ def parse_resource_path(permission_config_entry, # type: ConfigItem raise ValueError("cannot use cookies without corresponding request URL") resource = None - resource_path = permission_config_entry.get('resource', '') - if resource_path.startswith('/'): + resource_path = permission_config_entry.get("resource", "") + if resource_path.startswith("/"): resource_path = resource_path[1:] - if resource_path.endswith('/'): + if resource_path.endswith("/"): resource_path = resource_path[:-1] if resource_path: try: - svc_name = service_info['service_name'] - svc_type = service_info['service_type'] + svc_name = service_info["service_name"] + svc_type = service_info["service_type"] if use_request(cookies_or_session): res_path = get_magpie_url() + ServiceResourcesAPI.path.format(service_name=svc_name) res_resp = requests.get(res_path, cookies=cookies_or_session) - res_dict = get_json(res_resp)[svc_name]['resources'] + res_dict = get_json(res_resp)[svc_name]["resources"] else: from magpie.api.management.service.service_formats import format_service_resources svc = models.Service.by_service_name(svc_name, db_session=cookies_or_session) res_dict = format_service_resources(svc, show_all_children=True, db_session=cookies_or_session) - parent = res_dict['resource_id'] - child_resources = res_dict['resources'] - for res in resource_path.split('/'): + parent = res_dict["resource_id"] + child_resources = res_dict["resources"] + for res in resource_path.split("/"): # search in existing children resources if len(child_resources): # noinspection PyTypeChecker res_id = list(filter(lambda r: res in [r, child_resources[r]["resource_name"]], child_resources)) if res_id: - res_info = child_resources[res_id[0]] # type: Dict[Str, JsonBody] - child_resources = res_info['children'] # update next sub-resource iteration - parent = res_info['resource_id'] + res_info = child_resources[res_id[0]] # type: Dict[Str, JSON] + child_resources = res_info["children"] # update next sub-resource iteration + parent = res_info["resource_id"] continue # missing resource, attempt creation - svc_res_types = service_type_dict[svc_type].resource_types + svc_res_types = SERVICE_TYPE_DICT[svc_type].resource_types type_count = len(svc_res_types) if type_count != 1: warn_permission("Cannot automatically generate resources", entry_index, @@ -564,7 +572,7 @@ def parse_resource_path(permission_config_entry, # type: ConfigItem raise Exception("Missing resource to apply permission.") # fail fast res_type = svc_res_types[0] if use_request(cookies_or_session): - body = {'resource_name': res, 'resource_type': res_type, 'parent_id': parent} + body = {"resource_name": res, "resource_type": res_type, "parent_id": parent} # noinspection PyUnboundLocalVariable resp = requests.post(res_path, json=body, cookies=cookies_or_session) else: @@ -573,7 +581,7 @@ def parse_resource_path(permission_config_entry, # type: ConfigItem if resp.status_code != 201: resp.raise_for_status() child_resources = {} - parent = get_json(resp)['resource']['resource_id'] + parent = get_json(resp)["resource"]["resource_id"] resource = parent if not resource: raise Exception("Could not extract child resource from resource path.") @@ -591,7 +599,7 @@ def apply_permission_entry(permission_config_entry, # type: ConfigItem entry_index, # type: int resource_id, # type: int cookies_or_session, # type: CookiesOrSessionType - magpie_url, # type: Optional[Str] + magpie_url, # type: Str ): # type: (...) -> None """ Applies the single permission entry retrieved from the permission configuration. @@ -603,18 +611,18 @@ def _apply_request(_usr_name=None, _grp_name=None): """Apply operation using HTTP request.""" action_oper = None if usr_name: - action_oper = UserResourcePermissionsAPI.path.replace('{user_name}', _usr_name) + action_oper = UserResourcePermissionsAPI.path.replace("{user_name}", _usr_name) if grp_name: - action_oper = GroupResourcePermissionsAPI.path.replace('{group_name}', _grp_name) + action_oper = GroupResourcePermissionsAPI.path.replace("{group_name}", _grp_name) if not action_oper: return None if create_perm: action_func = requests.post - action_path = '{url}{path}'.format(url=magpie_url, path=action_oper) - action_body = {'permission_name': perm_name} + action_path = "{url}{path}".format(url=magpie_url, path=action_oper) + action_body = {"permission_name": perm_name} else: action_func = requests.delete - action_path = '{url}{path}/{perm_name}'.format(url=magpie_url, path=action_oper, perm_name=perm_name) + action_path = "{url}{path}/{perm_name}".format(url=magpie_url, path=action_oper, perm_name=perm_name) action_body = {} action_path = action_path.format(resource_id=resource_id) action_resp = action_func(action_path, json=action_body, cookies=cookies_or_session) @@ -641,26 +649,26 @@ def _apply_session(_usr_name=None, _grp_name=None): def _apply_profile(_usr_name=None, _grp_name=None): """Creates the user/group profile as required.""" - usr_data = {'user_name': _usr_name, 'password': '12345', 'email': '{}@mail.com'.format(_usr_name), - 'group_name': get_constant('MAGPIE_ANONYMOUS_GROUP')} + usr_data = {"user_name": _usr_name, "password": "12345", "email": "{}@mail.com".format(_usr_name), + "group_name": get_constant("MAGPIE_ANONYMOUS_GROUP")} if use_request(cookies_or_session): if _usr_name: - path = '{url}{path}'.format(url=magpie_url, path=UsersAPI.path) + path = "{url}{path}".format(url=magpie_url, path=UsersAPI.path) return requests.post(path, json=usr_data) if _grp_name: - path = '{url}{path}'.format(url=magpie_url, path=GroupsAPI.path) - data = {'group_name': _grp_name} + path = "{url}{path}".format(url=magpie_url, path=GroupsAPI.path) + data = {"group_name": _grp_name} return requests.post(path, json=data) else: if _usr_name: from magpie.api.management.user.user_utils import create_user - usr_data['db_session'] = cookies_or_session + usr_data["db_session"] = cookies_or_session return create_user(**usr_data) if _grp_name: from magpie.api.management.group.group_utils import create_group return create_group(_grp_name, cookies_or_session) - def _validate_response(operation, is_create, item_type='Permission'): + def _validate_response(operation, is_create, item_type="Permission"): """Validate action/operation applied.""" # handle HTTPException raised if not islambda(operation): @@ -692,10 +700,10 @@ def _validate_response(operation, is_create, item_type='Permission'): warn_permission("Unknown response [{}]".format(_resp.status_code), entry_index, permission=permission_config_entry, level=logging.ERROR) - create_perm = permission_config_entry['action'] == 'create' - perm_name = permission_config_entry['permission'] - usr_name = permission_config_entry.get('user') - grp_name = permission_config_entry.get('group') + create_perm = permission_config_entry["action"] == "create" + perm_name = permission_config_entry["permission"] + usr_name = permission_config_entry.get("user") + grp_name = permission_config_entry.get("group") _validate_response(lambda: _apply_profile(usr_name, None), is_create=True) _validate_response(lambda: _apply_profile(None, grp_name), is_create=True) @@ -720,7 +728,7 @@ def magpie_register_permissions_from_config(permissions_config, magpie_url=None, .. seealso:: `magpie/permissions.cfg` for specific parameters and operational details. """ - permissions = _load_config(permissions_config, 'permissions') + permissions = _load_config(permissions_config, "permissions") if not permissions: LOGGER.warning("Permissions configuration are empty.") return @@ -737,26 +745,26 @@ def magpie_register_permissions_from_config(permissions_config, magpie_url=None, logging.info("Found {} permissions to update.".format(len(permissions))) for i, perm in enumerate(permissions): # parameter validation - if not isinstance(perm, dict) or not all(f in perm for f in ['permission', 'service']): + if not isinstance(perm, dict) or not all(f in perm for f in ["permission", "service"]): warn_permission("Invalid permission format for [{!s}]".format(perm), i) continue - if perm['permission'] not in permissions_supported: + if perm["permission"] not in Permission.values(): warn_permission("Unknown permission [{!s}]".format(perm['permission']), i) continue - usr_name = perm.get('user') - grp_name = perm.get('group') + usr_name = perm.get("user") + grp_name = perm.get("group") if not any([usr_name, grp_name]): warn_permission("Missing required user and/or group field.", i) continue - if 'action' not in perm: + if "action" not in perm: warn_permission("Unspecified action", i, trail="using default (create)...") - perm['action'] = 'create' - if perm['action'] not in ['create', 'remove']: - warn_permission("Unknown action [{!s}]".format(perm['action']), i) + perm["action"] = "create" + if perm["action"] not in ["create", "remove"]: + warn_permission("Unknown action [{!s}]".format(perm["action"]), i) continue # retrieve service for permissions validation - svc_name = perm['service'] + svc_name = perm["service"] if use_request(cookies_or_session): svc_path = magpie_url + ServiceAPI.path.format(service_name=svc_name) svc_resp = requests.get(svc_path, cookies=cookies_or_session) @@ -777,7 +785,7 @@ def magpie_register_permissions_from_config(permissions_config, magpie_url=None, resource_id, found = parse_resource_path(perm, i, service_info, cookies_or_session, magpie_url) if found: if not resource_id: - resource_id = service_info['resource_id'] + resource_id = service_info["resource_id"] apply_permission_entry(perm, i, resource_id, cookies_or_session, magpie_url) if not use_request(cookies_or_session): diff --git a/magpie/security.py b/magpie/security.py index 643e7d8d4..24df6fefa 100644 --- a/magpie/security.py +++ b/magpie/security.py @@ -1,16 +1,16 @@ from magpie.api.login import esgfopenid, wso2 -from magpie.common import get_logger from magpie.constants import get_constant from magpie.definitions.pyramid_definitions import ( AuthTktAuthenticationPolicy, ACLAuthorizationPolicy, Configurator, asbool ) from magpie.definitions.ziggurat_definitions import groupfinder +from magpie.utils import get_logger from authomatic import Authomatic, provider_id from authomatic.providers import oauth2, openid from typing import TYPE_CHECKING import logging if TYPE_CHECKING: - from magpie.definitions.typedefs import JsonBody # noqa: F401 + from magpie.definitions.typedefs import JSON # noqa: F401 AUTHOMATIC_LOGGER = get_logger('magpie.authomatic', level=logging.DEBUG) @@ -128,7 +128,7 @@ def authomatic_config(request=None): } # Concatenate the configs. - config = {} # type: JsonBody + config = {} # type: JSON config.update(oauth2_config) config.update(openid_config) config.update(esgf_config) diff --git a/magpie/services.py b/magpie/services.py index da0c59ea3..d5dda0f97 100644 --- a/magpie/services.py +++ b/magpie/services.py @@ -10,35 +10,37 @@ ) from magpie.api import api_except as ax from magpie.owsrequest import ows_parser_factory -from magpie import models, permissions as p +from magpie.permissions import Permission +from magpie import models from typing import TYPE_CHECKING from six import with_metaclass if TYPE_CHECKING: - from magpie.definitions.typedefs import Str, List, Dict, Union # noqa: F401 + from magpie.definitions.typedefs import Str, List, Dict, Type, ResourcePermissionType # noqa: F401 from magpie.definitions.pyramid_definitions import Request # noqa: F401 - ResourcePermissionType = Union[models.GroupPermission, models.UserPermission] class ServiceMeta(type): @property def resource_types(cls): - # type: (...) -> List[Str] + # type: (Type[ServiceInterface]) -> List[Str] """Allowed resources types under the service.""" return list(cls.resource_types_permissions.keys()) @property def child_resource_allowed(cls): - # type: (...) -> bool + # type: (Type[ServiceInterface]) -> bool return len(cls.resource_types) > 0 -class ServiceI(with_metaclass(ServiceMeta)): +class ServiceInterface(with_metaclass(ServiceMeta)): + # required service type identifier (unique) + service_type = None # type: Str # required request parameters for the service params_expected = [] # type: List[Str] # global permissions allowed for the service (top-level resource) - permission_names = [] # type: List[Str] + permissions = [] # type: List[Permission] # dict of list for each corresponding allowed resource permissions (children resources) - resource_types_permissions = {} # type: Dict[Str, List[Str]] + resource_types_permissions = {} # type: Dict[models.Resource, List[Permission]] def __init__(self, service, request): self.service = service @@ -62,20 +64,20 @@ def expand_acl(self, resource, user): for outcome, perm_user, perm_name in permission_to_pyramid_acls(permissions): self.acl.append((outcome, perm_user, perm_name,)) else: - user = UserService.by_user_name(get_constant('MAGPIE_ANONYMOUS_USER'), db_session=self.request.db) + user = UserService.by_user_name(get_constant("MAGPIE_ANONYMOUS_USER"), db_session=self.request.db) if user is None: - raise Exception('No Anonymous user in the database') + raise Exception("No Anonymous user in the database") else: permissions = ResourceService.perms_for_user(resource, user, db_session=self.request.db) for outcome, perm_user, perm_name in permission_to_pyramid_acls(permissions): self.acl.append((outcome, EVERYONE, perm_name,)) def permission_requested(self): - # type: (...) -> Str + # type: () -> Str try: - return self.parser.params[u'request'] + return self.parser.params[u"request"] except Exception as e: - # if 'ServiceI', 'params_expected' is empty and will raise a KeyError + # if 'ServiceInterface', 'params_expected' is empty and will raise a KeyError raise NotImplementedError("Exception: [" + repr(e) + "]") def effective_permissions(self, resource, user): @@ -95,18 +97,19 @@ def effective_permissions(self, resource, user): return resource_effective_perms -class ServiceWPS(ServiceI): +class ServiceWPS(ServiceInterface): + service_type = u"wps" - permission_names = [ - p.PERMISSION_GET_CAPABILITIES, - p.PERMISSION_DESCRIBE_PROCESS, - p.PERMISSION_EXECUTE, + permissions = [ + Permission.GET_CAPABILITIES, + Permission.DESCRIBE_PROCESS, + Permission.EXECUTE, ] params_expected = [ - u'service', - u'request', - u'version' + u"service", + u"request", + u"version" ] resource_types_permissions = {} @@ -120,58 +123,59 @@ def __acl__(self): return self.acl -class ServiceWMS(ServiceI): - permission_names = [ - p.PERMISSION_GET_CAPABILITIES, - p.PERMISSION_GET_MAP, - p.PERMISSION_GET_FEATURE_INFO, - p.PERMISSION_GET_LEGEND_GRAPHIC, - p.PERMISSION_GET_METADATA, +class ServiceBaseWMS(ServiceInterface): + permissions = [ + Permission.GET_CAPABILITIES, + Permission.GET_MAP, + Permission.GET_FEATURE_INFO, + Permission.GET_LEGEND_GRAPHIC, + Permission.GET_METADATA, ] params_expected = [ - u'service', - u'request', - u'version', - u'layers', - u'layername', - u'dataset' + u"service", + u"request", + u"version", + u"layers", + u"layername", + u"dataset" ] resource_types_permissions = { - models.Workspace.resource_type_name: [ - p.PERMISSION_GET_CAPABILITIES, - p.PERMISSION_GET_MAP, - p.PERMISSION_GET_FEATURE_INFO, - p.PERMISSION_GET_LEGEND_GRAPHIC, - p.PERMISSION_GET_METADATA, + models.Workspace: [ + Permission.GET_CAPABILITIES, + Permission.GET_MAP, + Permission.GET_FEATURE_INFO, + Permission.GET_LEGEND_GRAPHIC, + Permission.GET_METADATA, ] } def __init__(self, service, request): - super(ServiceWMS, self).__init__(service, request) + super(ServiceBaseWMS, self).__init__(service, request) @property def __acl__(self): raise NotImplementedError -class ServiceNCWMS2(ServiceWMS): +class ServiceNCWMS2(ServiceBaseWMS): + service_type = u"ncwms" resource_types_permissions = { - models.File.resource_type_name: [ - p.PERMISSION_GET_CAPABILITIES, - p.PERMISSION_GET_MAP, - p.PERMISSION_GET_FEATURE_INFO, - p.PERMISSION_GET_LEGEND_GRAPHIC, - p.PERMISSION_GET_METADATA, + models.File: [ + Permission.GET_CAPABILITIES, + Permission.GET_MAP, + Permission.GET_FEATURE_INFO, + Permission.GET_LEGEND_GRAPHIC, + Permission.GET_METADATA, ], - models.Directory.resource_type_name: [ - p.PERMISSION_GET_CAPABILITIES, - p.PERMISSION_GET_MAP, - p.PERMISSION_GET_FEATURE_INFO, - p.PERMISSION_GET_LEGEND_GRAPHIC, - p.PERMISSION_GET_METADATA, + models.Directory: [ + Permission.GET_CAPABILITIES, + Permission.GET_MAP, + Permission.GET_FEATURE_INFO, + Permission.GET_LEGEND_GRAPHIC, + Permission.GET_METADATA, ] } @@ -185,37 +189,37 @@ def __acl__(self): # According to the permission, the resource we want to authorize is not formatted the same way permission_requested = self.permission_requested() netcdf_file = None - if permission_requested == p.PERMISSION_GET_CAPABILITIES: + if permission_requested == Permission.GET_CAPABILITIES: # https://colibri.crim.ca/twitcher/ows/proxy/ncWMS2/wms?SERVICE=WMS&REQUEST=GetCapabilities& # VERSION=1.3.0&DATASET=outputs/ouranos/subdaily/aet/pcp/aet_pcp_1961.nc - if 'dataset' in self.parser.params.keys(): - netcdf_file = self.parser.params['dataset'] + if "dataset" in self.parser.params.keys(): + netcdf_file = self.parser.params["dataset"] - elif permission_requested == p.PERMISSION_GET_MAP: + elif permission_requested == Permission.GET_MAP: # https://colibri.crim.ca/ncWMS2/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng& # TRANSPARENT=TRUE&ABOVEMAXCOLOR=extend&STYLES=default-scalar%2Fseq-Blues& # LAYERS=outputs/ouranos/subdaily/aet/pcp/aet_pcp_1961.nc/PCP&EPSG=4326 - netcdf_file = self.parser.params['layers'] + netcdf_file = self.parser.params["layers"] if netcdf_file: - netcdf_file = netcdf_file.rsplit('/', 1)[0] + netcdf_file = netcdf_file.rsplit("/", 1)[0] - elif permission_requested == p.PERMISSION_GET_METADATA: + elif permission_requested == Permission.GET_METADATA: # https://colibri.crim.ca/ncWMS2/wms?request=GetMetadata&item=layerDetails& # layerName=outputs/ouranos/subdaily/aet/pcp/aet_pcp_1961.nc/PCP - netcdf_file = self.parser.params['layername'] + netcdf_file = self.parser.params["layername"] if netcdf_file: - netcdf_file = netcdf_file.rsplit('/', 1)[0] + netcdf_file = netcdf_file.rsplit("/", 1)[0] else: return [(ALLOW, EVERYONE, permission_requested,)] if netcdf_file: - ax.verify_param('outputs/', paramCompare=netcdf_file, httpError=HTTPNotFound, - msgOnFail='outputs/ is not in path', notIn=True) - netcdf_file = netcdf_file.replace('outputs/', 'birdhouse/') + ax.verify_param("outputs/", paramCompare=netcdf_file, httpError=HTTPNotFound, + msgOnFail="'outputs/' is not in path", notIn=True) + netcdf_file = netcdf_file.replace("outputs/", "birdhouse/") db_session = self.request.db - path_elems = netcdf_file.split('/') + path_elems = netcdf_file.split("/") new_child = self.service while new_child and path_elems: elem_name = path_elems.pop(0) @@ -227,10 +231,11 @@ def __acl__(self): return self.acl -class ServiceGeoserver(ServiceWMS): +class ServiceGeoserverWMS(ServiceBaseWMS): + service_type = u"geoserverwms" def __init__(self, service, request): - super(ServiceGeoserver, self).__init__(service, request) + super(ServiceGeoserverWMS, self).__init__(service, request) @property def __acl__(self): @@ -245,16 +250,16 @@ def __acl__(self): # here we need to check the workspace in the path request_type = self.permission_requested() - if request_type == p.PERMISSION_GET_CAPABILITIES: - path_elem = self.request.path.split('/') - wms_idx = path_elem.index('wms') - if path_elem[wms_idx - 1] != 'geoserver': + if request_type == Permission.GET_CAPABILITIES: + path_elem = self.request.path.split("/") + wms_idx = path_elem.index("wms") + if path_elem[wms_idx - 1] != "geoserver": workspace_name = path_elem[wms_idx - 1] else: - workspace_name = '' + workspace_name = "" else: - layer_name = self.parser.params['layers'] - workspace_name = layer_name.split(':')[0] + layer_name = self.parser.params["layers"] + workspace_name = layer_name.split(":")[0] # load workspace resource from the database workspace = models.find_children_by_name(child_name=workspace_name, @@ -265,9 +270,13 @@ def __acl__(self): return self.acl -class ServiceAccess(ServiceI): - permission_names = [p.PERMISSION_ACCESS] +class ServiceAccess(ServiceInterface): + service_type = u"access" + + permissions = [Permission.ACCESS] + params_expected = [] + resource_types_permissions = {} def __init__(self, service, request): @@ -279,16 +288,18 @@ def __acl__(self): return self.acl def permission_requested(self): - return p.PERMISSION_ACCESS + return Permission.ACCESS -class ServiceAPI(ServiceI): - permission_names = models.Route.permission_names +class ServiceAPI(ServiceInterface): + service_type = u"api" + + permissions = models.Route.permissions params_expected = [] resource_types_permissions = { - models.Route.resource_type_name: models.Route.permission_names + models.Route: models.Route.permissions } def __init__(self, service, request): @@ -302,7 +313,7 @@ def route_acl(self, sub_api_route=None): self.expand_acl(self.service, self.request.user) match_index = 0 - route_parts = self.request.path.split('/') + route_parts = self.request.path.split("/") route_api_base = self.service.resource_name if sub_api_route is None else sub_api_route if self.service.resource_name in route_parts and route_api_base in route_parts: @@ -324,45 +335,46 @@ def route_acl(self, sub_api_route=None): # process read/write-match specific permission access # (convert exact route 'match' to read/write counterparts only if matching last item's permissions) for i in range(match_index, len(self.acl)): - if self.acl[i][2] == p.PERMISSION_READ_MATCH: - self.acl[i] = (self.acl[i][0], self.acl[i][1], p.PERMISSION_READ) - if self.acl[i][2] == p.PERMISSION_WRITE_MATCH: - self.acl[i] = (self.acl[i][0], self.acl[i][1], p.PERMISSION_WRITE) + if self.acl[i][2] == Permission.READ_MATCH: + self.acl[i] = (self.acl[i][0], self.acl[i][1], Permission.READ) + if self.acl[i][2] == Permission.WRITE_MATCH: + self.acl[i] = (self.acl[i][0], self.acl[i][1], Permission.WRITE) return self.acl def permission_requested(self): # only read/write are used for 'real' access control, 'match' permissions must be updated accordingly - if self.request.method.upper() in ['GET', 'HEAD']: - return p.PERMISSION_READ - return p.PERMISSION_WRITE + if self.request.method.upper() in ["GET", "HEAD"]: + return Permission.READ + return Permission.WRITE def effective_permissions(self, resource, user): # if 'match' permissions are on the specified 'resource', keep them # otherwise, keep only the non 'match' variations from inherited parent resources permissions resource_effective_perms = super(ServiceAPI, self).effective_permissions(resource, user) return filter(lambda perm: - (perm.perm_name in [p.PERMISSION_READ, p.PERMISSION_WRITE]) or - (perm.perm_name in [p.PERMISSION_READ_MATCH, p.PERMISSION_WRITE_MATCH] and + (perm.perm_name in [Permission.READ.value, Permission.WRITE.value]) or + (perm.perm_name in [Permission.READ_MATCH.value, Permission.WRITE_MATCH.value] and perm.resource.resource_id == resource.resource_id), resource_effective_perms) -class ServiceWFS(ServiceI): +class ServiceWFS(ServiceInterface): + service_type = u"wfs" - permission_names = [ - p.PERMISSION_GET_CAPABILITIES, - p.PERMISSION_DESCRIBE_FEATURE_TYPE, - p.PERMISSION_GET_FEATURE, - p.PERMISSION_LOCK_FEATURE, - p.PERMISSION_TRANSACTION, + permissions = [ + Permission.GET_CAPABILITIES, + Permission.DESCRIBE_FEATURE_TYPE, + Permission.GET_FEATURE, + Permission.LOCK_FEATURE, + Permission.TRANSACTION, ] params_expected = [ - u'service', - u'request', - u'version', - u'typenames' + u"service", + u"request", + u"version", + u"typenames" ] resource_types_permissions = {} @@ -374,16 +386,16 @@ def __init__(self, service, request): def __acl__(self): self.expand_acl(self.service, self.request.user) request_type = self.permission_requested() - if request_type == p.PERMISSION_GET_CAPABILITIES: - path_elem = self.request.path.split('/') - wms_idx = path_elem.index('wfs') - if path_elem[wms_idx - 1] != 'geoserver': + if request_type == Permission.GET_CAPABILITIES: + path_elem = self.request.path.split("/") + wms_idx = path_elem.index("wfs") + if path_elem[wms_idx - 1] != "geoserver": workspace_name = path_elem[wms_idx - 1] else: - workspace_name = '' + workspace_name = "" else: - layer_name = self.parser.params['typenames'] - workspace_name = layer_name.split(':')[0] + layer_name = self.parser.params["typenames"] + workspace_name = layer_name.split(":")[0] # load workspace resource from the database workspace = models.find_children_by_name(child_name=workspace_name, @@ -394,20 +406,21 @@ def __acl__(self): return self.acl -class ServiceTHREDDS(ServiceI): +class ServiceTHREDDS(ServiceInterface): + service_type = u"thredds" - permission_names = [ - p.PERMISSION_READ, - p.PERMISSION_WRITE, + permissions = [ + Permission.READ, + Permission.WRITE, ] params_expected = [ - u'request' + u"request" ] resource_types_permissions = { - models.Directory.resource_type_name: permission_names, - models.File.resource_type_name: permission_names, + models.Directory: permissions, + models.File: permissions, } def __init__(self, service, request): @@ -416,16 +429,16 @@ def __init__(self, service, request): @property def __acl__(self): self.expand_acl(self.service, self.request.user) - elems = self.request.path.split('/') - - if 'fileServer' in elems: - first_idx = elems.index('fileServer') - elif 'dodsC' in elems: - first_idx = elems.index('dodsC') - elems[-1] = elems[-1].replace('.html', '') - elif 'catalog' in elems: - first_idx = elems.index('catalog') - elif elems[-1] == 'catalog.html': + elems = self.request.path.split("/") + + if "fileServer" in elems: + first_idx = elems.index("fileServer") + elif "dodsC" in elems: + first_idx = elems.index("dodsC") + elems[-1] = elems[-1].replace(".html", "") + elif "catalog" in elems: + first_idx = elems.index("catalog") + elif elems[-1] == "catalog.html": first_idx = elems.index(self.service.resource_name) - 1 else: return self.acl @@ -443,38 +456,25 @@ def __acl__(self): return self.acl def permission_requested(self): - return u'read' + return Permission.READ.value -service_type_dict = { - u'access': ServiceAccess, # noqa: E241 - u'api': ServiceAPI, # noqa: E241 - u'geoserverwms': ServiceGeoserver, # noqa: E241 - u'ncwms': ServiceNCWMS2, # noqa: E241 - u'thredds': ServiceTHREDDS, # noqa: E241 - u'wfs': ServiceWFS, # noqa: E241 - u'wps': ServiceWPS, # noqa: E241 -} +SERVICE_TYPE_DICT = dict() +for svc in [ServiceAccess, ServiceAPI, ServiceGeoserverWMS, ServiceNCWMS2, ServiceTHREDDS, ServiceWFS, ServiceWPS]: + SERVICE_TYPE_DICT[svc.service_type] = svc def service_factory(service, request): - # type: (models.Service, Request) -> ServiceI + # type: (models.Service, Request) -> ServiceInterface """Retrieve the specific service class from the provided database service entry.""" ax.verify_param(service, paramCompare=models.Service, ofType=True, - httpError=HTTPBadRequest, content={u'service': repr(service)}, + httpError=HTTPBadRequest, content={u"service": repr(service)}, msgOnFail="Cannot process invalid service object") service_type = ax.evaluate_call(lambda: service.type, httpError=HTTPInternalServerError, msgOnFail="Cannot retrieve service type from object") - ax.verify_param(service_type, isIn=True, paramCompare=service_type_dict.keys(), - httpError=HTTPNotImplemented, content={u'service_type': service_type}, + ax.verify_param(service_type, isIn=True, paramCompare=SERVICE_TYPE_DICT.keys(), + httpError=HTTPNotImplemented, content={u"service_type": service_type}, msgOnFail="Undefined service type mapping to service object") - return ax.evaluate_call(lambda: service_type_dict[service_type](service, request), + return ax.evaluate_call(lambda: SERVICE_TYPE_DICT[service_type](service, request), httpError=HTTPInternalServerError, msgOnFail="Failed to find requested service type.") - - -def get_all_service_permission_names(): - all_permission_names_list = set() - for service_type in service_type_dict.keys(): - all_permission_names_list.update(service_type_dict[service_type].permission_names) - return all_permission_names_list diff --git a/magpie/ui/__init__.py b/magpie/ui/__init__.py index 12167278b..15ad98333 100644 --- a/magpie/ui/__init__.py +++ b/magpie/ui/__init__.py @@ -1,13 +1,12 @@ -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) def includeme(config): - LOGGER.info('Adding ui routes ...') + LOGGER.info("Adding ui routes ...") # Add all the admin ui routes - config.include('magpie.ui.login') - config.include('magpie.ui.home') - config.include('magpie.ui.management') - config.include('magpie.ui.swagger') - # config.scan() + config.include("magpie.ui.login") + config.include("magpie.ui.home") + config.include("magpie.ui.management") + config.include("magpie.ui.swagger") diff --git a/magpie/ui/home/__init__.py b/magpie/ui/home/__init__.py index 767ac0eaf..8ae4d0e0c 100644 --- a/magpie/ui/home/__init__.py +++ b/magpie/ui/home/__init__.py @@ -1,5 +1,5 @@ from magpie.definitions.pyramid_definitions import IAuthenticationPolicy, Authenticated -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) diff --git a/magpie/ui/home/static/style.css b/magpie/ui/home/static/style.css index ce01b2b40..77768b34d 100644 --- a/magpie/ui/home/static/style.css +++ b/magpie/ui/home/static/style.css @@ -464,7 +464,8 @@ ul.breadcrumb li a:hover { .header { background: #000000; background: black; /* For browsers that do not support gradients */ - background: -webkit-linear-gradient(left bottom, black, gray); /* Safari 5.1 to 6.0 */ + background: -webkit-gradient(bottom top, black, gray); /* Chrome, Safari4+ */ + background: -webkit-linear-gradient(left bottom, black, gray); /* Chrome10+, Safari5.1+ */ background: -o-linear-gradient(bottom top, black, gray); /* Opera 11.1 to 12.0 */ background: -moz-linear-gradient(bottom top, black, gray); /* Firefox 3.6 to 15 */ background: -ms-linear-gradient(bottom top, black, gray); /* IE10+ */ diff --git a/magpie/ui/login/__init__.py b/magpie/ui/login/__init__.py index db0e5852a..fe4eb8350 100755 --- a/magpie/ui/login/__init__.py +++ b/magpie/ui/login/__init__.py @@ -1,4 +1,4 @@ -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) diff --git a/magpie/ui/login/views.py b/magpie/ui/login/views.py index e05754062..bf10a40f4 100755 --- a/magpie/ui/login/views.py +++ b/magpie/ui/login/views.py @@ -1,5 +1,4 @@ from magpie.api import api_rest_schemas as schemas -from magpie.common import get_json from magpie.definitions.pyramid_definitions import ( NO_PERMISSION_REQUIRED, view_config, @@ -12,7 +11,7 @@ ) from magpie.ui.utils import check_response, request_api from magpie.ui.home import add_template_data -from magpie.utils import get_magpie_url +from magpie.utils import get_magpie_url, get_json import requests @@ -22,62 +21,61 @@ def __init__(self, request): self.magpie_url = get_magpie_url(request.registry) def request_providers_json(self): - resp = request_api(self.request, schemas.ProvidersAPI.path, 'GET') + resp = request_api(self.request, schemas.ProvidersAPI.path, "GET") check_response(resp) - return get_json(resp)['providers'] + return get_json(resp)["providers"] - @view_config(route_name='login', renderer='templates/login.mako', permission=NO_PERMISSION_REQUIRED) + @view_config(route_name="login", renderer="templates/login.mako", permission=NO_PERMISSION_REQUIRED) def login(self): - external_providers = self.request_providers_json()['external'] + external_providers = self.request_providers_json()["external"] return_data = { - u'external_providers': external_providers, - u'user_name_external': self.request.POST.get('user_name', u''), - u'user_name_internal': self.request.POST.get('user_name', u''), - u'invalid_credentials': False, - u'error': False, + u"external_providers": external_providers, + u"user_name_external": self.request.POST.get("user_name", u""), + u"user_name_internal": self.request.POST.get("user_name", u""), + u"invalid_credentials": False, + u"error": False, } try: - if 'submit' in self.request.POST: + if "submit" in self.request.POST: data = {} for key in self.request.POST: data[key] = self.request.POST.get(key) - return_data[u'provider_name'] = data.get('provider_name', '').lower() - is_external = return_data[u'provider_name'] in [p.lower() for p in external_providers] + return_data[u"provider_name"] = data.get("provider_name", "").lower() + is_external = return_data[u"provider_name"] in [p.lower() for p in external_providers] if is_external: - return_data[u'user_name_internal'] = u'' + return_data[u"user_name_internal"] = u"" else: - return_data[u'user_name_external'] = u'' + return_data[u"user_name_external"] = u"" # keep using the external requests for external providers if is_external: - signin_url = '{}{}'.format(self.magpie_url, schemas.SigninAPI.path) + signin_url = "{}{}".format(self.magpie_url, schemas.SigninAPI.path) response = requests.post(signin_url, data=data, allow_redirects=True) # use sub request for internal to avoid retry connection errors else: - response = request_api(self.request, schemas.SigninAPI.path, 'POST', data=data) + response = request_api(self.request, schemas.SigninAPI.path, "POST", data=data) if response.status_code in (HTTPOk.code, HTTPFound.code): if is_external: pyr_res = Response(body=response.content, headers=response.headers) for cookie in response.cookies: pyr_res.set_cookie(name=cookie.name, value=cookie.value, overwrite=True) - is_external = response.url != '{}{}'.format(self.magpie_url, schemas.SigninAPI.path) return HTTPFound(response.url, headers=pyr_res.headers) - return HTTPFound(location=self.request.route_url('home'), headers=response.headers) + return HTTPFound(location=self.request.route_url("home"), headers=response.headers) elif response.status_code == HTTPUnauthorized.code: - return_data[u'invalid_credentials'] = True + return_data[u"invalid_credentials"] = True else: - return_data[u'error'] = True + return_data[u"error"] = True return add_template_data(self.request, return_data) except Exception as e: return HTTPInternalServerError(detail=repr(e)) return add_template_data(self.request, data=return_data) - @view_config(route_name='logout', renderer='templates/login.mako', permission=NO_PERMISSION_REQUIRED) + @view_config(route_name="logout", renderer="templates/login.mako", permission=NO_PERMISSION_REQUIRED) def logout(self): # Flush cookies and return to home - request_api(self.request, schemas.SignoutAPI.path, 'GET') - return HTTPFound(location=self.request.route_url('home'), headers=forget(self.request)) + request_api(self.request, schemas.SignoutAPI.path, "GET") + return HTTPFound(location=self.request.route_url("home"), headers=forget(self.request)) diff --git a/magpie/ui/management/__init__.py b/magpie/ui/management/__init__.py index 65b01fce0..876c04119 100644 --- a/magpie/ui/management/__init__.py +++ b/magpie/ui/management/__init__.py @@ -1,18 +1,18 @@ -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) def includeme(config): from magpie.ui.management.views import ManagementViews - LOGGER.info('Adding management ...') - config.add_route(ManagementViews.view_groups.__name__, '/ui/groups') - config.add_route(ManagementViews.add_group.__name__, '/ui/groups/add') - config.add_route(ManagementViews.edit_group.__name__, '/ui/groups/{group_name}/{cur_svc_type}') - config.add_route(ManagementViews.view_users.__name__, '/ui/users') - config.add_route(ManagementViews.add_user.__name__, '/ui/users/add') - config.add_route(ManagementViews.edit_user.__name__, '/ui/users/{user_name}/{cur_svc_type}') - config.add_route(ManagementViews.view_services.__name__, '/ui/services/{cur_svc_type}') - config.add_route(ManagementViews.add_service.__name__, '/ui/services/{cur_svc_type}/add') - config.add_route(ManagementViews.edit_service.__name__, '/ui/services/{cur_svc_type}/{service_name}') - config.add_route(ManagementViews.add_resource.__name__, '/ui/services/{cur_svc_type}/{service_name}/add/{resource_id}') + LOGGER.info("Adding management ...") + config.add_route(ManagementViews.view_groups.__name__, "/ui/groups") + config.add_route(ManagementViews.add_group.__name__, "/ui/groups/add") + config.add_route(ManagementViews.edit_group.__name__, "/ui/groups/{group_name}/{cur_svc_type}") + config.add_route(ManagementViews.view_users.__name__, "/ui/users") + config.add_route(ManagementViews.add_user.__name__, "/ui/users/add") + config.add_route(ManagementViews.edit_user.__name__, "/ui/users/{user_name}/{cur_svc_type}") + config.add_route(ManagementViews.view_services.__name__, "/ui/services/{cur_svc_type}") + config.add_route(ManagementViews.add_service.__name__, "/ui/services/{cur_svc_type}/add") + config.add_route(ManagementViews.edit_service.__name__, "/ui/services/{cur_svc_type}/{service_name}") + config.add_route(ManagementViews.add_resource.__name__, "/ui/services/{cur_svc_type}/{service_name}/add/{resource_id}") config.scan() diff --git a/magpie/ui/management/templates/edit_service.mako b/magpie/ui/management/templates/edit_service.mako index 426a30bc2..c28239c31 100644 --- a/magpie/ui/management/templates/edit_service.mako +++ b/magpie/ui/management/templates/edit_service.mako @@ -7,9 +7,9 @@ % else:
% endif - % if 'id' in value.keys(): - % if int(value['id']) in resources_id_type.keys(): - % if not resources_id_type[int(value['id'])] in resources_no_child: + % if "id" in value.keys(): + % if int(value["id"]) in resources_id_type.keys(): + % if not resources_id_type[int(value["id"])] in resources_no_child:
% else:
@@ -49,9 +49,9 @@ %endif
+ onclick="this.parentElement.style.display="none";"> + onclick="this.parentElement.style.display="none";">
@@ -108,7 +108,7 @@

Protected URL: - %if edit_mode == 'edit_url': + %if edit_mode == "edit_url": diff --git a/magpie/ui/management/views.py b/magpie/ui/management/views.py index dbb693d21..b9c8721fb 100644 --- a/magpie/ui/management/views.py +++ b/magpie/ui/management/views.py @@ -1,4 +1,5 @@ from magpie.api import api_rest_schemas as schemas +from magpie.constants import get_constant from magpie.definitions.pyramid_definitions import ( asbool, view_config, @@ -8,16 +9,14 @@ HTTPNotFound, HTTPConflict, ) -from magpie.constants import get_constant -from magpie.common import get_json, get_logger, JSON_TYPE from magpie.helpers.sync_resources import OUT_OF_SYNC from magpie.helpers import sync_resources -from magpie.models import resource_type_dict, remote_resource_tree_service # TODO: remove, implement getters via API +from magpie.models import RESOURCE_TYPE_DICT, remote_resource_tree_service # TODO: remove, implement getters via API from magpie.ui.utils import check_response, request_api, error_badrequest from magpie.ui.home import add_template_data -from magpie import register, __meta__ +from magpie.utils import get_json, get_logger, CONTENT_TYPE_JSON +from magpie import register from collections import OrderedDict -from distutils.version import LooseVersion import datetime import humanize import json @@ -49,15 +48,15 @@ def get_group_users(self, group_name): @error_badrequest def get_user_groups(self, user_name): path = schemas.UserGroupsAPI.path.format(user_name=user_name) - resp = request_api(self.request, path, 'GET') + resp = request_api(self.request, path, "GET") check_response(resp) - return get_json(resp)['group_names'] + return get_json(resp)["group_names"] @error_badrequest def get_user_names(self): - resp = request_api(self.request, schemas.UsersAPI.path, 'GET') + resp = request_api(self.request, schemas.UsersAPI.path, "GET") check_response(resp) - return get_json(resp)['user_names'] + return get_json(resp)["user_names"] @error_badrequest def get_user_emails(self): @@ -65,12 +64,9 @@ def get_user_emails(self): emails = list() for user in user_names: path = schemas.UserAPI.path.format(user_name=user) - resp = request_api(self.request, path, 'GET') + resp = request_api(self.request, path, "GET") check_response(resp) - if LooseVersion(__meta__.__version__) >= LooseVersion('0.6.3'): - user_email = get_json(resp)['user']['email'] - else: - user_email = get_json(resp)['email'] + user_email = get_json(resp)["user"]["email"] emails.append(user_email) return emails @@ -79,18 +75,18 @@ def get_resource_types(self): :return: dictionary of all resources as {id: 'resource_type'} :rtype: dict """ - resp = request_api(self.request, schemas.ResourcesAPI.path, 'GET') + resp = request_api(self.request, schemas.ResourcesAPI.path, "GET") check_response(resp) - res_dic = self.default_get(get_json(resp), 'resources', dict()) + res_dic = self.default_get(get_json(resp), "resources", dict()) res_ids = dict() self.flatten_tree_resource(res_dic, res_ids) return res_ids @error_badrequest def get_services(self, cur_svc_type): - resp = request_api(self.request, schemas.ServicesAPI.path, 'GET') + resp = request_api(self.request, schemas.ServicesAPI.path, "GET") check_response(resp) - all_services = get_json(resp)['services'] + all_services = get_json(resp)["services"] svc_types = sorted(all_services.keys()) if cur_svc_type not in svc_types: cur_svc_type = svc_types[0] @@ -100,48 +96,48 @@ def get_services(self, cur_svc_type): @error_badrequest def get_service_data(self, service_name): path = schemas.ServiceAPI.path.format(service_name=service_name) - resp = request_api(self.request, path, 'GET') + resp = request_api(self.request, path, "GET") check_response(resp) - return get_json(resp)['service'] + return get_json(resp)["service"] def get_service_types(self): - svc_types_resp = request_api(self.request, schemas.ServiceTypesAPI.path, 'GET') - return get_json(svc_types_resp)['service_types'] + svc_types_resp = request_api(self.request, schemas.ServiceTypesAPI.path, "GET") + return get_json(svc_types_resp)["service_types"] @error_badrequest def update_service_name(self, old_service_name, new_service_name, service_push): svc_data = self.get_service_data(old_service_name) - svc_data['service_name'] = new_service_name - svc_data['resource_name'] = new_service_name - svc_data['service_push'] = service_push - svc_id = str(svc_data['resource_id']) + svc_data["service_name"] = new_service_name + svc_data["resource_name"] = new_service_name + svc_data["service_push"] = service_push + svc_id = str(svc_data["resource_id"]) path = schemas.ResourceAPI.path.format(resource_id=svc_id) - resp = request_api(self.request, path, 'PUT', data=svc_data) + resp = request_api(self.request, path, "PUT", data=svc_data) check_response(resp) @error_badrequest def update_service_url(self, service_name, new_service_url, service_push): svc_data = self.get_service_data(service_name) - svc_data['service_url'] = new_service_url - svc_data['service_push'] = service_push + svc_data["service_url"] = new_service_url + svc_data["service_push"] = service_push path = schemas.ServiceAPI.path.format(service_name=service_name) - resp = request_api(self.request, path, 'PUT', data=svc_data) + resp = request_api(self.request, path, "PUT", data=svc_data) check_response(resp) @error_badrequest def goto_service(self, resource_id): path = schemas.ResourceAPI.path.format(resource_id=resource_id) - resp = request_api(self.request, path, 'GET') + resp = request_api(self.request, path, "GET") check_response(resp) body = get_json(resp) - svc_name = body['resource']['resource_name'] + svc_name = body["resource"]["resource_name"] # get service type instead of 'cur_svc_type' in case of 'default' ('cur_svc_type' not set yet) path = schemas.ServiceAPI.path.format(service_name=svc_name) - resp = request_api(self.request, path, 'GET') + resp = request_api(self.request, path, "GET") check_response(resp) body = get_json(resp) - svc_type = body['service']['service_type'] - return HTTPFound(self.request.route_url('edit_service', service_name=svc_name, cur_svc_type=svc_type)) + svc_type = body["service"]["service_type"] + return HTTPFound(self.request.route_url("edit_service", service_name=svc_name, cur_svc_type=svc_type)) @staticmethod def flatten_tree_resource(resource_node, resource_dict): @@ -859,11 +855,11 @@ def edit_service(self): check_response(resp) svc_body = get_json(resp)['service'] - # TODO: use an API request instead of direct access to `resource_type_dict` + # TODO: use an API request instead of direct access to `RESOURCE_TYPE_DICT` service_info['resources'] = resources service_info['resources_id_type'] = resources_id_type - service_info['resources_no_child'] = [res for res in resource_type_dict - if not resource_type_dict[res].child_resource_allowed] + service_info['resources_no_child'] = [res for res in RESOURCE_TYPE_DICT + if not RESOURCE_TYPE_DICT[res].child_resource_allowed] service_info['service_no_child'] = not svc_body['resource_child_allowed'] return add_template_data(self.request, service_info) @@ -881,7 +877,7 @@ def add_resource(self): u'resource_type': resource_type, u'parent_id': int(resource_id) if resource_id else None} resp = request_api(self.request, schemas.ResourcesAPI.path, 'POST', data=data, - headers={'Content-Type': JSON_TYPE}) + headers={'Content-Type': CONTENT_TYPE_JSON}) check_response(resp) return HTTPFound(self.request.route_url('edit_service', diff --git a/magpie/ui/swagger/__init__.py b/magpie/ui/swagger/__init__.py index 481143c86..a8dc6b893 100644 --- a/magpie/ui/swagger/__init__.py +++ b/magpie/ui/swagger/__init__.py @@ -1,15 +1,15 @@ from magpie.api import api_rest_schemas as s from magpie.definitions.pyramid_definitions import NO_PERMISSION_REQUIRED from magpie.ui.swagger.views import api_swagger -from magpie.common import get_logger +from magpie.utils import get_logger LOGGER = get_logger(__name__) def includeme(config): - LOGGER.info('Adding swagger ...') + LOGGER.info("Adding swagger ...") config.add_route(**s.service_api_route_info(s.SwaggerAPI)) config.add_route(**s.service_api_route_info(s.SwaggerGenerator)) - config.add_view(s.api_schema, route_name=s.SwaggerGenerator.name, request_method='GET', - renderer='json', permission=NO_PERMISSION_REQUIRED) + config.add_view(s.api_schema, route_name=s.SwaggerGenerator.name, request_method="GET", + renderer="json", permission=NO_PERMISSION_REQUIRED) config.add_view(api_swagger, route_name=s.SwaggerAPI.name, - renderer='templates/swagger_ui.mako', permission=NO_PERMISSION_REQUIRED) + renderer="templates/swagger_ui.mako", permission=NO_PERMISSION_REQUIRED) diff --git a/magpie/ui/swagger/views.py b/magpie/ui/swagger/views.py index 7b61e2a42..73556b0d6 100644 --- a/magpie/ui/swagger/views.py +++ b/magpie/ui/swagger/views.py @@ -3,14 +3,15 @@ import os +# noinspection PyUnusedLocal @s.SwaggerAPI.get(tags=[s.APITag]) def api_swagger(request): """ Swagger UI route to display the Magpie REST API schemas. """ - swagger_versions_dir = '{}'.format(os.path.abspath(os.path.join(MAGPIE_MODULE_DIR, 'ui/swagger/versions'))) - swagger_ui_path = s.SwaggerGenerator.path.lstrip('/') - return_data = {'api_title': s.TitleAPI, - 'api_schema_path': swagger_ui_path, - 'api_schema_versions_dir': swagger_versions_dir} + swagger_versions_dir = "{}".format(os.path.abspath(os.path.join(MAGPIE_MODULE_DIR, "ui/swagger/versions"))) + swagger_ui_path = s.SwaggerGenerator.path.lstrip("/") + return_data = {"api_title": s.TitleAPI, + "api_schema_path": swagger_ui_path, + "api_schema_versions_dir": swagger_versions_dir} return return_data diff --git a/magpie/ui/utils.py b/magpie/ui/utils.py index 09f3c0c6a..4c6b86ae8 100644 --- a/magpie/ui/utils.py +++ b/magpie/ui/utils.py @@ -1,9 +1,9 @@ from magpie.definitions.pyramid_definitions import exception_response, Request, HTTPBadRequest -from magpie.common import get_header, JSON_TYPE +from magpie.utils import get_header, CONTENT_TYPE_JSON from typing import TYPE_CHECKING import json if TYPE_CHECKING: - from magpie.definitions.typedefs import Str, JsonBody, CookiesType, HeadersType, Optional # noqa: F401 + from magpie.definitions.typedefs import Str, JSON, CookiesType, HeadersType, Optional # noqa: F401 from magpie.definitions.pyramid_definitions import Response # noqa: F401 @@ -16,7 +16,7 @@ def check_response(response): def request_api(request, # type: Request path, # type: Str method='GET', # type: Optional[Str] - data=None, # type: Optional[JsonBody] + data=None, # type: Optional[JSON] headers=None, # type: Optional[HeadersType] cookies=None, # type: Optional[CookiesType] ): # type: (...) -> Response @@ -26,7 +26,7 @@ def request_api(request, # type: Request Some information is retrieved from ``request`` to pass down to the sub-request (eg: headers, cookies). If they are passed as argument, corresponding values will override the ones found in ``request``. - All sub-requests to the API are assumed to be of ``magpie.common.JSON_TYPE``. + All sub-requests to the API are assumed to be of ``magpie.common.CONTENT_TYPE_JSON``. """ method = method.upper() extra_kwargs = {'method': method} @@ -34,7 +34,7 @@ def request_api(request, # type: Request if headers: headers = dict(headers) if not headers and not request.headers: - headers = {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE} + headers = {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON} if not headers: headers = request.headers # although no body is required per-say for HEAD/GET requests, add it if missing @@ -43,7 +43,7 @@ def request_api(request, # type: Request # of local/remote testing with corresponding `webtest.TestApp`/`requests.Request` if not data: data = u'' - if isinstance(data, dict) and get_header('Content-Type', headers, split=[',', ';']) == JSON_TYPE: + if isinstance(data, dict) and get_header('Content-Type', headers, split=[',', ';']) == CONTENT_TYPE_JSON: data = json.dumps(data) if isinstance(cookies, dict): diff --git a/magpie/utils.py b/magpie/utils.py index 60ec24441..3712b0f00 100644 --- a/magpie/utils.py +++ b/magpie/utils.py @@ -1,23 +1,179 @@ -from magpie.common import raise_log, get_logger, JSON_TYPE +#!/usr/bin/env python +# -*- coding: utf-8 -*- from magpie.constants import get_constant from magpie.definitions.pyramid_definitions import ( - HTTPOk, HTTPClientError, ConfigurationError, Configurator, Registry, Request + HTTPOk, HTTPClientError, HTTPException, ConfigurationError, Configurator, Registry, Request, Response, truthy ) from six.moves.urllib.parse import urlparse -from typing import TYPE_CHECKING from requests.cookies import RequestsCookieJar -import logging +from requests.structures import CaseInsensitiveDict +from webob.headers import ResponseHeaders, EnvironHeaders +from distutils.dir_util import mkpath +from six.moves import configparser +from typing import TYPE_CHECKING import requests +import logging +import types +import six +import sys +import os if TYPE_CHECKING: - from magpie.definitions.typedefs import Str, CookiesType, SettingsType, SettingsContainer, Optional # noqa: F401 + from magpie.definitions.typedefs import ( # noqa: F401 + Any, Str, List, Optional, Type, Union, + AnyResponseType, AnyHeadersType, LoggerType, CookiesType, SettingsType, SettingsContainer, + ) + +CONTENT_TYPE_ANY = "*/*" +CONTENT_TYPE_JSON = "application/json" +CONTENT_TYPE_HTML = "text/html" +CONTENT_TYPE_PLAIN = "text/plain" +SUPPORTED_CONTENT_TYPES = [CONTENT_TYPE_JSON, CONTENT_TYPE_HTML, CONTENT_TYPE_PLAIN] + + +def get_logger(name, level=None): + """ + Immediately sets the logger level to avoid duplicate log outputs + from the `root logger` and `this logger` when `level` is `NOTSET`. + """ + from magpie.constants import MAGPIE_LOG_LEVEL + logger = logging.getLogger(name) + logger.setLevel(level or MAGPIE_LOG_LEVEL) + return logger + + LOGGER = get_logger(__name__) +def print_log(msg, logger=None, level=logging.INFO): + if not logger: + logger = get_logger(__name__) + all_handlers = logging.root.handlers + logger.handlers + if not any(isinstance(h, logging.StreamHandler) for h in all_handlers): + logger.addHandler(logging.StreamHandler(sys.stdout)) + if logger.disabled: + logger.disabled = False + logger.log(level, msg) + + +def raise_log(msg, exception=Exception, logger=None, level=logging.ERROR): + # type: (Str, Optional[Type[Exception]], Optional[LoggerType], Optional[int]) -> None + if not logger: + logger = get_logger(__name__) + logger.log(level, msg) + if not hasattr(exception, 'message'): + exception = Exception + raise exception(msg) + + +def bool2str(value): + # type: (Any) -> Str + return 'true' if str(value).lower() in truthy else 'false' + + +def islambda(func): + return isinstance(func, types.LambdaType) and func.__name__ == (lambda: None).__name__ + + +def isclass(obj): + """ + Evaluate an object for class type (ie: class definition, not an instance nor any other type). + + :param obj: object to evaluate for class type + :return: (bool) indicating if `object` is a class + """ + return isinstance(obj, (type, six.class_types)) + + +# alternative to 'makedirs' with 'exists_ok' parameter only available for python>3.5 +def make_dirs(path): + dir_path = os.path.dirname(path) + if not os.path.isfile(path) or not os.path.isdir(dir_path): + for subdir in mkpath(dir_path): + if not os.path.isdir(subdir): + os.mkdir(subdir) + + +def get_settings_from_config_ini(config_ini_path, ini_main_section_name='app:magpie_app'): + parser = configparser.ConfigParser() + parser.optionxform = lambda option: option # preserve case of config (ziggurat requires it for 'User' model) + parser.read([config_ini_path]) + settings = dict(parser.items(ini_main_section_name)) + return settings + + +def get_json(response): + """ + Retrieves the 'JSON' body of a response using the property/callable + according to the response's implementation. + """ + if isinstance(response.json, dict): + return response.json + return response.json() + + +def get_header(header_name, header_container, default=None, split=None): + # type: (Str, AnyHeadersType, Optional[Str], Optional[Union[Str, List[Str]]]) -> Optional[Str] + """ + Retrieves ``header_name`` by fuzzy match (independently of upper/lower-case and underscore/dash) + from various framework implementations of ``Headers``. + + If ``split`` is specified, the matched ``header_name`` is first split with it and the first item is returned. + This allows to parse complex headers (e.g.: ``text/plain; charset=UTF-8`` to ``text/plain`` with ``split=';'``). + + :param header_name: header to find. + :param header_container: where to look for `header_name`. + :param default: value to returned if `header_container` is invalid or `header_name` could not be found. + :param split: character(s) to use to split the *found* `header_name`. + """ + def fuzzy_name(name): + return name.lower().replace('-', '_') + + if header_container is None: + return default + headers = header_container + if isinstance(headers, (ResponseHeaders, EnvironHeaders, CaseInsensitiveDict)): + headers = dict(headers) + if isinstance(headers, dict): + headers = header_container.items() + header_name = fuzzy_name(header_name) + for h, v in headers: + if fuzzy_name(h) == header_name: + if isinstance(split, six.string_types) and len(split) > 1: + split = [c for c in split] + if hasattr(split, '__iter__') and not isinstance(split, six.string_types): + for s in split: + v = v.replace(s, split[0]) + split = split[0] + return (v.split(split)[0] if split else v).strip() + return default + + +def convert_response(response): + # type: (AnyResponseType) -> Response + """ + Converts a ``response`` implementation (e.g.: ``requests.Response``) + to an equivalent ``pyramid.response.Response`` version. + """ + if isinstance(response, Response): + return response + json_body = get_json(response) + pyramid_response = Response(body=json_body, headers=response.headers) + if hasattr(response, 'cookies'): + for cookie in response.cookies: + pyramid_response.set_cookie(name=cookie.name, value=cookie.value, overwrite=True) + if isinstance(response, HTTPException): + # noinspection PyProtectedMember + for header_name, header_value in response.headers._items: + if header_name.lower() == 'set-cookie': + pyramid_response.set_cookie(name=header_name, value=header_value, overwrite=True) + return pyramid_response + + def get_admin_cookies(magpie_url, verify=True, raise_message=None): # type: (Str, Optional[bool], Optional[Str]) -> CookiesType magpie_login_url = '{}/signin'.format(magpie_url) cred = {'user_name': get_constant('MAGPIE_ADMIN_USER'), 'password': get_constant('MAGPIE_ADMIN_PASSWORD')} - resp = requests.post(magpie_login_url, data=cred, headers={'Accept': JSON_TYPE}, verify=verify) + resp = requests.post(magpie_login_url, data=cred, headers={'Accept': CONTENT_TYPE_JSON}, verify=verify) if resp.status_code != HTTPOk.code: if raise_message: raise_log(raise_message, logger=LOGGER) diff --git a/tests/interfaces.py b/tests/interfaces.py index 797465ca3..f7e6bc5b3 100644 --- a/tests/interfaces.py +++ b/tests/interfaces.py @@ -1,9 +1,8 @@ from magpie.api.api_rest_schemas import SwaggerGenerator -from magpie.common import JSON_TYPE from magpie.constants import get_constant -from magpie.models import resource_type_dict -from magpie.services import service_type_dict -from magpie.utils import get_twitcher_protected_service_url +from magpie.models import RESOURCE_TYPE_DICT +from magpie.services import SERVICE_TYPE_DICT, ServiceAPI +from magpie.utils import get_twitcher_protected_service_url, CONTENT_TYPE_JSON from tests import utils, runner # noinspection PyPackageRequirements from six.moves.urllib.parse import urlparse @@ -49,36 +48,36 @@ class Interface_MagpieAPI_NoAuth(Base_Magpie_TestCase): @runner.MAGPIE_TEST_LOGIN def test_GetSession_Anonymous(self): - resp = utils.test_request(self, 'GET', '/session', headers=self.json_headers) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_equal(json_body['authenticated'], False) - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - utils.check_val_not_in('user', json_body) + resp = utils.test_request(self, "GET", "/session", headers=self.json_headers) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_equal(json_body["authenticated"], False) + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + utils.check_val_not_in("user", json_body) else: - utils.check_val_not_in('user_name', json_body) - utils.check_val_not_in('user_email', json_body) - utils.check_val_not_in('group_names', json_body) + utils.check_val_not_in("user_name", json_body) + utils.check_val_not_in("user_email", json_body) + utils.check_val_not_in("group_names", json_body) def test_GetVersion(self): - resp = utils.test_request(self, 'GET', '/version', headers=self.json_headers) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('db_version', json_body) - utils.check_val_is_in('version', json_body) + resp = utils.test_request(self, "GET", "/version", headers=self.json_headers) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("db_version", json_body) + utils.check_val_is_in("version", json_body) # server not necessarily at latest version, ensure at least format - utils.check_val_equal(json_body['version'], self.version) - utils.check_val_type(json_body['version'], six.string_types) - version_parts = json_body['version'].split('.') + utils.check_val_equal(json_body["version"], self.version) + utils.check_val_type(json_body["version"], six.string_types) + version_parts = json_body["version"].split(".") utils.check_val_equal(len(version_parts), 3) @runner.MAGPIE_TEST_USERS def test_GetCurrentUser(self): - logged_user = get_constant('MAGPIE_LOGGED_USER') - resp = utils.test_request(self, 'GET', '/users/{}'.format(logged_user), headers=self.json_headers) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - utils.check_val_equal(json_body['user']['user_name'], self.usr) + logged_user = get_constant("MAGPIE_LOGGED_USER") + resp = utils.test_request(self, "GET", "/users/{}".format(logged_user), headers=self.json_headers) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + utils.check_val_equal(json_body["user"]["user_name"], self.usr) else: - utils.check_val_equal(json_body['user_name'], self.usr) + utils.check_val_equal(json_body["user_name"], self.usr) # noinspection PyAbstractClass, PyPep8Naming @@ -120,31 +119,33 @@ def check_requirements(cls): @classmethod def setup_test_values(cls): - services_cfg = yaml.safe_load(open(get_constant('MAGPIE_PROVIDERS_CONFIG_PATH'), 'r')) - provider_services_info = services_cfg['providers'] + services_cfg = yaml.safe_load(open(get_constant("MAGPIE_PROVIDERS_CONFIG_PATH"), 'r')) + provider_services_info = services_cfg["providers"] # filter impossible providers from possible previous version of remote server possible_service_types = utils.get_service_types_for_version(cls.version) cls.test_services_info = dict() for svc_name in provider_services_info: - if provider_services_info[svc_name]['type'] in possible_service_types: + if provider_services_info[svc_name]["type"] in possible_service_types: cls.test_services_info[svc_name] = provider_services_info[svc_name] - cls.test_service_name = u'magpie-unittest-service-api' - cls.test_service_type = u'api' + cls.test_service_name = u"magpie-unittest-service-api" + cls.test_service_type = ServiceAPI.service_type utils.TestSetup.create_TestService(cls) - cls.test_resource_name = u'magpie-unittest-resource' - test_service_res_perm_dict = service_type_dict[cls.test_service_type].resource_types_permissions + cls.test_resource_name = u"magpie-unittest-resource" + test_service_res_perm_dict = SERVICE_TYPE_DICT[cls.test_service_type].resource_types_permissions test_service_resource_types = list(test_service_res_perm_dict.keys()) assert len(test_service_resource_types), "test service must allow at least 1 sub-resource for test execution" - cls.test_resource_type = test_service_resource_types[0] - test_service_resource_perms = test_service_res_perm_dict[cls.test_resource_type] + cls.test_resource_class = test_service_resource_types[0] + cls.test_resource_type = cls.test_resource_class.resource_type + test_service_resource_perms = test_service_res_perm_dict[cls.test_resource_class] assert len(test_service_resource_perms), "test service must allow at least 1 sub-permission for test execution" - cls.test_resource_perm = test_service_resource_perms[0] + cls.test_resource_perm_type = test_service_resource_perms[0] + cls.test_resource_perm_name = cls.test_resource_perm_type.value - cls.test_group_name = u'magpie-unittest-dummy-group' - cls.test_user_name = u'magpie-unittest-toto' - cls.test_user_group = u'users' + cls.test_group_name = u"magpie-unittest-dummy-group" + cls.test_user_name = u"magpie-unittest-toto" + cls.test_user_group = u"users" def setUp(self): self.check_requirements() @@ -153,22 +154,22 @@ def setUp(self): utils.TestSetup.delete_TestUser(self) def test_GetAPI(self): - resp = utils.test_request(self, 'GET', SwaggerGenerator.path, headers=self.json_headers) + resp = utils.test_request(self, "GET", SwaggerGenerator.path, headers=self.json_headers) json_body = utils.get_json_body(resp) content_types = utils.get_response_content_types_list(resp) - utils.check_val_is_in(JSON_TYPE, content_types) + utils.check_val_is_in(CONTENT_TYPE_JSON, content_types) utils.check_val_equal(resp.status_code, 200) - utils.check_val_is_in('info', json_body) - utils.check_val_is_in('version', json_body['info']) - utils.check_val_equal(json_body['info']['version'], self.version) - utils.check_val_is_in('paths', json_body) - utils.check_val_is_in('host', json_body) - utils.check_val_is_in('schemes', json_body) - utils.check_val_is_in('tags', json_body) - utils.check_val_is_in('basePath', json_body) - utils.check_val_is_in('securityDefinitions', json_body) - utils.check_val_is_in('swagger', json_body) - utils.check_val_equal(json_body['swagger'], '2.0') + utils.check_val_is_in("info", json_body) + utils.check_val_is_in("version", json_body["info"]) + utils.check_val_equal(json_body["info"]["version"], self.version) + utils.check_val_is_in("paths", json_body) + utils.check_val_is_in("host", json_body) + utils.check_val_is_in("schemes", json_body) + utils.check_val_is_in("tags", json_body) + utils.check_val_is_in("basePath", json_body) + utils.check_val_is_in("securityDefinitions", json_body) + utils.check_val_is_in("swagger", json_body) + utils.check_val_equal(json_body["swagger"], "2.0") @runner.MAGPIE_TEST_STATUS def test_unauthorized_forbidden_responses(self): @@ -176,7 +177,7 @@ def test_unauthorized_forbidden_responses(self): Verify that unauthorized (401) and forbidden (403) are properly returned for corresponding operations. Both variations use the same forbidden view. """ - utils.warn_version(self, "check for response (401/403) statuses", '0.9.1', skip=True) + utils.warn_version(self, "check for response (401/403) statuses", "0.9.1", skip=True) app_or_url = utils.get_app_or_url(self) if isinstance(app_or_url, six.string_types): @@ -184,84 +185,84 @@ def test_unauthorized_forbidden_responses(self): RuntimeWarning) else: # call a route that will make a forbidden access to db - with mock.patch('magpie.models.User.all', side_effect=Exception('Test')): - resp = utils.test_request(self, 'GET', '/users', headers=self.json_headers, expect_errors=True) - body = utils.check_response_basic_info(resp, 403, expected_method='GET') - utils.check_val_equal(body['code'], 403) + with mock.patch("magpie.models.User.all", side_effect=Exception("Test")): + resp = utils.test_request(self, "GET", "/users", headers=self.json_headers, expect_errors=True) + body = utils.check_response_basic_info(resp, 403, expected_method="GET") + utils.check_val_equal(body["code"], 403) # call a route that is admin-only utils.check_or_try_logout_user(app_or_url) - resp = utils.test_request(self, 'GET', '/services', headers=self.json_headers, expect_errors=True) - body = utils.check_response_basic_info(resp, 401, expected_method='GET') - utils.check_val_equal(body['code'], 401) + resp = utils.test_request(self, "GET", "/services", headers=self.json_headers, expect_errors=True) + body = utils.check_response_basic_info(resp, 401, expected_method="GET") + utils.check_val_equal(body["code"], 401) @runner.MAGPIE_TEST_LOGIN def test_GetSession_Administrator(self): - resp = utils.test_request(self, 'GET', '/session', headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_equal(json_body['authenticated'], True) - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - utils.check_val_is_in('user', json_body) - utils.check_val_equal(json_body['user']['user_name'], self.usr) - utils.check_val_is_in(get_constant('MAGPIE_ADMIN_GROUP'), json_body['user']['group_names']) - utils.check_val_type(json_body['user']['group_names'], list) - utils.check_val_is_in('email', json_body['user']) + resp = utils.test_request(self, "GET", "/session", headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_equal(json_body["authenticated"], True) + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + utils.check_val_is_in("user", json_body) + utils.check_val_equal(json_body["user"]["user_name"], self.usr) + utils.check_val_is_in(get_constant("MAGPIE_ADMIN_GROUP"), json_body["user"]["group_names"]) + utils.check_val_type(json_body["user"]["group_names"], list) + utils.check_val_is_in("email", json_body["user"]) else: - utils.check_val_equal(json_body['user_name'], self.usr) - utils.check_val_is_in(get_constant('MAGPIE_ADMIN_GROUP'), json_body['group_names']) - utils.check_val_type(json_body['group_names'], list) - utils.check_val_is_in('user_email', json_body) + utils.check_val_equal(json_body["user_name"], self.usr) + utils.check_val_is_in(get_constant("MAGPIE_ADMIN_GROUP"), json_body["group_names"]) + utils.check_val_type(json_body["group_names"], list) + utils.check_val_is_in("user_email", json_body) @runner.MAGPIE_TEST_USERS def test_GetUsers(self): - resp = utils.test_request(self, 'GET', '/users', headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('user_names', json_body) - utils.check_val_type(json_body['user_names'], list) - utils.check_val_equal(len(json_body['user_names']) > 1, True) # should have more than only 'anonymous' - utils.check_val_is_in('anonymous', json_body['user_names']) # anonymous always in users - utils.check_val_is_in(self.usr, json_body['user_names']) # current test user in users + resp = utils.test_request(self, "GET", "/users", headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("user_names", json_body) + utils.check_val_type(json_body["user_names"], list) + utils.check_val_equal(len(json_body["user_names"]) > 1, True) # should have more than only 'anonymous' + utils.check_val_is_in("anonymous", json_body["user_names"]) # anonymous always in users + utils.check_val_is_in(self.usr, json_body["user_names"]) # current test user in users @runner.MAGPIE_TEST_USERS @runner.MAGPIE_TEST_DEFAULTS def test_ValidateDefaultUsers(self): - resp = utils.test_request(self, 'GET', '/users', headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - users = json_body['user_names'] - utils.check_val_is_in(get_constant('MAGPIE_ANONYMOUS_USER'), users) - utils.check_val_is_in(get_constant('MAGPIE_ADMIN_USER'), users) + resp = utils.test_request(self, "GET", "/users", headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + users = json_body["user_names"] + utils.check_val_is_in(get_constant("MAGPIE_ANONYMOUS_USER"), users) + utils.check_val_is_in(get_constant("MAGPIE_ADMIN_USER"), users) @classmethod def check_GetUserResourcesPermissions(cls, user_name, resource_id, query=None): - query = '?{}'.format(query) if query else '' - route = '/users/{usr}/resources/{res_id}/permissions{q}'.format(res_id=resource_id, usr=user_name, q=query) - resp = utils.test_request(cls, 'GET', route, headers=cls.json_headers, cookies=cls.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('permission_names', json_body) - utils.check_val_type(json_body['permission_names'], list) + query = "?{}".format(query) if query else "" + route = "/users/{usr}/resources/{res_id}/permissions{q}".format(res_id=resource_id, usr=user_name, q=query) + resp = utils.test_request(cls, "GET", route, headers=cls.json_headers, cookies=cls.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("permission_names", json_body) + utils.check_val_type(json_body["permission_names"], list) return json_body @runner.MAGPIE_TEST_USERS def test_GetCurrentUser(self): - logged_user = get_constant('MAGPIE_LOGGED_USER') - path = '/users/{}'.format(logged_user) - resp = utils.test_request(self, 'GET', path, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - utils.check_val_equal(json_body['user']['user_name'], self.usr) + logged_user = get_constant("MAGPIE_LOGGED_USER") + path = "/users/{}".format(logged_user) + resp = utils.test_request(self, "GET", path, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + utils.check_val_equal(json_body["user"]["user_name"], self.usr) else: - utils.check_val_equal(json_body['user_name'], self.usr) + utils.check_val_equal(json_body["user_name"], self.usr) @runner.MAGPIE_TEST_USERS def test_GetCurrentUserResourcesPermissions(self): utils.TestSetup.create_TestService(self) json_body = utils.TestSetup.create_TestServiceResource(self) - res_id = json_body['resource']['resource_id'] - self.check_GetUserResourcesPermissions(get_constant('MAGPIE_LOGGED_USER'), res_id) + res_id = json_body["resource"]["resource_id"] + self.check_GetUserResourcesPermissions(get_constant("MAGPIE_LOGGED_USER"), res_id) @runner.MAGPIE_TEST_USERS def test_GetCurrentUserResourcesPermissions_Queries(self): - utils.warn_version(self, "queries", '0.7.0', skip=True) + utils.warn_version(self, "queries", "0.7.0", skip=True) # setup test resources under service with permissions # Service/Resources | Admin-User | Admin-Group | Anonym-User | Anonym-Group @@ -270,9 +271,9 @@ def test_GetCurrentUserResourcesPermissions_Queries(self): # |- test-resource (parent) | | r-m | | # |- test-resource (child) | | | r-m | json_body = utils.TestSetup.create_TestService(self) - test_svc_res_id = json_body['service']['resource_id'] + test_svc_res_id = json_body["service"]["resource_id"] json_body = utils.TestSetup.create_TestServiceResource(self) - test_parent_res_id = json_body['resource']['resource_id'] + test_parent_res_id = json_body["resource"]["resource_id"] child_resource_name = self.test_resource_name + "-child" data_override = { "resource_name": child_resource_name, @@ -280,251 +281,251 @@ def test_GetCurrentUserResourcesPermissions_Queries(self): "parent_id": test_parent_res_id } json_body = utils.TestSetup.create_TestServiceResource(self, data_override) - test_child_res_id = json_body['resource']['resource_id'] - anonym_usr = get_constant('MAGPIE_ANONYMOUS_USER') - anonym_grp = get_constant('MAGPIE_ANONYMOUS_GROUP') - - perm_recur = self.test_resource_perm - perm_match = self.test_resource_perm + "-match" - data_recur = {u'permission_name': perm_recur} - data_match = {u'permission_name': perm_match} - path = '/users/{usr}/resources/{res_id}/permissions'.format(res_id=test_svc_res_id, usr=self.usr) - utils.test_request(self, 'POST', path, data=data_recur, headers=self.json_headers, cookies=self.cookies) - path = '/groups/{grp}/resources/{res_id}/permissions'.format(res_id=test_svc_res_id, grp=self.grp) - utils.test_request(self, 'POST', path, data=data_match, headers=self.json_headers, cookies=self.cookies) - path = '/groups/{grp}/resources/{res_id}/permissions'.format(res_id=test_parent_res_id, grp=self.grp) - utils.test_request(self, 'POST', path, data=data_match, headers=self.json_headers, cookies=self.cookies) - path = '/users/{usr}/resources/{res_id}/permissions'.format(res_id=test_child_res_id, usr=anonym_usr) - utils.test_request(self, 'POST', path, data=data_match, headers=self.json_headers, cookies=self.cookies) - path = '/groups/{grp}/resources/{res_id}/permissions'.format(res_id=test_svc_res_id, grp=anonym_grp) - utils.test_request(self, 'POST', path, data=data_recur, headers=self.json_headers, cookies=self.cookies) + test_child_res_id = json_body["resource"]["resource_id"] + anonym_usr = get_constant("MAGPIE_ANONYMOUS_USER") + anonym_grp = get_constant("MAGPIE_ANONYMOUS_GROUP") + + perm_recur = self.test_resource_perm_name + perm_match = self.test_resource_perm_name + "-match" + data_recur = {u"permission_name": perm_recur} + data_match = {u"permission_name": perm_match} + path = "/users/{usr}/resources/{res_id}/permissions".format(res_id=test_svc_res_id, usr=self.usr) + utils.test_request(self, "POST", path, data=data_recur, headers=self.json_headers, cookies=self.cookies) + path = "/groups/{grp}/resources/{res_id}/permissions".format(res_id=test_svc_res_id, grp=self.grp) + utils.test_request(self, "POST", path, data=data_match, headers=self.json_headers, cookies=self.cookies) + path = "/groups/{grp}/resources/{res_id}/permissions".format(res_id=test_parent_res_id, grp=self.grp) + utils.test_request(self, "POST", path, data=data_match, headers=self.json_headers, cookies=self.cookies) + path = "/users/{usr}/resources/{res_id}/permissions".format(res_id=test_child_res_id, usr=anonym_usr) + utils.test_request(self, "POST", path, data=data_match, headers=self.json_headers, cookies=self.cookies) + path = "/groups/{grp}/resources/{res_id}/permissions".format(res_id=test_svc_res_id, grp=anonym_grp) + utils.test_request(self, "POST", path, data=data_recur, headers=self.json_headers, cookies=self.cookies) # tests q_groups = "inherit=true" q_effect = "effective=true" json_body = self.check_GetUserResourcesPermissions(self.usr, resource_id=test_child_res_id, query=None) - utils.check_val_equal(json_body['permission_names'], []) + utils.check_val_equal(json_body["permission_names"], []) json_body = self.check_GetUserResourcesPermissions(self.usr, resource_id=test_child_res_id, query=q_groups) - utils.check_val_equal(json_body['permission_names'], []) + utils.check_val_equal(json_body["permission_names"], []) json_body = self.check_GetUserResourcesPermissions(self.usr, resource_id=test_child_res_id, query=q_effect) - utils.check_val_equal(json_body['permission_names'], [perm_recur]) + utils.check_val_equal(json_body["permission_names"], [perm_recur]) json_body = self.check_GetUserResourcesPermissions(self.usr, resource_id=test_parent_res_id, query=None) - utils.check_val_equal(json_body['permission_names'], []) + utils.check_val_equal(json_body["permission_names"], []) json_body = self.check_GetUserResourcesPermissions(self.usr, resource_id=test_parent_res_id, query=q_groups) - utils.check_val_equal(json_body['permission_names'], [perm_match]) + utils.check_val_equal(json_body["permission_names"], [perm_match]) json_body = self.check_GetUserResourcesPermissions(self.usr, resource_id=test_parent_res_id, query=q_effect) - utils.check_all_equal(json_body['permission_names'], [perm_recur, perm_match], any_order=True) + utils.check_all_equal(json_body["permission_names"], [perm_recur, perm_match], any_order=True) json_body = self.check_GetUserResourcesPermissions(self.usr, resource_id=test_svc_res_id, query=None) - utils.check_val_equal(json_body['permission_names'], [perm_recur]) + utils.check_val_equal(json_body["permission_names"], [perm_recur]) json_body = self.check_GetUserResourcesPermissions(self.usr, resource_id=test_svc_res_id, query=q_groups) - utils.check_all_equal(json_body['permission_names'], [perm_recur, perm_match], any_order=True) + utils.check_all_equal(json_body["permission_names"], [perm_recur, perm_match], any_order=True) json_body = self.check_GetUserResourcesPermissions(self.usr, resource_id=test_svc_res_id, query=q_effect) - utils.check_all_equal(json_body['permission_names'], [perm_recur, perm_match], any_order=True) + utils.check_all_equal(json_body["permission_names"], [perm_recur, perm_match], any_order=True) json_body = self.check_GetUserResourcesPermissions(anonym_usr, resource_id=test_child_res_id, query=None) - utils.check_val_equal(json_body['permission_names'], [perm_match]) + utils.check_val_equal(json_body["permission_names"], [perm_match]) json_body = self.check_GetUserResourcesPermissions(anonym_usr, resource_id=test_child_res_id, query=q_groups) - utils.check_val_equal(json_body['permission_names'], [perm_match]) + utils.check_val_equal(json_body["permission_names"], [perm_match]) json_body = self.check_GetUserResourcesPermissions(anonym_usr, resource_id=test_child_res_id, query=q_effect) - utils.check_all_equal(json_body['permission_names'], [perm_recur, perm_match], any_order=True) + utils.check_all_equal(json_body["permission_names"], [perm_recur, perm_match], any_order=True) json_body = self.check_GetUserResourcesPermissions(anonym_usr, resource_id=test_parent_res_id, query=None) - utils.check_val_equal(json_body['permission_names'], []) + utils.check_val_equal(json_body["permission_names"], []) json_body = self.check_GetUserResourcesPermissions(anonym_usr, resource_id=test_parent_res_id, query=q_groups) - utils.check_val_equal(json_body['permission_names'], []) + utils.check_val_equal(json_body["permission_names"], []) json_body = self.check_GetUserResourcesPermissions(anonym_usr, resource_id=test_parent_res_id, query=q_effect) - utils.check_val_equal(json_body['permission_names'], [perm_recur]) + utils.check_val_equal(json_body["permission_names"], [perm_recur]) json_body = self.check_GetUserResourcesPermissions(anonym_usr, resource_id=test_svc_res_id, query=None) - utils.check_val_equal(json_body['permission_names'], []) + utils.check_val_equal(json_body["permission_names"], []) json_body = self.check_GetUserResourcesPermissions(anonym_usr, resource_id=test_svc_res_id, query=q_groups) - utils.check_val_equal(json_body['permission_names'], [perm_recur]) + utils.check_val_equal(json_body["permission_names"], [perm_recur]) json_body = self.check_GetUserResourcesPermissions(anonym_usr, resource_id=test_svc_res_id, query=q_effect) - utils.check_val_equal(json_body['permission_names'], [perm_recur]) + utils.check_val_equal(json_body["permission_names"], [perm_recur]) @runner.MAGPIE_TEST_USERS def test_GetUserResourcesPermissions(self): utils.TestSetup.create_TestService(self) json_body = utils.TestSetup.create_TestServiceResource(self) - self.check_GetUserResourcesPermissions(self.usr, json_body['resource']['resource_id']) + self.check_GetUserResourcesPermissions(self.usr, json_body["resource"]["resource_id"]) @runner.MAGPIE_TEST_USERS def test_PostUserResourcesPermissions_Created(self): - resource_name = 'post_res_perm_created' + resource_name = "post_res_perm_created" utils.TestSetup.delete_TestServiceResource(self, override_resource_name=resource_name) - data = {'resource_name': resource_name} + data = {"resource_name": resource_name} body = utils.TestSetup.create_TestServiceResource(self, data_override=data) - test_res_id = body['resource']['resource_id'] + test_res_id = body["resource"]["resource_id"] # test permission creation - path = '/users/{usr}/resources/{res_id}/permissions'.format(res_id=test_res_id, usr=self.usr) - data = {u'permission_name': self.test_resource_perm} - resp = utils.test_request(self, 'POST', path, data=data, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 201, expected_method='POST') - utils.check_val_is_in('permission_name', json_body) - utils.check_val_is_in('resource_id', json_body) - utils.check_val_is_in('user_id', json_body) - utils.check_val_type(json_body['permission_name'], six.string_types) - utils.check_val_type(json_body['resource_id'], int) - utils.check_val_type(json_body['user_id'], int) + path = "/users/{usr}/resources/{res_id}/permissions".format(res_id=test_res_id, usr=self.usr) + data = {u"permission_name": self.test_resource_perm_name} + resp = utils.test_request(self, "POST", path, data=data, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 201, expected_method="POST") + utils.check_val_is_in("permission_name", json_body) + utils.check_val_is_in("resource_id", json_body) + utils.check_val_is_in("user_id", json_body) + utils.check_val_type(json_body["permission_name"], six.string_types) + utils.check_val_type(json_body["resource_id"], int) + utils.check_val_type(json_body["user_id"], int) # cleanup (delete sub resource should remove child permission) utils.TestSetup.delete_TestServiceResource(self, override_resource_name=resource_name) @runner.MAGPIE_TEST_USERS def test_PostUserResourcesPermissions_Conflict(self): - resource_name = 'post_res_perm_conflict' + resource_name = "post_res_perm_conflict" utils.TestSetup.delete_TestServiceResource(self, override_resource_name=resource_name) - data = {'resource_name': resource_name} + data = {"resource_name": resource_name} body = utils.TestSetup.create_TestServiceResource(self, data_override=data) - test_res_id = body['resource']['resource_id'] + test_res_id = body["resource"]["resource_id"] - path = '/users/{usr}/resources/{res_id}/permissions'.format(res_id=test_res_id, usr=self.usr) - data = {u'permission_name': self.test_resource_perm} - utils.test_request(self, 'POST', path, data=data, headers=self.json_headers, cookies=self.cookies) + path = "/users/{usr}/resources/{res_id}/permissions".format(res_id=test_res_id, usr=self.usr) + data = {u"permission_name": self.test_resource_perm_name} + utils.test_request(self, "POST", path, data=data, headers=self.json_headers, cookies=self.cookies) json_body = self.check_GetUserResourcesPermissions(self.usr, resource_id=test_res_id) - utils.check_val_is_in(self.test_resource_perm, json_body['permission_names'], + utils.check_val_is_in(self.test_resource_perm_name, json_body["permission_names"], msg="Can't test for conflicting permissions if it doesn't exist first.") - resp = utils.test_request(self, 'POST', path, data=data, headers=self.json_headers, cookies=self.cookies, + resp = utils.test_request(self, "POST", path, data=data, headers=self.json_headers, cookies=self.cookies, expect_errors=True) - json_body = utils.check_response_basic_info(resp, 409, expected_method='POST') - utils.check_val_is_in('permission_name', json_body) - utils.check_val_is_in('resource_id', json_body) - utils.check_val_is_in('user_id', json_body) - utils.check_val_type(json_body['permission_name'], six.string_types) - utils.check_val_type(json_body['resource_id'], int) - utils.check_val_type(json_body['user_id'], int) + json_body = utils.check_response_basic_info(resp, 409, expected_method="POST") + utils.check_val_is_in("permission_name", json_body) + utils.check_val_is_in("resource_id", json_body) + utils.check_val_is_in("user_id", json_body) + utils.check_val_type(json_body["permission_name"], six.string_types) + utils.check_val_type(json_body["resource_id"], int) + utils.check_val_type(json_body["user_id"], int) # cleanup (delete sub resource should remove child permission) utils.TestSetup.delete_TestServiceResource(self, override_resource_name=resource_name) @runner.MAGPIE_TEST_USERS def test_GetCurrentUserGroups(self): - resp = utils.test_request(self, 'GET', '/users/current/groups', + resp = utils.test_request(self, "GET", "/users/current/groups", headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('group_names', json_body) - utils.check_val_type(json_body['group_names'], list) - utils.check_val_is_in(get_constant('MAGPIE_ADMIN_GROUP'), json_body['group_names']) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("group_names", json_body) + utils.check_val_type(json_body["group_names"], list) + utils.check_val_is_in(get_constant("MAGPIE_ADMIN_GROUP"), json_body["group_names"]) @runner.MAGPIE_TEST_USERS def test_GetUserInheritedResources(self): utils.TestSetup.create_TestService(self) utils.TestSetup.create_TestServiceResource(self) - if LooseVersion(self.version) >= LooseVersion('0.7.0'): - route = '/users/{usr}/inherited_resources'.format(usr=self.usr) + if LooseVersion(self.version) >= LooseVersion("0.7.0"): + route = "/users/{usr}/inherited_resources".format(usr=self.usr) else: - route = '/users/{usr}/resources?inherit=true'.format(usr=self.usr) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('resources', json_body) - utils.check_val_type(json_body['resources'], dict) + route = "/users/{usr}/resources?inherit=true".format(usr=self.usr) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("resources", json_body) + utils.check_val_type(json_body["resources"], dict) service_types = utils.get_service_types_for_version(self.version) - utils.check_all_equal(json_body['resources'].keys(), service_types, any_order=True) - for svc_type in json_body['resources']: - for svc in json_body['resources'][svc_type]: - svc_dict = json_body['resources'][svc_type][svc] + utils.check_all_equal(json_body["resources"].keys(), service_types, any_order=True) + for svc_type in json_body["resources"]: + for svc in json_body["resources"][svc_type]: + svc_dict = json_body["resources"][svc_type][svc] utils.check_val_type(svc_dict, dict) - utils.check_val_is_in('resource_id', svc_dict) - utils.check_val_is_in('service_name', svc_dict) - utils.check_val_is_in('service_type', svc_dict) - utils.check_val_is_in('public_url', svc_dict) - utils.check_val_is_in('permission_names', svc_dict) - utils.check_val_is_in('resources', svc_dict) - utils.check_val_type(svc_dict['resource_id'], int) - utils.check_val_type(svc_dict['service_name'], six.string_types) - utils.check_val_type(svc_dict['service_type'], six.string_types) - utils.check_val_type(svc_dict['public_url'], six.string_types) - utils.check_val_type(svc_dict['permission_names'], list) - utils.check_val_type(svc_dict['resources'], dict) - if LooseVersion(self.version) >= LooseVersion('0.7.0'): - utils.check_val_is_in('service_sync_type', svc_dict) - utils.check_val_type(svc_dict['service_sync_type'], utils.OptionalStringType) - utils.check_val_not_in('service_url', svc_dict, - msg="Services under user routes shouldn't show private url.") + utils.check_val_is_in("resource_id", svc_dict) + utils.check_val_is_in("service_name", svc_dict) + utils.check_val_is_in("service_type", svc_dict) + utils.check_val_is_in("public_url", svc_dict) + utils.check_val_is_in("permission_names", svc_dict) + utils.check_val_is_in("resources", svc_dict) + utils.check_val_type(svc_dict["resource_id"], int) + utils.check_val_type(svc_dict["service_name"], six.string_types) + utils.check_val_type(svc_dict["service_type"], six.string_types) + utils.check_val_type(svc_dict["public_url"], six.string_types) + utils.check_val_type(svc_dict["permission_names"], list) + utils.check_val_type(svc_dict["resources"], dict) + if LooseVersion(self.version) >= LooseVersion("0.7.0"): + utils.check_val_is_in("service_sync_type", svc_dict) + utils.check_val_type(svc_dict["service_sync_type"], utils.OptionalStringType) + utils.check_val_not_in("service_url", svc_dict, + msg="Services under user routes shouldn"t show private url.") else: - utils.check_val_is_in('service_url', svc_dict) - utils.check_val_type(svc_dict['service_url'], six.string_types) + utils.check_val_is_in("service_url", svc_dict) + utils.check_val_type(svc_dict["service_url"], six.string_types) @runner.MAGPIE_TEST_USERS def test_GetUserServices(self): - route = '/users/{usr}/services'.format(usr=self.usr) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('services', json_body) - services = json_body['services'] + route = "/users/{usr}/services".format(usr=self.usr) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("services", json_body) + services = json_body["services"] utils.check_val_type(services, dict) service_types = utils.get_service_types_for_version(self.version) - # as of version '0.7.0', visible services depend on the connected user permissions, + # as of version 0.7.0, visible services depend on the connected user permissions, # so all services types not necessarily returned in the response - if LooseVersion(self.version) < LooseVersion('0.7.0'): + if LooseVersion(self.version) < LooseVersion("0.7.0"): utils.check_all_equal(services.keys(), service_types, any_order=True) for svc_type in services: utils.check_val_is_in(svc_type, service_types) # one of valid service types for svc in services[svc_type]: svc_dict = services[svc_type][svc] utils.check_val_type(svc_dict, dict) - utils.check_val_is_in('resource_id', svc_dict) - utils.check_val_is_in('service_name', svc_dict) - utils.check_val_is_in('service_type', svc_dict) - utils.check_val_is_in('public_url', svc_dict) - utils.check_val_is_in('permission_names', svc_dict) - utils.check_val_type(svc_dict['resource_id'], int) - utils.check_val_type(svc_dict['service_name'], six.string_types) - utils.check_val_type(svc_dict['service_type'], six.string_types) - utils.check_val_type(svc_dict['public_url'], six.string_types) - utils.check_val_type(svc_dict['permission_names'], list) - if LooseVersion(self.version) >= LooseVersion('0.7.0'): - utils.check_val_is_in('service_sync_type', svc_dict) - utils.check_val_type(svc_dict['service_sync_type'], utils.OptionalStringType) - utils.check_val_not_in('service_url', svc_dict, + utils.check_val_is_in("resource_id", svc_dict) + utils.check_val_is_in("service_name", svc_dict) + utils.check_val_is_in("service_type", svc_dict) + utils.check_val_is_in("public_url", svc_dict) + utils.check_val_is_in("permission_names", svc_dict) + utils.check_val_type(svc_dict["resource_id"], int) + utils.check_val_type(svc_dict["service_name"], six.string_types) + utils.check_val_type(svc_dict["service_type"], six.string_types) + utils.check_val_type(svc_dict["public_url"], six.string_types) + utils.check_val_type(svc_dict["permission_names"], list) + if LooseVersion(self.version) >= LooseVersion("0.7.0"): + utils.check_val_is_in("service_sync_type", svc_dict) + utils.check_val_type(svc_dict["service_sync_type"], utils.OptionalStringType) + utils.check_val_not_in("service_url", svc_dict, msg="Services under user routes shouldn't show private url.") else: - utils.check_val_is_in('service_url', svc_dict) - utils.check_val_type(svc_dict['service_url'], six.string_types) + utils.check_val_is_in("service_url", svc_dict) + utils.check_val_type(svc_dict["service_url"], six.string_types) @runner.MAGPIE_TEST_USERS def test_GetUserServiceResources(self): utils.TestSetup.create_TestService(self) utils.TestSetup.create_TestServiceResource(self) - route = '/users/{usr}/services/{svc}/resources'.format(usr=self.usr, svc=self.test_service_name) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('service', json_body) - svc_dict = json_body['service'] + route = "/users/{usr}/services/{svc}/resources".format(usr=self.usr, svc=self.test_service_name) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("service", json_body) + svc_dict = json_body["service"] utils.check_val_type(svc_dict, dict) - utils.check_val_is_in('resource_id', svc_dict) - utils.check_val_is_in('service_name', svc_dict) - utils.check_val_is_in('service_type', svc_dict) - utils.check_val_is_in('public_url', svc_dict) - utils.check_val_is_in('permission_names', svc_dict) - utils.check_val_is_in('resources', svc_dict) - utils.check_val_type(svc_dict['resource_id'], int) - utils.check_val_type(svc_dict['service_name'], six.string_types) - utils.check_val_type(svc_dict['service_type'], six.string_types) - utils.check_val_type(svc_dict['public_url'], six.string_types) - utils.check_val_type(svc_dict['permission_names'], list) - utils.check_val_type(svc_dict['resources'], dict) - if LooseVersion(self.version) >= LooseVersion('0.7.0'): - utils.check_val_is_in('service_sync_type', svc_dict) - utils.check_val_type(svc_dict['service_sync_type'], utils.OptionalStringType) - utils.check_val_not_in('service_url', svc_dict) + utils.check_val_is_in("resource_id", svc_dict) + utils.check_val_is_in("service_name", svc_dict) + utils.check_val_is_in("service_type", svc_dict) + utils.check_val_is_in("public_url", svc_dict) + utils.check_val_is_in("permission_names", svc_dict) + utils.check_val_is_in("resources", svc_dict) + utils.check_val_type(svc_dict["resource_id"], int) + utils.check_val_type(svc_dict["service_name"], six.string_types) + utils.check_val_type(svc_dict["service_type"], six.string_types) + utils.check_val_type(svc_dict["public_url"], six.string_types) + utils.check_val_type(svc_dict["permission_names"], list) + utils.check_val_type(svc_dict["resources"], dict) + if LooseVersion(self.version) >= LooseVersion("0.7.0"): + utils.check_val_is_in("service_sync_type", svc_dict) + utils.check_val_type(svc_dict["service_sync_type"], utils.OptionalStringType) + utils.check_val_not_in("service_url", svc_dict) else: - utils.check_val_is_in('service_url', svc_dict) - utils.check_val_type(svc_dict['service_url'], six.string_types) + utils.check_val_is_in("service_url", svc_dict) + utils.check_val_type(svc_dict["service_url"], six.string_types) @runner.MAGPIE_TEST_USERS def test_PostUsers(self): json_body = utils.TestSetup.create_TestUser(self) - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - utils.check_val_is_in('user', json_body) - utils.check_val_is_in('user_name', json_body['user']) - utils.check_val_type(json_body['user']['user_name'], six.string_types) - utils.check_val_is_in('email', json_body['user']) - utils.check_val_type(json_body['user']['email'], six.string_types) - utils.check_val_is_in('group_names', json_body['user']) - utils.check_val_type(json_body['user']['group_names'], list) + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + utils.check_val_is_in("user", json_body) + utils.check_val_is_in("user_name", json_body["user"]) + utils.check_val_type(json_body["user"]["user_name"], six.string_types) + utils.check_val_is_in("email", json_body["user"]) + utils.check_val_type(json_body["user"]["email"], six.string_types) + utils.check_val_is_in("group_names", json_body["user"]) + utils.check_val_type(json_body["user"]["group_names"], list) users = utils.TestSetup.get_RegisteredUsersList(self) utils.check_val_is_in(self.test_user_name, users) @@ -532,66 +533,66 @@ def test_PostUsers(self): @runner.MAGPIE_TEST_USERS def test_PostUsers_ReservedKeyword_Current(self): data = { - 'user_name': get_constant('MAGPIE_LOGGED_USER'), - 'password': 'pwd', - 'email': 'email@mail.com', - 'group_name': 'users', + "user_name": get_constant("MAGPIE_LOGGED_USER"), + "password": "pwd", + "email": "email@mail.com", + "group_name": "users", } - resp = utils.test_request(self, 'POST', '/users', data=data, + resp = utils.test_request(self, "POST", "/users", data=data, headers=self.json_headers, cookies=self.cookies, expect_errors=True) - utils.check_response_basic_info(resp, 400, expected_method='POST') + utils.check_response_basic_info(resp, 400, expected_method="POST") @runner.MAGPIE_TEST_USERS def test_PutUser_ReservedKeyword_Current(self): utils.TestSetup.create_TestUser(self) - route = '/users/{usr}'.format(usr=get_constant('MAGPIE_LOGGED_USER')) - data = {'user_name': self.test_user_name + '-new-put-over-current'} - resp = utils.test_request(self, 'PUT', route, data=data, + route = "/users/{usr}".format(usr=get_constant("MAGPIE_LOGGED_USER")) + data = {"user_name": self.test_user_name + "-new-put-over-current"} + resp = utils.test_request(self, "PUT", route, data=data, headers=self.json_headers, cookies=self.cookies, expect_errors=True) - utils.check_response_basic_info(resp, 400, expected_method='PUT') + utils.check_response_basic_info(resp, 400, expected_method="PUT") @runner.MAGPIE_TEST_USERS def test_PutUsers_nothing(self): utils.TestSetup.create_TestUser(self) - route = '/users/{usr}'.format(usr=self.test_user_name) - resp = utils.test_request(self, 'PUT', route, data={}, + route = "/users/{usr}".format(usr=self.test_user_name) + resp = utils.test_request(self, "PUT", route, data={}, headers=self.json_headers, cookies=self.cookies, expect_errors=True) - utils.check_response_basic_info(resp, 400, expected_method='PUT') + utils.check_response_basic_info(resp, 400, expected_method="PUT") @runner.MAGPIE_TEST_USERS def test_PutUsers_username(self): utils.TestSetup.create_TestUser(self) - new_name = self.test_user_name + '-new' + new_name = self.test_user_name + "-new" # cleanup in case the updated username already exists (ex: previous test execution failure) utils.TestSetup.delete_TestUser(self, override_user_name=new_name) # update existing user name - data = {'user_name': new_name} - route = '/users/{usr}'.format(usr=self.test_user_name) - resp = utils.test_request(self, 'PUT', route, headers=self.json_headers, cookies=self.cookies, data=data) - utils.check_response_basic_info(resp, 200, expected_method='PUT') + data = {"user_name": new_name} + route = "/users/{usr}".format(usr=self.test_user_name) + resp = utils.test_request(self, "PUT", route, headers=self.json_headers, cookies=self.cookies, data=data) + utils.check_response_basic_info(resp, 200, expected_method="PUT") # validate change of user name - route = '/users/{usr}'.format(usr=new_name) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_equal(body['user']['user_name'], new_name) + route = "/users/{usr}".format(usr=new_name) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_equal(body["user"]["user_name"], new_name) # validate removed previous user name - route = '/users/{usr}'.format(usr=self.test_user_name) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies, + route = "/users/{usr}".format(usr=self.test_user_name) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies, expect_errors=True) - utils.check_response_basic_info(resp, 404, expected_method='GET') + utils.check_response_basic_info(resp, 404, expected_method="GET") # validate effective new user name utils.check_or_try_logout_user(self) headers, cookies = utils.check_or_try_login_user(self, username=new_name, password=self.test_user_name, use_ui_form_submit=True, version=self.version) - resp = utils.test_request(self, 'GET', '/session', headers=headers, cookies=cookies) - body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_equal(body['authenticated'], True) - utils.check_val_equal(body['user']['user_name'], new_name) + resp = utils.test_request(self, "GET", "/session", headers=headers, cookies=cookies) + body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_equal(body["authenticated"], True) + utils.check_val_equal(body["user"]["user_name"], new_name) # validate ineffective previous user name utils.check_or_try_logout_user(self) @@ -599,92 +600,92 @@ def test_PutUsers_username(self): self, username=self.test_user_name, password=self.test_user_name, version=self.version, use_ui_form_submit=True, expect_errors=True) utils.check_val_equal(cookies, {}, msg="CookiesType should be empty from login failure.") - resp = utils.test_request(self, 'GET', '/session', headers=headers, cookies=cookies) - body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_equal(body['authenticated'], False) + resp = utils.test_request(self, "GET", "/session", headers=headers, cookies=cookies) + body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_equal(body["authenticated"], False) @runner.MAGPIE_TEST_USERS def test_PutUsers_email(self): utils.TestSetup.create_TestUser(self) - new_email = 'toto@new-email.lol' - data = {'email': new_email} - route = '/users/{usr}'.format(usr=self.test_user_name) - resp = utils.test_request(self, 'PUT', route, headers=self.json_headers, cookies=self.cookies, data=data) - utils.check_response_basic_info(resp, 200, expected_method='PUT') + new_email = "toto@new-email.lol" + data = {"email": new_email} + route = "/users/{usr}".format(usr=self.test_user_name) + resp = utils.test_request(self, "PUT", route, headers=self.json_headers, cookies=self.cookies, data=data) + utils.check_response_basic_info(resp, 200, expected_method="PUT") - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_equal(body['user']['email'], new_email) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_equal(body["user"]["email"], new_email) @runner.MAGPIE_TEST_USERS def test_PutUsers_password(self): utils.TestSetup.create_TestUser(self) old_password = self.test_user_name - new_password = 'n0t-SO-ez-2-Cr4cK' - data = {'password': new_password} - route = '/users/{usr}'.format(usr=self.test_user_name) - resp = utils.test_request(self, 'PUT', route, headers=self.json_headers, cookies=self.cookies, data=data) - utils.check_response_basic_info(resp, 200, expected_method='PUT') + new_password = "n0t-SO-ez-2-Cr4cK" + data = {"password": new_password} + route = "/users/{usr}".format(usr=self.test_user_name) + resp = utils.test_request(self, "PUT", route, headers=self.json_headers, cookies=self.cookies, data=data) + utils.check_response_basic_info(resp, 200, expected_method="PUT") utils.check_or_try_logout_user(self) # validate that the new password is effective headers, cookies = utils.check_or_try_login_user( self, username=self.test_user_name, password=new_password, use_ui_form_submit=True, version=self.version) - resp = utils.test_request(self, 'GET', '/session', headers=headers, cookies=cookies) - body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_equal(body['authenticated'], True) - utils.check_val_equal(body['user']['user_name'], self.test_user_name) + resp = utils.test_request(self, "GET", "/session", headers=headers, cookies=cookies) + body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_equal(body["authenticated"], True) + utils.check_val_equal(body["user"]["user_name"], self.test_user_name) utils.check_or_try_logout_user(self) # validate that previous password is ineffective headers, cookies = utils.check_or_try_login_user( self, username=self.test_user_name, password=old_password, version=self.version, use_ui_form_submit=True, expect_errors=True) - resp = utils.test_request(self, 'GET', '/session', headers=headers, cookies=cookies) - body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_equal(body['authenticated'], False) + resp = utils.test_request(self, "GET", "/session", headers=headers, cookies=cookies) + body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_equal(body["authenticated"], False) @runner.MAGPIE_TEST_USERS def test_GetUser_existing(self): utils.TestSetup.create_TestUser(self) - route = '/users/{usr}'.format(usr=self.test_user_name) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - utils.check_val_is_in('user', json_body) - utils.check_val_is_in('user_name', json_body['user']) - utils.check_val_type(json_body['user']['user_name'], six.string_types) - utils.check_val_is_in('email', json_body['user']) - utils.check_val_type(json_body['user']['email'], six.string_types) - utils.check_val_is_in('group_names', json_body['user']) - utils.check_val_type(json_body['user']['group_names'], list) + route = "/users/{usr}".format(usr=self.test_user_name) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + utils.check_val_is_in("user", json_body) + utils.check_val_is_in("user_name", json_body["user"]) + utils.check_val_type(json_body["user"]["user_name"], six.string_types) + utils.check_val_is_in("email", json_body["user"]) + utils.check_val_type(json_body["user"]["email"], six.string_types) + utils.check_val_is_in("group_names", json_body["user"]) + utils.check_val_type(json_body["user"]["group_names"], list) else: - utils.check_val_is_in('user_name', json_body) - utils.check_val_type(json_body['user_name'], six.string_types) - utils.check_val_is_in('email', json_body) - utils.check_val_type(json_body['email'], six.string_types) - utils.check_val_is_in('group_names', json_body) - utils.check_val_type(json_body['group_names'], list) + utils.check_val_is_in("user_name", json_body) + utils.check_val_type(json_body["user_name"], six.string_types) + utils.check_val_is_in("email", json_body) + utils.check_val_type(json_body["email"], six.string_types) + utils.check_val_is_in("group_names", json_body) + utils.check_val_type(json_body["group_names"], list) @runner.MAGPIE_TEST_USERS def test_GetUser_missing(self): utils.TestSetup.check_NonExistingTestUser(self) route = '/users/{usr}'.format(usr=self.test_user_name) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies, expect_errors=True) - utils.check_response_basic_info(resp, 404, expected_method='GET') + utils.check_response_basic_info(resp, 404, expected_method="GET") @runner.MAGPIE_TEST_GROUPS @runner.MAGPIE_TEST_DEFAULTS def test_ValidateDefaultGroups(self): - resp = utils.test_request(self, 'GET', '/groups', headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - groups = json_body['group_names'] - utils.check_val_is_in(get_constant('MAGPIE_ANONYMOUS_GROUP'), groups) - utils.check_val_is_in(get_constant('MAGPIE_USERS_GROUP'), groups) - utils.check_val_is_in(get_constant('MAGPIE_ADMIN_GROUP'), groups) + resp = utils.test_request(self, "GET", "/groups", headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + groups = json_body["group_names"] + utils.check_val_is_in(get_constant("MAGPIE_ANONYMOUS_GROUP"), groups) + utils.check_val_is_in(get_constant("MAGPIE_USERS_GROUP"), groups) + utils.check_val_is_in(get_constant("MAGPIE_ADMIN_GROUP"), groups) @runner.MAGPIE_TEST_GROUPS def test_PostUserGroup_assign(self): @@ -694,161 +695,161 @@ def test_PostUserGroup_assign(self): @runner.MAGPIE_TEST_GROUPS def test_PostUserGroup_not_found(self): - route = '/users/{usr}/groups'.format(usr=get_constant('MAGPIE_ADMIN_USER')) - data = {'group_name': 'not_found'} - resp = utils.test_request(self, 'POST', route, expect_errors=True, + route = "/users/{usr}/groups".format(usr=get_constant("MAGPIE_ADMIN_USER")) + data = {"group_name": "not_found"} + resp = utils.test_request(self, "POST", route, expect_errors=True, headers=self.json_headers, cookies=self.cookies, data=data) - utils.check_response_basic_info(resp, 404, expected_method='POST') + utils.check_response_basic_info(resp, 404, expected_method="POST") @runner.MAGPIE_TEST_GROUPS def test_PostUserGroup_conflict(self): - route = '/users/{usr}/groups'.format(usr=get_constant('MAGPIE_ADMIN_USER')) - data = {'group_name': get_constant('MAGPIE_ADMIN_GROUP')} - resp = utils.test_request(self, 'POST', route, expect_errors=True, + route = "/users/{usr}/groups".format(usr=get_constant("MAGPIE_ADMIN_USER")) + data = {"group_name": get_constant("MAGPIE_ADMIN_GROUP")} + resp = utils.test_request(self, "POST", route, expect_errors=True, headers=self.json_headers, cookies=self.cookies, data=data) - utils.check_response_basic_info(resp, 409, expected_method='POST') + utils.check_response_basic_info(resp, 409, expected_method="POST") @runner.MAGPIE_TEST_GROUPS def test_GetGroupUsers(self): - route = '/groups/{grp}/users'.format(grp=get_constant('MAGPIE_ADMIN_GROUP')) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('user_names', json_body) - utils.check_val_type(json_body['user_names'], list) - utils.check_val_is_in(get_constant('MAGPIE_ADMIN_USER'), json_body['user_names']) - utils.check_val_is_in(self.usr, json_body['user_names']) + route = "/groups/{grp}/users".format(grp=get_constant("MAGPIE_ADMIN_GROUP")) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("user_names", json_body) + utils.check_val_type(json_body["user_names"], list) + utils.check_val_is_in(get_constant("MAGPIE_ADMIN_USER"), json_body["user_names"]) + utils.check_val_is_in(self.usr, json_body["user_names"]) @runner.MAGPIE_TEST_GROUPS def test_GetGroupServices(self): - route = '/groups/{grp}/services'.format(grp=self.grp) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('services', json_body) - services = json_body['services'] + route = "/groups/{grp}/services".format(grp=self.grp) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("services", json_body) + services = json_body["services"] utils.check_val_type(services, dict) service_types = utils.get_service_types_for_version(self.version) - # as of version '0.7.0', visible services depend on the connected user permissions, + # as of version 0.7.0, visible services depend on the connected user permissions, # so all services types not necessarily returned in the response - if LooseVersion(self.version) < LooseVersion('0.7.0'): + if LooseVersion(self.version) < LooseVersion("0.7.0"): utils.check_all_equal(services.keys(), service_types, any_order=True) for svc_type in services: utils.check_val_is_in(svc_type, service_types) # one of valid service types for svc in services[svc_type]: svc_dict = services[svc_type][svc] utils.check_val_type(svc_dict, dict) - utils.check_val_is_in('resource_id', svc_dict) - utils.check_val_is_in('service_name', svc_dict) - utils.check_val_is_in('service_type', svc_dict) - utils.check_val_is_in('public_url', svc_dict) - utils.check_val_is_in('permission_names', svc_dict) - utils.check_val_type(svc_dict['resource_id'], int) - utils.check_val_type(svc_dict['service_name'], six.string_types) - utils.check_val_type(svc_dict['service_type'], six.string_types) - utils.check_val_type(svc_dict['public_url'], six.string_types) - utils.check_val_type(svc_dict['permission_names'], list) - if LooseVersion(self.version) >= LooseVersion('0.7.0'): - utils.check_val_is_in('service_sync_type', svc_dict) - utils.check_val_type(svc_dict['service_sync_type'], utils.OptionalStringType) - utils.check_val_not_in('service_url', svc_dict) + utils.check_val_is_in("resource_id", svc_dict) + utils.check_val_is_in("service_name", svc_dict) + utils.check_val_is_in("service_type", svc_dict) + utils.check_val_is_in("public_url", svc_dict) + utils.check_val_is_in("permission_names", svc_dict) + utils.check_val_type(svc_dict["resource_id"], int) + utils.check_val_type(svc_dict["service_name"], six.string_types) + utils.check_val_type(svc_dict["service_type"], six.string_types) + utils.check_val_type(svc_dict["public_url"], six.string_types) + utils.check_val_type(svc_dict["permission_names"], list) + if LooseVersion(self.version) >= LooseVersion("0.7.0"): + utils.check_val_is_in("service_sync_type", svc_dict) + utils.check_val_type(svc_dict["service_sync_type"], utils.OptionalStringType) + utils.check_val_not_in("service_url", svc_dict) else: - utils.check_val_is_in('service_url', svc_dict) - utils.check_val_type(svc_dict['service_url'], six.string_types) + utils.check_val_is_in("service_url", svc_dict) + utils.check_val_type(svc_dict["service_url"], six.string_types) @runner.MAGPIE_TEST_GROUPS def test_GetGroupServiceResources(self): utils.TestSetup.create_TestService(self) utils.TestSetup.create_TestServiceResource(self) - route = '/groups/{grp}/services/{svc}/resources'.format(grp=self.grp, svc=self.test_service_name) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('service', json_body) - svc_dict = json_body['service'] + route = "/groups/{grp}/services/{svc}/resources".format(grp=self.grp, svc=self.test_service_name) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("service", json_body) + svc_dict = json_body["service"] utils.check_val_type(svc_dict, dict) - utils.check_val_is_in('resource_id', svc_dict) - utils.check_val_is_in('service_name', svc_dict) - utils.check_val_is_in('service_type', svc_dict) - utils.check_val_is_in('public_url', svc_dict) - utils.check_val_is_in('permission_names', svc_dict) - utils.check_val_is_in('resources', svc_dict) - utils.check_val_type(svc_dict['resource_id'], int) - utils.check_val_type(svc_dict['service_name'], six.string_types) - utils.check_val_type(svc_dict['service_type'], six.string_types) - utils.check_val_type(svc_dict['public_url'], six.string_types) - utils.check_val_type(svc_dict['permission_names'], list) - utils.check_val_type(svc_dict['resources'], dict) - if LooseVersion(self.version) >= LooseVersion('0.7.0'): - utils.check_val_is_in('service_sync_type', svc_dict) - utils.check_val_type(svc_dict['service_sync_type'], utils.OptionalStringType) - utils.check_val_not_in('service_url', svc_dict) + utils.check_val_is_in("resource_id", svc_dict) + utils.check_val_is_in("service_name", svc_dict) + utils.check_val_is_in("service_type", svc_dict) + utils.check_val_is_in("public_url", svc_dict) + utils.check_val_is_in("permission_names", svc_dict) + utils.check_val_is_in("resources", svc_dict) + utils.check_val_type(svc_dict["resource_id"], int) + utils.check_val_type(svc_dict["service_name"], six.string_types) + utils.check_val_type(svc_dict["service_type"], six.string_types) + utils.check_val_type(svc_dict["public_url"], six.string_types) + utils.check_val_type(svc_dict["permission_names"], list) + utils.check_val_type(svc_dict["resources"], dict) + if LooseVersion(self.version) >= LooseVersion("0.7.0"): + utils.check_val_is_in("service_sync_type", svc_dict) + utils.check_val_type(svc_dict["service_sync_type"], utils.OptionalStringType) + utils.check_val_not_in("service_url", svc_dict) else: - utils.check_val_is_in('service_url', svc_dict) - utils.check_val_type(svc_dict['service_url'], six.string_types) + utils.check_val_is_in("service_url", svc_dict) + utils.check_val_type(svc_dict["service_url"], six.string_types) @runner.MAGPIE_TEST_SERVICES def test_PostService_ResponseFormat(self): json_body = utils.TestSetup.create_TestService(self) - utils.check_val_is_in('service', json_body) - utils.check_val_type(json_body['service'], dict) - utils.check_val_is_in('resource_id', json_body['service']) - utils.check_val_is_in('public_url', json_body['service']) - utils.check_val_is_in('service_url', json_body['service']) - utils.check_val_is_in('service_name', json_body['service']) - utils.check_val_is_in('service_type', json_body['service']) - utils.check_val_is_in('permission_names', json_body['service']) - utils.check_val_type(json_body['service']['resource_id'], int) - utils.check_val_type(json_body['service']['public_url'], six.string_types) - utils.check_val_type(json_body['service']['service_url'], six.string_types) - utils.check_val_type(json_body['service']['service_name'], six.string_types) - utils.check_val_type(json_body['service']['service_type'], six.string_types) - utils.check_val_type(json_body['service']['permission_names'], list) - if LooseVersion(self.version) >= LooseVersion('0.7.0'): - utils.check_val_is_in('service_sync_type', json_body['service']) - utils.check_val_type(json_body['service']['service_sync_type'], utils.OptionalStringType) + utils.check_val_is_in("service", json_body) + utils.check_val_type(json_body["service"], dict) + utils.check_val_is_in("resource_id", json_body["service"]) + utils.check_val_is_in("public_url", json_body["service"]) + utils.check_val_is_in("service_url", json_body["service"]) + utils.check_val_is_in("service_name", json_body["service"]) + utils.check_val_is_in("service_type", json_body["service"]) + utils.check_val_is_in("permission_names", json_body["service"]) + utils.check_val_type(json_body["service"]["resource_id"], int) + utils.check_val_type(json_body["service"]["public_url"], six.string_types) + utils.check_val_type(json_body["service"]["service_url"], six.string_types) + utils.check_val_type(json_body["service"]["service_name"], six.string_types) + utils.check_val_type(json_body["service"]["service_type"], six.string_types) + utils.check_val_type(json_body["service"]["permission_names"], list) + if LooseVersion(self.version) >= LooseVersion("0.7.0"): + utils.check_val_is_in("service_sync_type", json_body["service"]) + utils.check_val_type(json_body["service"]["service_sync_type"], utils.OptionalStringType) @runner.MAGPIE_TEST_SERVICES def test_PutService_UpdateSuccess(self): json_body = utils.TestSetup.create_TestService(self) - service = json_body['service'] - new_svc_name = service['service_name'] + "-updated" - new_svc_url = service['service_url'] + "/updated" + service = json_body["service"] + new_svc_name = service["service_name"] + "-updated" + new_svc_url = service["service_url"] + "/updated" utils.TestSetup.delete_TestService(self, override_service_name=new_svc_name) - path = '/services/{svc}'.format(svc=service['service_name']) - data = {'service_name': new_svc_name, 'service_url': new_svc_url} - resp = utils.test_request(self, 'PUT', path, data=data, headers=self.json_headers, cookies=self.cookies) - body = utils.check_response_basic_info(resp, expected_method='PUT') - utils.check_val_is_in('service', body) - utils.check_val_type(body['service'], dict) - utils.check_val_is_in('resource_id', body['service']) - utils.check_val_is_in('public_url', body['service']) - utils.check_val_is_in('service_url', body['service']) - utils.check_val_is_in('service_name', body['service']) - utils.check_val_is_in('service_type', body['service']) - utils.check_val_is_in('permission_names', body['service']) - utils.check_val_type(body['service']['resource_id'], int) - utils.check_val_type(body['service']['public_url'], six.string_types) - utils.check_val_type(body['service']['service_url'], six.string_types) - utils.check_val_type(body['service']['service_name'], six.string_types) - utils.check_val_type(body['service']['service_type'], six.string_types) - utils.check_val_type(body['service']['permission_names'], list) - if LooseVersion(self.version) >= LooseVersion('0.7.0'): - utils.check_val_is_in('service_sync_type', body['service']) - utils.check_val_type(body['service']['service_sync_type'], utils.OptionalStringType) - utils.check_val_equal(body['service']['service_url'], new_svc_url) - utils.check_val_equal(body['service']['service_name'], new_svc_name) + path = "/services/{svc}".format(svc=service["service_name"]) + data = {"service_name": new_svc_name, "service_url": new_svc_url} + resp = utils.test_request(self, "PUT", path, data=data, headers=self.json_headers, cookies=self.cookies) + body = utils.check_response_basic_info(resp, expected_method="PUT") + utils.check_val_is_in("service", body) + utils.check_val_type(body["service"], dict) + utils.check_val_is_in("resource_id", body["service"]) + utils.check_val_is_in("public_url", body["service"]) + utils.check_val_is_in("service_url", body["service"]) + utils.check_val_is_in("service_name", body["service"]) + utils.check_val_is_in("service_type", body["service"]) + utils.check_val_is_in("permission_names", body["service"]) + utils.check_val_type(body["service"]["resource_id"], int) + utils.check_val_type(body["service"]["public_url"], six.string_types) + utils.check_val_type(body["service"]["service_url"], six.string_types) + utils.check_val_type(body["service"]["service_name"], six.string_types) + utils.check_val_type(body["service"]["service_type"], six.string_types) + utils.check_val_type(body["service"]["permission_names"], list) + if LooseVersion(self.version) >= LooseVersion("0.7.0"): + utils.check_val_is_in("service_sync_type", body["service"]) + utils.check_val_type(body["service"]["service_sync_type"], utils.OptionalStringType) + utils.check_val_equal(body["service"]["service_url"], new_svc_url) + utils.check_val_equal(body["service"]["service_name"], new_svc_name) @runner.MAGPIE_TEST_SERVICES def test_PutService_UpdateConflict(self): body = utils.TestSetup.create_TestService(self) - service = body['service'] - new_svc_name = service['service_name'] + "-updated" - new_svc_url = service['service_url'] + "/updated" + service = body["service"] + new_svc_name = service["service_name"] + "-updated" + new_svc_url = service["service_url"] + "/updated" try: utils.TestSetup.create_TestService(self, override_service_name=new_svc_name) - path = '/services/{svc}'.format(svc=service['service_name']) - data = {'service_name': new_svc_name, 'service_url': new_svc_url} - resp = utils.test_request(self, 'PUT', path, data=data, expect_errors=True, + path = "/services/{svc}".format(svc=service["service_name"]) + data = {"service_name": new_svc_name, "service_url": new_svc_url} + resp = utils.test_request(self, "PUT", path, data=data, expect_errors=True, headers=self.json_headers, cookies=self.cookies) - utils.check_response_basic_info(resp, 409, expected_method='PUT') + utils.check_response_basic_info(resp, 409, expected_method="PUT") finally: utils.TestSetup.delete_TestService(self, override_service_name=new_svc_name) @@ -856,227 +857,227 @@ def test_PutService_UpdateConflict(self): def test_PutService_NoUpdateInfo(self): # no route PUT on '/services/types' (not equivalent to '/services/{service_name}') # so not even a forbidden case to handle - resp = utils.test_request(self, 'PUT', '/services/types', data={}, expect_errors=True, + resp = utils.test_request(self, "PUT", "/services/types", data={}, expect_errors=True, headers=self.json_headers, cookies=self.cookies) - if LooseVersion(self.version) >= LooseVersion('0.9.5'): + if LooseVersion(self.version) >= LooseVersion("0.9.5"): # directly interpreted as expected route `/services/types` behaviour, so method PUT not allowed - utils.check_response_basic_info(resp, 405, expected_method='PUT') + utils.check_response_basic_info(resp, 405, expected_method="PUT") else: # no route with service named 'types', filtered as not found - utils.check_response_basic_info(resp, 404, expected_method='PUT') + utils.check_response_basic_info(resp, 404, expected_method="PUT") @runner.MAGPIE_TEST_SERVICES def test_PutService_ReservedKeyword_Types(self): # try to PUT on 'types' route should raise the error - data = {'service_name': 'dummy', 'service_url': 'dummy'} - resp = utils.test_request(self, 'PUT', '/services/types', data=data, expect_errors=True, + data = {"service_name": "dummy", "service_url": "dummy"} + resp = utils.test_request(self, "PUT", "/services/types", data=data, expect_errors=True, headers=self.json_headers, cookies=self.cookies) - if LooseVersion(self.version) >= LooseVersion('0.9.5'): + if LooseVersion(self.version) >= LooseVersion("0.9.5"): # directly interpreted as expected route `/services/types` behaviour, so method PUT not allowed - utils.check_response_basic_info(resp, 405, expected_method='PUT') + utils.check_response_basic_info(resp, 405, expected_method="PUT") else: # no route with service named 'types', filtered as not found - utils.check_response_basic_info(resp, 404, expected_method='PUT') + utils.check_response_basic_info(resp, 404, expected_method="PUT") - utils.warn_version(self, "check for update service named 'types'", '0.9.1', skip=True) + utils.warn_version(self, "check for update service named 'types'", "0.9.1", skip=True) # try to PUT on valid service with new name 'types' should raise the error utils.TestSetup.create_TestService(self) - path = '/services/{}'.format(self.test_service_name) - data = {'service_name': 'types'} - resp = utils.test_request(self, 'PUT', path, data=data, expect_errors=True, + path = "/services/{}".format(self.test_service_name) + data = {"service_name": "types"} + resp = utils.test_request(self, "PUT", path, data=data, expect_errors=True, headers=self.json_headers, cookies=self.cookies) - utils.check_response_basic_info(resp, 400, expected_method='PUT') # don't allow naming to 'types' + utils.check_response_basic_info(resp, 400, expected_method="PUT") # don't allow naming to 'types' @runner.MAGPIE_TEST_SERVICES def test_GetService_ResponseFormat(self): utils.TestSetup.create_TestService(self) - path = '/services/{svc}'.format(svc=self.test_service_name) - resp = utils.test_request(self, 'GET', path, headers=self.json_headers, cookies=self.cookies) - body = utils.check_response_basic_info(resp, 200, expected_method='GET') - if LooseVersion(self.version) < LooseVersion('0.9.1'): + path = "/services/{svc}".format(svc=self.test_service_name) + resp = utils.test_request(self, "GET", path, headers=self.json_headers, cookies=self.cookies) + body = utils.check_response_basic_info(resp, 200, expected_method="GET") + if LooseVersion(self.version) < LooseVersion("0.9.1"): utils.check_val_is_in(self.test_service_name, body) svc_info = body[self.test_service_name] utils.check_val_type(svc_info, dict) else: - utils.check_val_is_in('service', body) - svc_info = body['service'] + utils.check_val_is_in("service", body) + svc_info = body["service"] utils.check_val_type(svc_info, dict) - utils.check_val_is_in('resource_child_allowed', svc_info) - utils.check_val_is_in('resource_types_allowed', svc_info) - utils.check_val_type(svc_info['resource_child_allowed'], bool) - utils.check_val_type(svc_info['resource_types_allowed'], list) - if svc_info['resource_child_allowed']: - svc_type = svc_info['service_type'] - utils.check_all_equal(svc_info['resource_types_allowed'], service_type_dict[svc_type].resource_types) + utils.check_val_is_in("resource_child_allowed", svc_info) + utils.check_val_is_in("resource_types_allowed", svc_info) + utils.check_val_type(svc_info["resource_child_allowed"], bool) + utils.check_val_type(svc_info["resource_types_allowed"], list) + if svc_info["resource_child_allowed"]: + svc_type = svc_info["service_type"] + utils.check_all_equal(svc_info["resource_types_allowed"], SERVICE_TYPE_DICT[svc_type].resource_types) else: - utils.check_val_equal(len(svc_info['resource_types_allowed']), 0) - utils.check_val_is_in('resource_id', svc_info) - utils.check_val_is_in('service_name', svc_info) - utils.check_val_is_in('service_type', svc_info) - utils.check_val_is_in('public_url', svc_info) - utils.check_val_is_in('permission_names', svc_info) - utils.check_val_type(svc_info['resource_id'], int) - utils.check_val_type(svc_info['service_name'], six.string_types) - utils.check_val_type(svc_info['service_type'], six.string_types) - utils.check_val_type(svc_info['public_url'], six.string_types) - utils.check_val_type(svc_info['permission_names'], list) - if LooseVersion(self.version) >= LooseVersion('0.7.0'): - utils.check_val_is_in('service_sync_type', svc_info) - utils.check_val_type(svc_info['service_sync_type'], utils.OptionalStringType) + utils.check_val_equal(len(svc_info["resource_types_allowed"]), 0) + utils.check_val_is_in("resource_id", svc_info) + utils.check_val_is_in("service_name", svc_info) + utils.check_val_is_in("service_type", svc_info) + utils.check_val_is_in("public_url", svc_info) + utils.check_val_is_in("permission_names", svc_info) + utils.check_val_type(svc_info["resource_id"], int) + utils.check_val_type(svc_info["service_name"], six.string_types) + utils.check_val_type(svc_info["service_type"], six.string_types) + utils.check_val_type(svc_info["public_url"], six.string_types) + utils.check_val_type(svc_info["permission_names"], list) + if LooseVersion(self.version) >= LooseVersion("0.7.0"): + utils.check_val_is_in("service_sync_type", svc_info) + utils.check_val_type(svc_info["service_sync_type"], utils.OptionalStringType) @runner.MAGPIE_TEST_SERVICES def test_GetServiceTypes_ResponseFormat(self): - utils.warn_version(self, "get service types", '0.9.1', skip=True) + utils.warn_version(self, "get service types", "0.9.1", skip=True) - resp = utils.test_request(self, 'GET', '/services/types', headers=self.json_headers, cookies=self.cookies) - body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('service_types', body) - utils.check_val_type(body['service_types'], list) - utils.check_all_equal(body['service_types'], list(service_type_dict.keys()), any_order=True) + resp = utils.test_request(self, "GET", "/services/types", headers=self.json_headers, cookies=self.cookies) + body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("service_types", body) + utils.check_val_type(body["service_types"], list) + utils.check_all_equal(body["service_types"], list(SERVICE_TYPE_DICT.keys()), any_order=True) @runner.MAGPIE_TEST_SERVICES def test_GetServiceTypeResources_ResponseFormat(self): - utils.warn_version(self, "get service type resources", '0.9.1', skip=True) + utils.warn_version(self, "get service type resources", "0.9.1", skip=True) utils.TestSetup.create_TestService(self) - path = '/services/types/{svc_type}/resources'.format(svc_type=self.test_service_type) - resp = utils.test_request(self, 'GET', path, headers=self.json_headers, cookies=self.cookies) - body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('resource_types', body) - utils.check_val_type(body['resource_types'], list) - utils.check_val_equal(len(body['resource_types']) > 0, True) - for rt in body['resource_types']: + path = "/services/types/{svc_type}/resources".format(svc_type=self.test_service_type) + resp = utils.test_request(self, "GET", path, headers=self.json_headers, cookies=self.cookies) + body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("resource_types", body) + utils.check_val_type(body["resource_types"], list) + utils.check_val_equal(len(body["resource_types"]) > 0, True) + for rt in body["resource_types"]: utils.check_val_type(rt, dict) - utils.check_val_is_in('resource_type', rt) - utils.check_val_is_in('resource_child_allowed', rt) - utils.check_val_is_in('permission_names', rt) - utils.check_val_type(rt['resource_type'], six.string_types) - utils.check_val_type(rt['resource_child_allowed'], bool) - utils.check_val_type(rt['permission_names'], list) - for p in rt['permission_names']: + utils.check_val_is_in("resource_type", rt) + utils.check_val_is_in("resource_child_allowed", rt) + utils.check_val_is_in("permission_names", rt) + utils.check_val_type(rt["resource_type"], six.string_types) + utils.check_val_type(rt["resource_child_allowed"], bool) + utils.check_val_type(rt["permission_names"], list) + for p in rt["permission_names"]: utils.check_val_type(p, six.string_types) - utils.check_val_is_in(rt['resource_type'], resource_type_dict) + utils.check_val_is_in(rt["resource_type"], RESOURCE_TYPE_DICT) @runner.MAGPIE_TEST_SERVICES def test_GetServiceTypeResources_CheckValues(self): - utils.warn_version(self, "get service type resources", '0.9.1', skip=True) + utils.warn_version(self, "get service type resources", "0.9.1", skip=True) # evaluate different types of services for svc_type, svc_res_info in [ # recursive child resource allowed - ('api', - {'route': { - 'perms': ['read', 'write', 'read-match', 'write-match'], - 'child': True}}), + (ServiceAPI.service_type, + {"route": { + "perms": ["read", "write", "read-match", "write-match"], + "child": True}}), # child resource allowed only for specific types - ('thredds', - {'directory': { - 'perms': ['read', 'write'], - 'child': True}, - 'file': { - 'perms': ['read', 'write'], - 'child': False}}), + (ServiceTHREDDS.service_type, + {"directory": { + "perms": ["read", "write"], + "child": True}, + "file": { + "perms": ["read", "write"], + "child": False}}), # no child allowed - ('access', {}), + (ServiceAccess.service_type, {}), ]: # test response details - path = '/services/types/{}/resources'.format(svc_type) - resp = utils.test_request(self, 'GET', path, headers=self.json_headers, cookies=self.cookies) - body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_type(body['resource_types'], list) - utils.check_val_equal(len(body['resource_types']), len(svc_res_info)) - for r in body['resource_types']: - utils.check_val_is_in(r['resource_type'], svc_res_info) - r_type = svc_res_info[r['resource_type']] - utils.check_val_equal(r['resource_child_allowed'], r_type['child']) - utils.check_all_equal(r['permission_names'], r_type['perms']) + path = "/services/types/{}/resources".format(svc_type) + resp = utils.test_request(self, "GET", path, headers=self.json_headers, cookies=self.cookies) + body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_type(body["resource_types"], list) + utils.check_val_equal(len(body["resource_types"]), len(svc_res_info)) + for r in body["resource_types"]: + utils.check_val_is_in(r["resource_type"], svc_res_info) + r_type = svc_res_info[r["resource_type"]] + utils.check_val_equal(r["resource_child_allowed"], r_type["child"]) + utils.check_all_equal(r["permission_names"], r_type["perms"]) @runner.MAGPIE_TEST_SERVICES def test_GetServiceResources(self): utils.TestSetup.create_TestService(self) utils.TestSetup.create_TestServiceResource(self) - route = '/services/{svc}/resources'.format(svc=self.test_service_name) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') + route = "/services/{svc}/resources".format(svc=self.test_service_name) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") svc_dict = json_body[self.test_service_name] utils.check_val_is_in(self.test_service_name, json_body) utils.check_val_type(json_body[self.test_service_name], dict) - utils.check_val_is_in('resource_id', svc_dict) - utils.check_val_is_in('service_name', svc_dict) - utils.check_val_is_in('service_type', svc_dict) - utils.check_val_is_in('service_url', svc_dict) - utils.check_val_is_in('public_url', svc_dict) - utils.check_val_is_in('permission_names', svc_dict) - utils.check_val_is_in('resources', svc_dict) - utils.check_val_type(svc_dict['resource_id'], int) - utils.check_val_type(svc_dict['service_name'], six.string_types) - utils.check_val_type(svc_dict['service_url'], six.string_types) - utils.check_val_type(svc_dict['service_type'], six.string_types) - utils.check_val_type(svc_dict['public_url'], six.string_types) - utils.check_val_type(svc_dict['permission_names'], list) - utils.check_resource_children(svc_dict['resources'], svc_dict['resource_id'], svc_dict['resource_id']) - if LooseVersion(self.version) >= LooseVersion('0.7.0'): - utils.check_val_is_in('service_sync_type', svc_dict) - utils.check_val_type(svc_dict['service_sync_type'], utils.OptionalStringType) + utils.check_val_is_in("resource_id", svc_dict) + utils.check_val_is_in("service_name", svc_dict) + utils.check_val_is_in("service_type", svc_dict) + utils.check_val_is_in("service_url", svc_dict) + utils.check_val_is_in("public_url", svc_dict) + utils.check_val_is_in("permission_names", svc_dict) + utils.check_val_is_in("resources", svc_dict) + utils.check_val_type(svc_dict["resource_id"], int) + utils.check_val_type(svc_dict["service_name"], six.string_types) + utils.check_val_type(svc_dict["service_url"], six.string_types) + utils.check_val_type(svc_dict["service_type"], six.string_types) + utils.check_val_type(svc_dict["public_url"], six.string_types) + utils.check_val_type(svc_dict["permission_names"], list) + utils.check_resource_children(svc_dict["resources"], svc_dict["resource_id"], svc_dict["resource_id"]) + if LooseVersion(self.version) >= LooseVersion("0.7.0"): + utils.check_val_is_in("service_sync_type", svc_dict) + utils.check_val_type(svc_dict["service_sync_type"], utils.OptionalStringType) @runner.MAGPIE_TEST_SERVICES def test_GetServicePermissions(self): services_list = utils.TestSetup.get_RegisteredServicesList(self) for svc in services_list: - svc_name = svc['service_name'] - service_perms = service_type_dict[svc['service_type']].permission_names - route = '/services/{svc}/permissions'.format(svc=svc_name) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - utils.check_val_is_in('permission_names', json_body) - utils.check_val_type(json_body['permission_names'], list) - utils.check_all_equal(json_body['permission_names'], service_perms, any_order=True) + svc_name = svc["service_name"] + service_perms = SERVICE_TYPE_DICT[svc["service_type"]].permission_names + route = "/services/{svc}/permissions".format(svc=svc_name) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + utils.check_val_is_in("permission_names", json_body) + utils.check_val_type(json_body["permission_names"], list) + utils.check_all_equal(json_body["permission_names"], service_perms, any_order=True) @runner.MAGPIE_TEST_SERVICES def test_PostServiceResources_DirectResource_NoParentID(self): utils.TestSetup.create_TestService(self) resources_prior = utils.TestSetup.get_TestServiceDirectResources(self) - resources_prior_ids = [res['resource_id'] for res in resources_prior] + resources_prior_ids = [res["resource_id"] for res in resources_prior] json_body = utils.TestSetup.create_TestServiceResource(self) - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - utils.check_val_is_in('resource', json_body) - json_body = json_body['resource'] - utils.check_val_is_in('resource_id', json_body) - utils.check_val_is_in('resource_name', json_body) - utils.check_val_is_in('resource_type', json_body) - utils.check_val_not_in(json_body['resource_id'], resources_prior_ids) - utils.check_val_equal(json_body['resource_name'], self.test_resource_name) - utils.check_val_equal(json_body['resource_type'], self.test_resource_type) + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + utils.check_val_is_in("resource", json_body) + json_body = json_body["resource"] + utils.check_val_is_in("resource_id", json_body) + utils.check_val_is_in("resource_name", json_body) + utils.check_val_is_in("resource_type", json_body) + utils.check_val_not_in(json_body["resource_id"], resources_prior_ids) + utils.check_val_equal(json_body["resource_name"], self.test_resource_name) + utils.check_val_equal(json_body["resource_type"], self.test_resource_type) @runner.MAGPIE_TEST_SERVICES def test_PostServiceResources_DirectResource_WithParentID(self): utils.TestSetup.create_TestService(self) resources_prior = utils.TestSetup.get_TestServiceDirectResources(self) - resources_prior_ids = [res['resource_id'] for res in resources_prior] - service_id = utils.TestSetup.get_ExistingTestServiceInfo(self)['resource_id'] + resources_prior_ids = [res["resource_id"] for res in resources_prior] + service_id = utils.TestSetup.get_ExistingTestServiceInfo(self)["resource_id"] extra_data = {"parent_id": service_id} json_body = utils.TestSetup.create_TestServiceResource(self, extra_data) - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - utils.check_val_is_in('resource', json_body) - json_body = json_body['resource'] - utils.check_val_is_in('resource_id', json_body) - utils.check_val_is_in('resource_name', json_body) - utils.check_val_is_in('resource_type', json_body) - utils.check_val_not_in(json_body['resource_id'], resources_prior_ids) - utils.check_val_equal(json_body['resource_name'], self.test_resource_name) - utils.check_val_equal(json_body['resource_type'], self.test_resource_type) + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + utils.check_val_is_in("resource", json_body) + json_body = json_body["resource"] + utils.check_val_is_in("resource_id", json_body) + utils.check_val_is_in("resource_name", json_body) + utils.check_val_is_in("resource_type", json_body) + utils.check_val_not_in(json_body["resource_id"], resources_prior_ids) + utils.check_val_equal(json_body["resource_name"], self.test_resource_name) + utils.check_val_equal(json_body["resource_type"], self.test_resource_type) @runner.MAGPIE_TEST_SERVICES def test_PostServiceResources_ChildrenResource_ParentID(self): # create the direct resource json_body = utils.TestSetup.create_TestServiceResource(self) resources = utils.TestSetup.get_TestServiceDirectResources(self) - resources_ids = [res['resource_id'] for res in resources] - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - test_resource_id = json_body['resource']['resource_id'] + resources_ids = [res["resource_id"] for res in resources] + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + test_resource_id = json_body["resource"]["resource_id"] else: - test_resource_id = json_body['resource_id'] + test_resource_id = json_body["resource_id"] utils.check_val_is_in(test_resource_id, resources_ids, msg="service resource must exist to create children resource") @@ -1088,48 +1089,48 @@ def test_PostServiceResources_ChildrenResource_ParentID(self): "parent_id": test_resource_id } json_body = utils.TestSetup.create_TestServiceResource(self, data_override) - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - utils.check_val_is_in('resource', json_body) - utils.check_val_type(json_body['resource'], dict) - json_body = json_body['resource'] - utils.check_val_is_in('resource_id', json_body) - utils.check_val_not_in(json_body['resource_id'], resources_ids) - utils.check_val_is_in('resource_name', json_body) - utils.check_val_equal(json_body['resource_name'], child_resource_name) - utils.check_val_is_in('resource_type', json_body) - utils.check_val_equal(json_body['resource_type'], self.test_resource_type) + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + utils.check_val_is_in("resource", json_body) + utils.check_val_type(json_body["resource"], dict) + json_body = json_body["resource"] + utils.check_val_is_in("resource_id", json_body) + utils.check_val_not_in(json_body["resource_id"], resources_ids) + utils.check_val_is_in("resource_name", json_body) + utils.check_val_equal(json_body["resource_name"], child_resource_name) + utils.check_val_is_in("resource_type", json_body) + utils.check_val_equal(json_body["resource_type"], self.test_resource_type) # validate created children resource info - service_root_id = utils.TestSetup.get_ExistingTestServiceInfo(self)['resource_id'] - child_resource_id = json_body['resource_id'] - route = '/resources/{res_id}'.format(res_id=child_resource_id) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - if LooseVersion(self.version) >= LooseVersion('0.9.2'): - utils.check_val_is_in('resource', json_body) - resource_body = json_body['resource'] + service_root_id = utils.TestSetup.get_ExistingTestServiceInfo(self)["resource_id"] + child_resource_id = json_body["resource_id"] + route = "/resources/{res_id}".format(res_id=child_resource_id) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + if LooseVersion(self.version) >= LooseVersion("0.9.2"): + utils.check_val_is_in("resource", json_body) + resource_body = json_body["resource"] else: utils.check_val_is_in(str(child_resource_id), json_body) resource_body = json_body[str(child_resource_id)] - utils.check_val_equal(resource_body['root_service_id'], service_root_id) - utils.check_val_equal(resource_body['parent_id'], test_resource_id) - utils.check_val_equal(resource_body['resource_id'], child_resource_id) - utils.check_val_equal(resource_body['resource_name'], child_resource_name) - utils.check_val_equal(resource_body['resource_type'], self.test_resource_type) - utils.check_val_type(resource_body['children'], dict) - utils.check_val_equal(len(resource_body['children']), 0) + utils.check_val_equal(resource_body["root_service_id"], service_root_id) + utils.check_val_equal(resource_body["parent_id"], test_resource_id) + utils.check_val_equal(resource_body["resource_id"], child_resource_id) + utils.check_val_equal(resource_body["resource_name"], child_resource_name) + utils.check_val_equal(resource_body["resource_type"], self.test_resource_type) + utils.check_val_type(resource_body["children"], dict) + utils.check_val_equal(len(resource_body["children"]), 0) @runner.MAGPIE_TEST_SERVICES def test_PostServiceResources_DirectResource_Conflict(self): utils.TestSetup.create_TestServiceResource(self) - route = '/services/{svc}/resources'.format(svc=self.test_service_name) + route = "/services/{svc}/resources".format(svc=self.test_service_name) data = {"resource_name": self.test_resource_name, "resource_type": self.test_resource_type} - resp = utils.test_request(self, 'POST', route, headers=self.json_headers, + resp = utils.test_request(self, "POST", route, headers=self.json_headers, cookies=self.cookies, json=data, expect_errors=True) - json_body = utils.check_response_basic_info(resp, 409, expected_method='POST') + json_body = utils.check_response_basic_info(resp, 409, expected_method="POST") utils.check_error_param_structure(json_body, version=self.version, is_param_value_literal_unicode=True, param_compare_exists=True, - param_value=self.test_resource_name, param_name=u'resource_name') + param_value=self.test_resource_name, param_name=u"resource_name") @runner.MAGPIE_TEST_SERVICES @runner.MAGPIE_TEST_DEFAULTS @@ -1139,46 +1140,46 @@ def test_ValidateDefaultServiceProviders(self): # ensure that registered services information are all matching the providers in config file # ignore registered services not from providers as their are not explicitly required from the config for svc in services_list: - svc_name = svc['service_name'] + svc_name = svc["service_name"] if svc_name in self.test_services_info: - utils.check_val_equal(svc['service_type'], self.test_services_info[svc_name]['type']) + utils.check_val_equal(svc["service_type"], self.test_services_info[svc_name]["type"]) hostname = utils.get_hostname(self) # private service URL should match format of Magpie (schema/host) - svc_url = self.test_services_info[svc_name]['url'].replace('${HOSTNAME}', hostname) - utils.check_val_equal(svc['service_url'], svc_url) + svc_url = self.test_services_info[svc_name]["url"].replace("${HOSTNAME}", hostname) + utils.check_val_equal(svc["service_url"], svc_url) # public service URL should match Twitcher config, but ignore schema that depends on each server config twitcher_svc_url = get_twitcher_protected_service_url(svc_name, hostname=hostname) twitcher_parsed_url = urlparse(twitcher_svc_url) twitcher_test_url = twitcher_parsed_url.netloc + twitcher_parsed_url.path - svc_parsed_url = urlparse(svc['public_url']) + svc_parsed_url = urlparse(svc["public_url"]) svc_test_public_url = svc_parsed_url.netloc + svc_parsed_url.path utils.check_val_equal(svc_test_public_url, twitcher_test_url) # ensure that no providers are missing from registered services - registered_svc_names = [svc['service_name'] for svc in services_list] + registered_svc_names = [svc["service_name"] for svc in services_list] for svc_name in self.test_services_info: utils.check_val_is_in(svc_name, registered_svc_names) # ensure that 'getcapabilities' permission is given to anonymous for applicable services - anonymous = get_constant('MAGPIE_ANONYMOUS_USER') - services_list_getcap = [svc for svc in services_list if 'getcapabilities' in svc['permission_names']] - route = '/users/{usr}/services'.format(usr=anonymous) - resp = utils.test_request(self, 'GET', route, headers=self.json_headers, cookies=self.cookies) - json_body = utils.check_response_basic_info(resp, 200, expected_method='GET') - services_body = json_body['services'] + anonymous = get_constant("MAGPIE_ANONYMOUS_USER") + services_list_getcap = [svc for svc in services_list if "getcapabilities" in svc["permission_names"]] + route = "/users/{usr}/services".format(usr=anonymous) + resp = utils.test_request(self, "GET", route, headers=self.json_headers, cookies=self.cookies) + json_body = utils.check_response_basic_info(resp, 200, expected_method="GET") + services_body = json_body["services"] for svc in services_list_getcap: - svc_name = svc['service_name'] - svc_type = svc['service_type'] - msg = "Service `{name}` of type `{type}` is expected to have `{perm}` permissions for user `{usr}`" \ - .format(name=svc_name, type=svc_type, perm='getcapabilities', usr=anonymous) + svc_name = svc["service_name"] + svc_type = svc["service_type"] + msg = "Service '{name}' of type '{type}' is expected to have '{perm}' permissions for user '{usr}'." \ + .format(name=svc_name, type=svc_type, perm="getcapabilities", usr=anonymous) utils.check_val_is_in(svc_name, services_body[svc_type], msg=msg) - utils.check_val_is_in('getcapabilities', services_body[svc_type][svc_name]['permission_names']) + utils.check_val_is_in("getcapabilities", services_body[svc_type][svc_name]["permission_names"]) @runner.MAGPIE_TEST_RESOURCES def test_PostResources_DirectServiceResource(self): utils.TestSetup.create_TestService(self) service_info = utils.TestSetup.get_ExistingTestServiceInfo(self) - service_resource_id = service_info['resource_id'] + service_resource_id = service_info["resource_id"] data = { "resource_name": self.test_resource_name, @@ -1186,9 +1187,9 @@ def test_PostResources_DirectServiceResource(self): "resource_type": self.test_resource_type, "parent_id": service_resource_id } - resp = utils.test_request(self, 'POST', '/resources', + resp = utils.test_request(self, "POST", "/resources", headers=self.json_headers, cookies=self.cookies, data=data) - json_body = utils.check_response_basic_info(resp, 201, expected_method='POST') + json_body = utils.check_response_basic_info(resp, 201, expected_method="POST") utils.check_post_resource_structure(json_body, self.test_resource_name, self.test_resource_type, self.test_resource_name, self.version) @@ -1196,7 +1197,7 @@ def test_PostResources_DirectServiceResource(self): def test_PostResources_DirectServiceResourceOptional(self): utils.TestSetup.create_TestService(self) service_info = utils.TestSetup.get_ExistingTestServiceInfo(self) - service_resource_id = service_info['resource_id'] + service_resource_id = service_info["resource_id"] data = { "resource_name": self.test_resource_name, @@ -1204,19 +1205,19 @@ def test_PostResources_DirectServiceResourceOptional(self): "resource_type": self.test_resource_type, "parent_id": service_resource_id } - resp = utils.test_request(self, 'POST', '/resources', + resp = utils.test_request(self, "POST", "/resources", headers=self.json_headers, cookies=self.cookies, data=data) - json_body = utils.check_response_basic_info(resp, 201, expected_method='POST') + json_body = utils.check_response_basic_info(resp, 201, expected_method="POST") utils.check_post_resource_structure(json_body, self.test_resource_name, self.test_resource_type, self.test_resource_name, self.version) @runner.MAGPIE_TEST_RESOURCES def test_PostResources_ChildrenResource(self): resource_info = utils.TestSetup.create_TestServiceResource(self) - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - direct_resource_id = resource_info['resource']['resource_id'] + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + direct_resource_id = resource_info["resource"]["resource_id"] else: - direct_resource_id = resource_info['resource_id'] + direct_resource_id = resource_info["resource_id"] data = { "resource_name": self.test_resource_name, @@ -1224,9 +1225,9 @@ def test_PostResources_ChildrenResource(self): "resource_type": self.test_resource_type, "parent_id": direct_resource_id } - resp = utils.test_request(self, 'POST', '/resources', + resp = utils.test_request(self, "POST", "/resources", headers=self.json_headers, cookies=self.cookies, data=data) - json_body = utils.check_response_basic_info(resp, 201, expected_method='POST') + json_body = utils.check_response_basic_info(resp, 201, expected_method="POST") utils.check_post_resource_structure(json_body, self.test_resource_name, self.test_resource_type, self.test_resource_name, self.version) @@ -1236,23 +1237,23 @@ def test_PostResources_MissingParentID(self): "resource_name": self.test_resource_name, "resource_type": self.test_resource_type, } - resp = utils.test_request(self, 'POST', '/resources', + resp = utils.test_request(self, "POST", "/resources", headers=self.json_headers, cookies=self.cookies, data=data, expect_errors=True) - json_body = utils.check_response_basic_info(resp, 422, expected_method='POST') + json_body = utils.check_response_basic_info(resp, 422, expected_method="POST") utils.check_error_param_structure(json_body, version=self.version, - param_name='parent_id', param_value=repr(None)) + param_name="parent_id", param_value=repr(None)) @runner.MAGPIE_TEST_RESOURCES def test_DeleteResource(self): json_body = utils.TestSetup.create_TestServiceResource(self) - if LooseVersion(self.version) >= LooseVersion('0.6.3'): - resource_id = json_body['resource']['resource_id'] + if LooseVersion(self.version) >= LooseVersion("0.6.3"): + resource_id = json_body["resource"]["resource_id"] else: - resource_id = json_body['resource_id'] + resource_id = json_body["resource_id"] - route = '/resources/{res_id}'.format(res_id=resource_id) - resp = utils.test_request(self, 'DELETE', route, headers=self.json_headers, cookies=self.cookies) - utils.check_response_basic_info(resp, 200, expected_method='DELETE') + route = "/resources/{res_id}".format(res_id=resource_id) + resp = utils.test_request(self, "DELETE", route, headers=self.json_headers, cookies=self.cookies) + utils.check_response_basic_info(resp, 200, expected_method="DELETE") utils.TestSetup.check_NonExistingTestServiceResource(self) @@ -1268,61 +1269,61 @@ class Interface_MagpieUI_NoAuth(Base_Magpie_TestCase): @runner.MAGPIE_TEST_STATUS def test_Home(self): - utils.TestSetup.check_UpStatus(self, method='GET', path='/') + utils.TestSetup.check_UpStatus(self, method="GET", path="/") @runner.MAGPIE_TEST_STATUS def test_Login(self): - utils.TestSetup.check_UpStatus(self, method='GET', path='/ui/login') + utils.TestSetup.check_UpStatus(self, method="GET", path="/ui/login") @runner.MAGPIE_TEST_STATUS def test_ViewUsers(self): - utils.TestSetup.check_Unauthorized(self, method='GET', path='/ui/users') + utils.TestSetup.check_Unauthorized(self, method="GET", path="/ui/users") @runner.MAGPIE_TEST_STATUS def test_ViewGroups(self): - utils.TestSetup.check_Unauthorized(self, method='GET', path='/ui/groups') + utils.TestSetup.check_Unauthorized(self, method="GET", path="/ui/groups") @runner.MAGPIE_TEST_STATUS def test_ViewServices(self): - utils.TestSetup.check_Unauthorized(self, method='GET', path='/ui/services/default') + utils.TestSetup.check_Unauthorized(self, method="GET", path="/ui/services/default") @runner.MAGPIE_TEST_STATUS def test_ViewServicesOfType(self): - path = '/ui/services/{}'.format(self.test_service_type) - utils.TestSetup.check_Unauthorized(self, method='GET', path=path) + path = "/ui/services/{}".format(self.test_service_type) + utils.TestSetup.check_Unauthorized(self, method="GET", path=path) @runner.MAGPIE_TEST_STATUS def test_EditUser(self): - path = '/ui/users/{}/default'.format(self.test_user) - utils.TestSetup.check_Unauthorized(self, method='GET', path=path) + path = "/ui/users/{}/default".format(self.test_user) + utils.TestSetup.check_Unauthorized(self, method="GET", path=path) @runner.MAGPIE_TEST_STATUS def test_EditGroup(self): - path = '/ui/groups/{}/default'.format(self.test_group) - utils.TestSetup.check_Unauthorized(self, method='GET', path=path) + path = "/ui/groups/{}/default".format(self.test_group) + utils.TestSetup.check_Unauthorized(self, method="GET", path=path) @runner.MAGPIE_TEST_STATUS def test_EditService(self): - path = '/ui/services/{type}/{name}'.format(type=self.test_service_type, name=self.test_service_name) - utils.TestSetup.check_Unauthorized(self, method='GET', path=path) + path = "/ui/services/{type}/{name}".format(type=self.test_service_type, name=self.test_service_name) + utils.TestSetup.check_Unauthorized(self, method="GET", path=path) @runner.MAGPIE_TEST_STATUS def test_AddUser(self): - path = '/ui/users/add' - utils.TestSetup.check_Unauthorized(self, method='GET', path=path) - utils.TestSetup.check_Unauthorized(self, method='POST', path=path) + path = "/ui/users/add" + utils.TestSetup.check_Unauthorized(self, method="GET", path=path) + utils.TestSetup.check_Unauthorized(self, method="POST", path=path) @runner.MAGPIE_TEST_STATUS def test_AddGroup(self): - path = '/ui/groups/add' - utils.TestSetup.check_Unauthorized(self, method='GET', path=path) - utils.TestSetup.check_Unauthorized(self, method='POST', path=path) + path = "/ui/groups/add" + utils.TestSetup.check_Unauthorized(self, method="GET", path=path) + utils.TestSetup.check_Unauthorized(self, method="POST", path=path) @runner.MAGPIE_TEST_STATUS def test_AddService(self): - path = '/ui/services/{}/add'.format(self.test_service_type) - utils.TestSetup.check_Unauthorized(self, method='GET', path=path) - utils.TestSetup.check_Unauthorized(self, method='POST', path=path) + path = "/ui/services/{}/add".format(self.test_service_type) + utils.TestSetup.check_Unauthorized(self, method="GET", path=path) + utils.TestSetup.check_Unauthorized(self, method="POST", path=path) # noinspection PyAbstractClass, PyPep8Naming @@ -1343,73 +1344,73 @@ def check_requirements(cls): @runner.MAGPIE_TEST_STATUS def test_Home(self): - utils.TestSetup.check_UpStatus(self, method='GET', path='/') + utils.TestSetup.check_UpStatus(self, method="GET", path="/") @runner.MAGPIE_TEST_STATUS def test_Login(self): - utils.TestSetup.check_UpStatus(self, method='GET', path='/ui/login') + utils.TestSetup.check_UpStatus(self, method="GET", path="/ui/login") @runner.MAGPIE_TEST_STATUS def test_ViewUsers(self): - utils.TestSetup.check_UpStatus(self, method='GET', path='/ui/users') + utils.TestSetup.check_UpStatus(self, method="GET", path="/ui/users") @runner.MAGPIE_TEST_STATUS def test_ViewUsers_GotoEditUser(self): - form = {'edit': None, 'user_name': self.test_user} - resp = utils.TestSetup.check_FormSubmit(self, form_match=form, form_submit='edit', path='/ui/users') + form = {"edit": None, "user_name": self.test_user} + resp = utils.TestSetup.check_FormSubmit(self, form_match=form, form_submit="edit", path="/ui/users") utils.check_val_is_in("Edit User: {}".format(self.test_user), resp.text, msg=utils.null) @runner.MAGPIE_TEST_STATUS def test_ViewGroups(self): - utils.TestSetup.check_UpStatus(self, method='GET', path='/ui/groups') + utils.TestSetup.check_UpStatus(self, method="GET", path="/ui/groups") @runner.MAGPIE_TEST_STATUS def test_ViewGroups_GotoEditGroup(self): - form = {'edit': None, 'group_name': self.test_group} - resp = utils.TestSetup.check_FormSubmit(self, form_match=form, form_submit='edit', path='/ui/groups') + form = {"edit": None, "group_name": self.test_group} + resp = utils.TestSetup.check_FormSubmit(self, form_match=form, form_submit="edit", path="/ui/groups") utils.check_val_is_in("Edit Group: {}".format(self.test_group), resp.text, msg=utils.null) @runner.MAGPIE_TEST_STATUS def test_ViewServicesDefault(self): - utils.TestSetup.check_UpStatus(self, method='GET', path='/ui/services/default') + utils.TestSetup.check_UpStatus(self, method="GET", path="/ui/services/default") @runner.MAGPIE_TEST_STATUS def test_ViewServicesOfType(self): - path = '/ui/services/{}'.format(self.test_service_type) - utils.TestSetup.check_UpStatus(self, method='GET', path=path) + path = "/ui/services/{}".format(self.test_service_type) + utils.TestSetup.check_UpStatus(self, method="GET", path=path) @runner.MAGPIE_TEST_STATUS def test_ViewServices_GotoEditService(self): - form = {'edit': None, 'service_name': self.test_service_name} - path = '/ui/services/{}'.format(self.test_service_type) - resp = utils.TestSetup.check_FormSubmit(self, form_match=form, form_submit='edit', path=path) - find = '{}'.format(self.test_service_name) + form = {"edit": None, "service_name": self.test_service_name} + path = "/ui/services/{}".format(self.test_service_type) + resp = utils.TestSetup.check_FormSubmit(self, form_match=form, form_submit="edit", path=path) + find = "{}".format(self.test_service_name) utils.check_val_is_in(find, resp.text, msg=utils.null) @runner.MAGPIE_TEST_STATUS def test_EditUser(self): - path = '/ui/users/{}/default'.format(self.test_user) - utils.TestSetup.check_UpStatus(self, method='GET', path=path) + path = "/ui/users/{}/default".format(self.test_user) + utils.TestSetup.check_UpStatus(self, method="GET", path=path) @runner.MAGPIE_TEST_STATUS def test_EditUserService(self): - path = '/ui/users/{usr}/{type}'.format(usr=self.test_user, type=self.test_service_type) - utils.TestSetup.check_UpStatus(self, method='GET', path=path) + path = "/ui/users/{usr}/{type}".format(usr=self.test_user, type=self.test_service_type) + utils.TestSetup.check_UpStatus(self, method="GET", path=path) @runner.MAGPIE_TEST_STATUS def test_EditGroup(self): - path = '/ui/groups/{}/default'.format(self.test_group) - utils.TestSetup.check_UpStatus(self, method='GET', path=path) + path = "/ui/groups/{}/default".format(self.test_group) + utils.TestSetup.check_UpStatus(self, method="GET", path=path) @runner.MAGPIE_TEST_STATUS def test_EditGroupService(self): - path = '/ui/groups/{grp}/{type}'.format(grp=self.test_group, type=self.test_service_type) - utils.TestSetup.check_UpStatus(self, method='GET', path=path) + path = "/ui/groups/{grp}/{type}".format(grp=self.test_group, type=self.test_service_type) + utils.TestSetup.check_UpStatus(self, method="GET", path=path) @runner.MAGPIE_TEST_STATUS def test_EditService(self): - path = '/ui/services/{type}/{name}'.format(type=self.test_service_type, name=self.test_service_name) - utils.TestSetup.check_UpStatus(self, method='GET', path=path) + path = "/ui/services/{type}/{name}".format(type=self.test_service_type, name=self.test_service_name) + utils.TestSetup.check_UpStatus(self, method="GET", path=path) @runner.MAGPIE_TEST_LOCAL # not implemented for remote URL @runner.MAGPIE_TEST_STATUS @@ -1421,20 +1422,20 @@ def test_EditService_GotoAddChild_BackToEditService(self): body = utils.TestSetup.create_TestService(self, override_service_name=self.test_service_parent_resource_name, override_service_type=self.test_service_parent_resource_type) - svc_res_id = body['service']['resource_id'] - form = {'add_child': None, 'resource_id': str(svc_res_id)} - path = '/ui/services/{}/{}'.format(self.test_service_parent_resource_type, + svc_res_id = body["service"]["resource_id"] + form = {"add_child": None, "resource_id": str(svc_res_id)} + path = "/ui/services/{}/{}".format(self.test_service_parent_resource_type, self.test_service_parent_resource_name) - resp = utils.TestSetup.check_FormSubmit(self, form_match=form, form_submit='add_child', path=path) + resp = utils.TestSetup.check_FormSubmit(self, form_match=form, form_submit="add_child", path=path) utils.check_val_is_in("New Resource", resp.text, msg=utils.null) # add resource page reached data = { - 'resource_name': self.test_service_child_resource_name, - 'resource_type': self.test_service_child_resource_type, + "resource_name": self.test_service_child_resource_name, + "resource_type": self.test_service_child_resource_type, } - resp = utils.TestSetup.check_FormSubmit(self, form_match='add_resource_form', form_submit='add_child', + resp = utils.TestSetup.check_FormSubmit(self, form_match="add_resource_form", form_submit="add_child", form_data=data, previous_response=resp) for res_name in (self.test_service_parent_resource_name, self.test_service_child_resource_name): - find = '

{}
'.format(res_name) + find = "
{}
".format(res_name) utils.check_val_is_in(find, resp.text, msg=utils.null) finally: utils.TestSetup.delete_TestService(self, override_service_name=self.test_service_parent_resource_name) @@ -1442,17 +1443,17 @@ def test_EditService_GotoAddChild_BackToEditService(self): @runner.MAGPIE_TEST_STATUS def test_AddUser(self): path = '/ui/users/add' - utils.TestSetup.check_UpStatus(self, method='GET', path=path) - utils.TestSetup.check_UpStatus(self, method='POST', path=path) # empty fields, same page but 'incorrect' + utils.TestSetup.check_UpStatus(self, method="GET", path=path) + utils.TestSetup.check_UpStatus(self, method="POST", path=path) # empty fields, same page but 'incorrect' @runner.MAGPIE_TEST_STATUS def test_AddGroup(self): path = '/ui/groups/add' - utils.TestSetup.check_UpStatus(self, method='GET', path=path) - utils.TestSetup.check_UpStatus(self, method='POST', path=path) # empty fields, same page but 'incorrect' + utils.TestSetup.check_UpStatus(self, method="GET", path=path) + utils.TestSetup.check_UpStatus(self, method="POST", path=path) # empty fields, same page but 'incorrect' @runner.MAGPIE_TEST_STATUS def test_AddService(self): path = '/ui/services/{}/add'.format(self.test_service_type) - utils.TestSetup.check_UpStatus(self, method='GET', path=path) - utils.TestSetup.check_UpStatus(self, method='POST', path=path) # empty fields, same page but 'incorrect' + utils.TestSetup.check_UpStatus(self, method="GET", path=path) + utils.TestSetup.check_UpStatus(self, method="POST", path=path) # empty fields, same page but 'incorrect' diff --git a/tests/test_magpie_api.py b/tests/test_magpie_api.py index 87c8da169..68fcaaebe 100644 --- a/tests/test_magpie_api.py +++ b/tests/test_magpie_api.py @@ -8,13 +8,13 @@ Tests for `magpie.api` module. """ -import unittest from magpie.constants import get_constant -from magpie.common import JSON_TYPE +from magpie.utils import CONTENT_TYPE_JSON from tests import utils, runner # NOTE: must be imported without 'from', otherwise the interface's test cases are also executed import tests.interfaces as ti # noqa: F401 +import unittest @runner.MAGPIE_TEST_API @@ -30,7 +30,7 @@ class TestCase_MagpieAPI_NoAuth_Local(ti.Interface_MagpieAPI_NoAuth, unittest.Te @classmethod def setUpClass(cls): cls.app = utils.get_test_magpie_app() - cls.json_headers = utils.get_headers(cls.app, {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE}) + cls.json_headers = utils.get_headers(cls.app, {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON}) cls.cookies = None cls.version = utils.TestSetup.get_Version(cls) cls.usr = get_constant('MAGPIE_ANONYMOUS_USER') @@ -68,7 +68,7 @@ def setUpClass(cls): cls.grp = get_constant('MAGPIE_ADMIN_GROUP') cls.usr = get_constant('MAGPIE_TEST_ADMIN_USERNAME') cls.pwd = get_constant('MAGPIE_TEST_ADMIN_PASSWORD') - cls.json_headers = utils.get_headers(cls.app, {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE}) + cls.json_headers = utils.get_headers(cls.app, {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON}) cls.cookies = None cls.version = utils.TestSetup.get_Version(cls) # TODO: fix UI views so that they can be 'found' directly in the WebTest.TestApp @@ -93,7 +93,7 @@ class TestCase_MagpieAPI_NoAuth_Remote(ti.Interface_MagpieAPI_NoAuth, unittest.T @classmethod def setUpClass(cls): cls.url = get_constant('MAGPIE_TEST_REMOTE_SERVER_URL') - cls.json_headers = utils.get_headers(cls.url, {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE}) + cls.json_headers = utils.get_headers(cls.url, {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON}) cls.cookies = None cls.usr = get_constant('MAGPIE_ANONYMOUS_USER') cls.grp = get_constant('MAGPIE_ANONYMOUS_GROUP') @@ -133,7 +133,7 @@ def setUpClass(cls): cls.url = get_constant('MAGPIE_TEST_REMOTE_SERVER_URL') cls.headers, cls.cookies = utils.check_or_try_login_user(cls.url, cls.usr, cls.pwd) cls.require = "cannot run tests without logged in user with '{}' permissions".format(cls.grp) - cls.json_headers = utils.get_headers(cls.url, {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE}) + cls.json_headers = utils.get_headers(cls.url, {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON}) cls.version = utils.TestSetup.get_Version(cls) cls.check_requirements() cls.setup_test_values() diff --git a/tests/test_magpie_ui.py b/tests/test_magpie_ui.py index 549abbdd6..a1f87c966 100644 --- a/tests/test_magpie_ui.py +++ b/tests/test_magpie_ui.py @@ -8,8 +8,8 @@ Tests for `magpie.ui` module. """ -from magpie.common import JSON_TYPE from magpie.constants import get_constant +from magpie.utils import CONTENT_TYPE_JSON from tests import utils, runner # NOTE: must be imported without 'from', otherwise the interface's test cases are also executed @@ -31,7 +31,7 @@ class TestCase_MagpieUI_NoAuth_Local(ti.Interface_MagpieUI_NoAuth, unittest.Test def setUpClass(cls): cls.app = utils.get_test_magpie_app() cls.url = cls.app # to simplify calls of TestSetup (all use .url) - cls.json_headers = utils.get_headers(cls.app, {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE}) + cls.json_headers = utils.get_headers(cls.app, {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON}) cls.cookies = None cls.test_user = get_constant('MAGPIE_ANONYMOUS_USER') cls.test_group = get_constant('MAGPIE_ANONYMOUS_GROUP') @@ -56,7 +56,7 @@ def setUpClass(cls): cls.pwd = get_constant('MAGPIE_TEST_ADMIN_PASSWORD') cls.app = utils.get_test_magpie_app() cls.url = cls.app # to simplify calls of TestSetup (all use .url) - cls.json_headers = utils.get_headers(cls.app, {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE}) + cls.json_headers = utils.get_headers(cls.app, {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON}) cls.cookies = None cls.version = utils.TestSetup.get_Version(cls) cls.headers, cls.cookies = utils.check_or_try_login_user(cls.url, cls.usr, cls.pwd, use_ui_form_submit=True) @@ -85,7 +85,7 @@ class TestCase_MagpieUI_NoAuth_Remote(ti.Interface_MagpieUI_NoAuth, unittest.Tes @classmethod def setUpClass(cls): cls.url = get_constant('MAGPIE_TEST_REMOTE_SERVER_URL') - cls.json_headers = utils.get_headers(cls.url, {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE}) + cls.json_headers = utils.get_headers(cls.url, {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON}) cls.cookies = None cls.usr = get_constant('MAGPIE_ANONYMOUS_USER') cls.version = utils.TestSetup.get_Version(cls) @@ -110,7 +110,7 @@ def setUpClass(cls): cls.url = get_constant('MAGPIE_TEST_REMOTE_SERVER_URL') cls.headers, cls.cookies = utils.check_or_try_login_user(cls.url, cls.usr, cls.pwd) cls.require = "cannot run tests without logged in '{}' user".format(get_constant('MAGPIE_ADMIN_GROUP')) - cls.json_headers = utils.get_headers(cls.url, {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE}) + cls.json_headers = utils.get_headers(cls.url, {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON}) cls.check_requirements() cls.version = utils.TestSetup.get_Version(cls) cls.test_user = get_constant('MAGPIE_ANONYMOUS_USER') diff --git a/tests/test_register.py b/tests/test_register.py index 4d091eada..4064dede5 100644 --- a/tests/test_register.py +++ b/tests/test_register.py @@ -8,8 +8,8 @@ Tests for `magpie.register` operations. """ from magpie.constants import get_constant -from magpie.common import JSON_TYPE from magpie.db import get_db_session_from_settings +from magpie.utils import CONTENT_TYPE_JSON from magpie import register from tests import utils, runner import unittest @@ -25,7 +25,7 @@ def setUpClass(cls): cls.grp = get_constant('MAGPIE_ADMIN_GROUP') cls.usr = get_constant('MAGPIE_TEST_ADMIN_USERNAME') cls.pwd = get_constant('MAGPIE_TEST_ADMIN_PASSWORD') - cls.json_headers = utils.get_headers(cls.url, {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE}) + cls.json_headers = utils.get_headers(cls.url, {'Accept': CONTENT_TYPE_JSON, 'Content-Type': CONTENT_TYPE_JSON}) cls.cookies = None cls.version = utils.TestSetup.get_Version(cls) # TODO: fix UI views so that they can be 'found' directly in the WebTest.TestApp diff --git a/tests/test_utils.py b/tests/test_utils.py index 689da7071..7063fbd40 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -9,8 +9,7 @@ """ from magpie.api import api_requests as ar, api_except as ax -from magpie.common import get_header, JSON_TYPE -from magpie.definitions.pyramid_definitions import ( # noqa: F401 +from magpie.definitions.pyramid_definitions import ( # noqa: F401 asbool, Request, HTTPInternalServerError, @@ -18,6 +17,7 @@ HTTPBadRequest, HTTPOk, ) +from magpie.utils import get_header, CONTENT_TYPE_JSON from pyramid.testing import DummyRequest from tests import utils, runner from typing import TYPE_CHECKING @@ -83,15 +83,15 @@ def get_post_item(request, name, default=None, p=None): with mock.patch('magpie.api.login.login.get_multiformat_post', side_effect=mock_get_multiformat_post): data = {'user_name': 'foo', 'password': 'bar'} - headers = {'Content-Type': JSON_TYPE, 'Accept': JSON_TYPE} + headers = {'Content-Type': CONTENT_TYPE_JSON, 'Accept': CONTENT_TYPE_JSON} resp = utils.test_request(app, 'POST', paths[0], json=data, headers=headers, expect_errors=True) utils.check_response_basic_info(resp, expected_code=406) # user name doesn't exist def test_get_header_split(self): - headers = {'Content-Type': '{}; charset=UTF-8'.format(JSON_TYPE)} + headers = {'Content-Type': '{}; charset=UTF-8'.format(CONTENT_TYPE_JSON)} for name in ['content_type', 'content-type', 'Content_Type', 'Content-Type', 'CONTENT_TYPE', 'CONTENT-TYPE']: for split in [';,', ',;', ';', (',', ';'), [';', ',']]: - utils.check_val_equal(get_header(name, headers, split=split), JSON_TYPE) + utils.check_val_equal(get_header(name, headers, split=split), CONTENT_TYPE_JSON) def test_get_query_param(self): r = self.make_request('/some/path') diff --git a/tests/utils.py b/tests/utils.py index ffa64f7af..27daac8a0 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,8 +1,7 @@ from magpie import __meta__, services, app -from magpie.common import get_settings_from_config_ini, get_header, JSON_TYPE, HTML_TYPE from magpie.constants import get_constant from magpie.definitions.pyramid_definitions import asbool -from magpie.utils import get_magpie_url +from magpie.utils import get_magpie_url, get_settings_from_config_ini, get_header, CONTENT_TYPE_JSON, CONTENT_TYPE_HTML from six.moves.urllib.parse import urlparse from distutils.version import LooseVersion from pyramid.testing import setUp as PyramidSetUp @@ -29,11 +28,11 @@ class RunOption(object): - __slots__ = ['_name', '_enabled', '_marker'] + __slots__ = ["_name", "_enabled", "_marker"] def __init__(self, name, marker=None): self._name = name - self._marker = marker if marker else name.lower().replace('magpie_test_', '') + self._marker = marker if marker else name.lower().replace("magpie_test_", "") self._enabled = self._default_run() def __call__(self, *args, **kwargs): @@ -44,7 +43,7 @@ def __str__(self): return self.message def __repr__(self): - return '{}[{}]'.format(type(self).__name__, self.message) + return "{}[{}]".format(type(self).__name__, self.message) def _default_run(self): option_value = asbool(get_constant(self._name, default_value=True, @@ -54,7 +53,7 @@ def _default_run(self): @property def message(self): option = " '{}' ".format(self._marker) - status = 'Run' if self._enabled else 'Skip' + status = "Run" if self._enabled else "Skip" return "{}{}tests requested [{}={}].".format(status, option, self._name, self._enabled) @property @@ -126,15 +125,15 @@ def config_setup_from_ini(config_ini_file_path): def get_test_magpie_app(settings=None): # parse settings from ini file to pass them to the application - config = config_setup_from_ini(get_constant('MAGPIE_INI_FILE_PATH')) - config.include('ziggurat_foundations.ext.pyramid.sign_in') - config.include('ziggurat_foundations.ext.pyramid.get_user') - config.registry.settings['magpie.url'] = 'http://localhost:80' - config.registry.settings['magpie.db_migration'] = False + config = config_setup_from_ini(get_constant("MAGPIE_INI_FILE_PATH")) + config.include("ziggurat_foundations.ext.pyramid.sign_in") + config.include("ziggurat_foundations.ext.pyramid.get_user") + config.registry.settings["magpie.url"] = "http://localhost:80" + config.registry.settings["magpie.db_migration"] = False if settings: config.registry.settings.update(settings) # create the test application - config.include('magpie') + config.include("magpie") magpie_app = TestApp(app.main({}, **config.registry.settings)) return magpie_app @@ -164,7 +163,7 @@ def get_headers(app_or_url, header_dict): def get_response_content_types_list(response): - return [ct.strip() for ct in response.headers['Content-Type'].split(';')] + return [ct.strip() for ct in response.headers["Content-Type"].split(";")] def get_json_body(response): @@ -174,9 +173,9 @@ def get_json_body(response): def get_service_types_for_version(version): - available_service_types = set(services.service_type_dict.keys()) - if LooseVersion(version) <= LooseVersion('0.6.1'): - available_service_types = available_service_types - {'access'} + available_service_types = set(services.SERVICE_TYPE_DICT.keys()) + if LooseVersion(version) <= LooseVersion("0.6.1"): + available_service_types = available_service_types - {"access"} return list(available_service_types) @@ -207,12 +206,12 @@ def test_request(test_item, method, path, timeout=5, allow_redirects=True, **kwa :return: response of the request """ method = method.upper() - status = kwargs.pop('status', None) + status = kwargs.pop("status", None) # obtain json body from any json/data/body/params kw and empty {} if not specified # reapply with the expected webtest/requests method kw afterward json_body = None - for kw in ['json', 'data', 'body', 'params']: + for kw in ["json", "data", "body", "params"]: json_body = kwargs.get(kw, json_body) if kw in kwargs: kwargs.pop(kw) @@ -221,24 +220,24 @@ def test_request(test_item, method, path, timeout=5, allow_redirects=True, **kwa app_or_url = get_app_or_url(test_item) if isinstance(app_or_url, TestApp): # remove any 'cookies' keyword handled by the 'TestApp' instance - if 'cookies' in kwargs: - cookies = kwargs.pop('cookies') + if "cookies" in kwargs: + cookies = kwargs.pop("cookies") if cookies and not app_or_url.cookies: app_or_url.cookies.update(cookies) # obtain Content-Type header if specified to ensure it is properly applied - kwargs['content_type'] = get_header('Content-Type', kwargs.get('headers')) + kwargs["content_type"] = get_header("Content-Type", kwargs.get("headers")) # convert JSON body as required - kwargs['params'] = json_body + kwargs["params"] = json_body if json_body is not None: - kwargs.update({'params': json.dumps(json_body, cls=json.JSONEncoder)}) + kwargs.update({"params": json.dumps(json_body, cls=json.JSONEncoder)}) if status and status >= 300: - kwargs.update({'expect_errors': True}) + kwargs.update({"expect_errors": True}) # noinspection PyProtectedMember resp = app_or_url._gen_request(method, path, **kwargs) # automatically follow the redirect if any and evaluate its response - max_redirect = kwargs.get('max_redirects', 5) + max_redirect = kwargs.get("max_redirects", 5) while 300 <= resp.status_code < 400 and max_redirect > 0: resp = resp.follow() max_redirect -= 1 @@ -248,34 +247,34 @@ def test_request(test_item, method, path, timeout=5, allow_redirects=True, **kwa return resp else: # remove keywords specific to TestApp - kwargs.pop('expect_errors', None) + kwargs.pop("expect_errors", None) - kwargs['json'] = json_body - url = '{url}{path}'.format(url=app_or_url, path=path) + kwargs["json"] = json_body + url = "{url}{path}".format(url=app_or_url, path=path) return requests.request(method, url, timeout=timeout, allow_redirects=allow_redirects, **kwargs) def get_session_user(app_or_url, headers=None): # type: (TestAppOrUrlType, Optional[HeadersType]) -> AnyResponseType if not headers: - headers = get_headers(app_or_url, {'Accept': JSON_TYPE, 'Content-Type': JSON_TYPE}) + headers = get_headers(app_or_url, {"Accept": CONTENT_TYPE_JSON, "Content-Type": CONTENT_TYPE_JSON}) if isinstance(app_or_url, TestApp): - resp = app_or_url.get('/session', headers=headers) + resp = app_or_url.get("/session", headers=headers) else: - resp = requests.get('{}/session'.format(app_or_url), headers=headers) + resp = requests.get("{}/session".format(app_or_url), headers=headers) if resp.status_code != 200: - raise Exception('cannot retrieve logged in user information') + raise Exception("cannot retrieve logged in user information") return resp def check_or_try_login_user(test_item, # type: AnyMagpieTestType username=None, # type: Optional[Str] password=None, # type: Optional[Str] - provider='ziggurat', # type: Optional[Str] + provider=None, # type: Optional[Str] headers=None, # type: Optional[Dict[Str, Str]] - use_ui_form_submit=False, # type: Optional[bool] - version=__meta__.__version__, # type: Optional[Str] - expect_errors=False, # type: Optional[bool] + use_ui_form_submit=False, # type: bool + version=__meta__.__version__, # type: Str + expect_errors=False, # type: bool ): # type: (...) -> OptionalHeaderCookiesType """ Verifies that the required user is already logged in (or none is if username=None), or tries to login him otherwise. @@ -284,7 +283,7 @@ def check_or_try_login_user(test_item, # type: AnyMagpieTes :param test_item: instance of the test application or remote server URL to call :param username: name of the user to login or None otherwise :param password: password to use for login if the user was not already logged in - :param provider: provider string to use for login (default: ziggurat, ie: magpie's local signin) + :param provider: provider string to use for login (default: `MAGPIE_DEFAULT_PROVIDER`, ie: magpie's local signin) :param headers: headers to include in the test request :param use_ui_form_submit: use Magpie UI login 'form' to obtain cookies (required for local `WebTest.App` login, ignored by requests using URL) @@ -299,27 +298,28 @@ def check_or_try_login_user(test_item, # type: AnyMagpieTes body = get_json_body(resp) resp_cookies = None - auth = body.get('authenticated', False) + auth = body.get("authenticated", False) if auth is False and username is None: return None, None if auth is False and username is not None: - data = {'user_name': username, 'password': password, 'provider_name': provider} + provider = provider or get_constant("MAGPIE_DEFAULT_PROVIDER") + data = {"user_name": username, "password": password, "provider_name": provider} if isinstance(app_or_url, TestApp): if use_ui_form_submit: - base_url = app_or_url.app.registry.settings.get('magpie.url') - resp = app_or_url.get(url='{}/ui/login'.format(base_url)) - form = resp.forms['login_internal'] - form['user_name'] = username - form['password'] = password - form['provider_name'] = provider - resp = form.submit('submit', expect_errors=expect_errors) + base_url = app_or_url.app.registry.settings.get("magpie.url") + resp = app_or_url.get(url="{}/ui/login".format(base_url)) + form = resp.forms["login_internal"] + form["user_name"] = username + form["password"] = password + form["provider_name"] = provider + resp = form.submit("submit", expect_errors=expect_errors) resp_cookies = app_or_url.cookies # automatically set by form submit else: - resp = app_or_url.post_json('/signin', data, headers=headers) + resp = app_or_url.post_json("/signin", data, headers=headers) resp_cookies = resp.cookies else: - resp = requests.post('{}/signin'.format(app_or_url), json=data, headers=headers) + resp = requests.post("{}/signin".format(app_or_url), json=data, headers=headers) resp_cookies = resp.cookies # response OK (200) if directly from API /signin @@ -328,10 +328,10 @@ def check_or_try_login_user(test_item, # type: AnyMagpieTes return resp.headers, resp_cookies if auth is True: - if LooseVersion(version) >= LooseVersion('0.6.3'): - logged_user = body.get('user', {}).get('user_name', '') + if LooseVersion(version) >= LooseVersion("0.6.3"): + logged_user = body.get("user", {}).get("user_name", "") else: - logged_user = body.get('user_name', '') + logged_user = body.get("user_name", "") if username != logged_user: raise Exception("invalid user") if isinstance(app_or_url, TestApp): @@ -355,12 +355,12 @@ def check_or_try_logout_user(test_item): def _is_logged_out(): resp = get_session_user(app_or_url) body = get_json_body(resp) - auth = body.get('authenticated', False) + auth = body.get("authenticated", False) return not auth if _is_logged_out(): return - resp_logout = test_request(app_or_url, 'GET', '/ui/logout', allow_redirects=True) + resp_logout = test_request(app_or_url, "GET", "/ui/logout", allow_redirects=True) if isinstance(app_or_url, TestApp): app_or_url.reset() # clear app cookies if resp_logout.status_code >= 400: @@ -370,18 +370,18 @@ def _is_logged_out(): raise Exception("logout did not succeed") -def format_test_val_ref(val, ref, pre='Fail', msg=None): +def format_test_val_ref(val, ref, pre="Fail", msg=None): if is_null(msg): - _msg = '({0}) Failed condition between test and reference values.'.format(pre) + _msg = "({0}) Failed condition between test and reference values.".format(pre) else: - _msg = '({0}) Test value: `{1}`, Reference value: `{2}`'.format(pre, val, ref) + _msg = "({0}) Test value: '{1}', Reference value: '{2}'".format(pre, val, ref) if isinstance(msg, six.string_types): - _msg = '{}\n{}'.format(msg, _msg) + _msg = "{}\n{}".format(msg, _msg) return _msg def all_equal(iter_val, iter_ref, any_order=False): - if not (hasattr(iter_val, '__iter__') and hasattr(iter_ref, '__iter__')): + if not (hasattr(iter_val, "__iter__") and hasattr(iter_ref, "__iter__")): return False if len(iter_val) != len(iter_ref): return False @@ -393,27 +393,27 @@ def all_equal(iter_val, iter_ref, any_order=False): def check_all_equal(iter_val, iter_ref, any_order=False, msg=None): r_it_val = repr(iter_val) r_it_ref = repr(iter_ref) - assert all_equal(iter_val, iter_ref, any_order), format_test_val_ref(r_it_val, r_it_ref, pre='Equal Fail', msg=msg) + assert all_equal(iter_val, iter_ref, any_order), format_test_val_ref(r_it_val, r_it_ref, pre="Equal Fail", msg=msg) def check_val_equal(val, ref, msg=None): - assert is_null(ref) or val == ref, format_test_val_ref(val, ref, pre='Equal Fail', msg=msg) + assert is_null(ref) or val == ref, format_test_val_ref(val, ref, pre="Equal Fail", msg=msg) def check_val_not_equal(val, ref, msg=None): - assert is_null(ref) or val != ref, format_test_val_ref(val, ref, pre='Equal Fail', msg=msg) + assert is_null(ref) or val != ref, format_test_val_ref(val, ref, pre="Equal Fail", msg=msg) def check_val_is_in(val, ref, msg=None): - assert is_null(ref) or val in ref, format_test_val_ref(val, ref, pre='Is In Fail', msg=msg) + assert is_null(ref) or val in ref, format_test_val_ref(val, ref, pre="Is In Fail", msg=msg) def check_val_not_in(val, ref, msg=None): - assert is_null(ref) or val not in ref, format_test_val_ref(val, ref, pre='Not In Fail', msg=msg) + assert is_null(ref) or val not in ref, format_test_val_ref(val, ref, pre="Not In Fail", msg=msg) def check_val_type(val, ref, msg=None): - assert isinstance(val, ref), format_test_val_ref(val, repr(ref), pre='Type Fail', msg=msg) + assert isinstance(val, ref), format_test_val_ref(val, repr(ref), pre="Type Fail", msg=msg) def check_raises(func, exception_type): @@ -447,7 +447,7 @@ def check_no_raise(func): raise AssertionError("Exception [{!r}] was raised when none is expected.".format(ex)) -def check_response_basic_info(response, expected_code=200, expected_type=JSON_TYPE, expected_method='GET'): +def check_response_basic_info(response, expected_code=200, expected_type=CONTENT_TYPE_JSON, expected_method="GET"): """ Validates basic Magpie API response metadata. @@ -458,32 +458,32 @@ def check_response_basic_info(response, expected_code=200, expected_type=JSON_TY :return: json body of the response for convenience. """ json_body = get_json_body(response) - check_val_is_in('Content-Type', dict(response.headers), msg="Response doesn't define `Content-Type` header.") + check_val_is_in("Content-Type", dict(response.headers), msg="Response doesn't define 'Content-Type' header.") content_types = get_response_content_types_list(response) check_val_equal(response.status_code, expected_code, msg="Response doesn't match expected HTTP status code.") check_val_is_in(expected_type, content_types, msg="Response doesn't match expected HTTP Content-Type header.") - check_val_is_in('code', json_body, msg="Parameter `code` should be in response JSON body.") - check_val_is_in('type', json_body, msg="Parameter `type` should be in response JSON body.") - check_val_is_in('detail', json_body, msg="Parameter `detail` should be in response JSON body.") - check_val_equal(json_body['code'], expected_code, msg="Parameter `code` should match the HTTP status code.") - check_val_equal(json_body['type'], expected_type, msg="Parameter `type` should match the HTTP Content-Type header.") - check_val_not_equal(json_body['detail'], '', msg="Parameter `detail` should not be empty.") + check_val_is_in("code", json_body, msg="Parameter 'code' should be in response JSON body.") + check_val_is_in("type", json_body, msg="Parameter 'type' should be in response JSON body.") + check_val_is_in("detail", json_body, msg="Parameter 'detail' should be in response JSON body.") + check_val_equal(json_body["code"], expected_code, msg="Parameter 'code' should match the HTTP status code.") + check_val_equal(json_body["type"], expected_type, msg="Parameter 'type' should match the HTTP Content-Type header.") + check_val_not_equal(json_body["detail"], "", msg="Parameter 'detail' should not be empty.") if response.status_code in [401, 404, 500]: - check_val_is_in('request_url', json_body) - check_val_is_in('route_name', json_body) - check_val_is_in('method', json_body) - check_val_equal(json_body['method'], expected_method) + check_val_is_in("request_url", json_body) + check_val_is_in("route_name", json_body) + check_val_is_in("method", json_body) + check_val_equal(json_body["method"], expected_method) return json_body -def check_ui_response_basic_info(response, expected_code=200, expected_type=HTML_TYPE): +def check_ui_response_basic_info(response, expected_code=200, expected_type=CONTENT_TYPE_HTML): msg = None \ - if get_header('Content-Type', response.headers) != JSON_TYPE \ + if get_header('Content-Type', response.headers) != CONTENT_TYPE_JSON \ else "Response body: {}".format(get_json_body(response)) check_val_equal(response.status_code, expected_code, msg=msg) - check_val_is_in('Content-Type', dict(response.headers)) + check_val_is_in("Content-Type", dict(response.headers)) check_val_is_in(expected_type, get_response_content_types_list(response)) check_val_is_in("Magpie Administration", response.text, msg=null) # don't output big html if failing @@ -491,7 +491,7 @@ def check_ui_response_basic_info(response, expected_code=200, expected_type=HTML class null(object): """ Represents a null value to differentiate from None. """ def __repr__(self): - return '' + return "" Null = null() @@ -515,25 +515,25 @@ def check_error_param_structure(json_body, param_value=Null, param_name=Null, pa :raise failing condition """ check_val_type(json_body, dict) - check_val_is_in('param', json_body) + check_val_is_in("param", json_body) version = version or __meta__.__version__ - if LooseVersion(version) >= LooseVersion('0.6.3'): - check_val_type(json_body['param'], dict) - check_val_is_in('value', json_body['param']) - check_val_is_in('name', json_body['param']) - check_val_equal(json_body['param']['name'], param_name) - check_val_equal(json_body['param']['value'], param_value) + if LooseVersion(version) >= LooseVersion("0.6.3"): + check_val_type(json_body["param"], dict) + check_val_is_in("value", json_body["param"]) + check_val_is_in("name", json_body["param"]) + check_val_equal(json_body["param"]["name"], param_name) + check_val_equal(json_body["param"]["value"], param_value) if param_compare_exists: - check_val_is_in('compare', json_body['param']) - check_val_equal(json_body['param']['compare'], param_compare) + check_val_is_in("compare", json_body["param"]) + check_val_equal(json_body["param"]["compare"], param_compare) else: # unicode representation was explicitly returned in value only when of string type if is_param_value_literal_unicode and isinstance(param_value, six.string_types): - param_value = u'u\'{}\''.format(param_value) - check_val_equal(json_body['param'], param_value) + param_value = u"u\'{}\'".format(param_value) + check_val_equal(json_body["param"], param_value) if param_compare_exists: - check_val_is_in('paramCompare', json_body) - check_val_equal(json_body['paramCompare'], param_compare) + check_val_is_in("paramCompare", json_body) + check_val_equal(json_body["paramCompare"], param_compare) def check_post_resource_structure(json_body, resource_name, resource_type, resource_display_name, version=None): @@ -547,24 +547,24 @@ def check_post_resource_structure(json_body, resource_name, resource_type, resou :raise failing condition """ version = version or __meta__.__version__ - if LooseVersion(version) >= LooseVersion('0.6.3'): - check_val_is_in('resource', json_body) - check_val_type(json_body['resource'], dict) - check_val_is_in('resource_name', json_body['resource']) - check_val_is_in('resource_display_name', json_body['resource']) - check_val_is_in('resource_type', json_body['resource']) - check_val_is_in('resource_id', json_body['resource']) - check_val_equal(json_body['resource']['resource_name'], resource_name) - check_val_equal(json_body['resource']['resource_display_name'], resource_display_name) - check_val_equal(json_body['resource']['resource_type'], resource_type) - check_val_type(json_body['resource']['resource_id'], int) + if LooseVersion(version) >= LooseVersion("0.6.3"): + check_val_is_in("resource", json_body) + check_val_type(json_body["resource"], dict) + check_val_is_in("resource_name", json_body["resource"]) + check_val_is_in("resource_display_name", json_body["resource"]) + check_val_is_in("resource_type", json_body["resource"]) + check_val_is_in("resource_id", json_body["resource"]) + check_val_equal(json_body["resource"]["resource_name"], resource_name) + check_val_equal(json_body["resource"]["resource_display_name"], resource_display_name) + check_val_equal(json_body["resource"]["resource_type"], resource_type) + check_val_type(json_body["resource"]["resource_id"], int) else: - check_val_is_in('resource_name', json_body) - check_val_is_in('resource_type', json_body) - check_val_is_in('resource_id', json_body) - check_val_equal(json_body['resource_name'], resource_name) - check_val_equal(json_body['resource_type'], resource_type) - check_val_type(json_body['resource_id'], int) + check_val_is_in("resource_name", json_body) + check_val_is_in("resource_type", json_body) + check_val_is_in("resource_id", json_body) + check_val_equal(json_body["resource_name"], resource_name) + check_val_equal(json_body["resource_type"], resource_type) + check_val_type(json_body["resource_id"], int) def check_resource_children(resource_dict, parent_resource_id, root_service_id): @@ -580,23 +580,23 @@ def check_resource_children(resource_dict, parent_resource_id, root_service_id): check_val_type(resource_id, six.string_types) resource_int_id = int(resource_id) # should by an 'int' string, no error raised resource_info = resource_dict[resource_id] - check_val_is_in('root_service_id', resource_info) - check_val_type(resource_info['root_service_id'], int) - check_val_equal(resource_info['root_service_id'], root_service_id) - check_val_is_in('resource_id', resource_info) - check_val_type(resource_info['resource_id'], int) - check_val_equal(resource_info['resource_id'], resource_int_id) - check_val_is_in('parent_id', resource_info) - check_val_type(resource_info['parent_id'], int) - check_val_equal(resource_info['parent_id'], parent_resource_id) - check_val_is_in('resource_name', resource_info) - check_val_type(resource_info['resource_name'], six.string_types) - check_val_is_in('resource_display_name', resource_info) - check_val_type(resource_info['resource_display_name'], six.string_types) - check_val_is_in('permission_names', resource_info) - check_val_type(resource_info['permission_names'], list) - check_val_is_in('children', resource_info) - check_resource_children(resource_info['children'], resource_int_id, root_service_id) + check_val_is_in("root_service_id", resource_info) + check_val_type(resource_info["root_service_id"], int) + check_val_equal(resource_info["root_service_id"], root_service_id) + check_val_is_in("resource_id", resource_info) + check_val_type(resource_info["resource_id"], int) + check_val_equal(resource_info["resource_id"], resource_int_id) + check_val_is_in("parent_id", resource_info) + check_val_type(resource_info["parent_id"], int) + check_val_equal(resource_info["parent_id"], parent_resource_id) + check_val_is_in("resource_name", resource_info) + check_val_type(resource_info["resource_name"], six.string_types) + check_val_is_in("resource_display_name", resource_info) + check_val_type(resource_info["resource_display_name"], six.string_types) + check_val_is_in("permission_names", resource_info) + check_val_type(resource_info["permission_names"], list) + check_val_is_in("children", resource_info) + check_resource_children(resource_info["children"], resource_int_id, root_service_id) # Generic setup and validation methods across unittests @@ -605,11 +605,11 @@ class TestSetup(object): @staticmethod def get_Version(test_class): app_or_url = get_app_or_url(test_class) - resp = test_request(app_or_url, 'GET', '/version', + resp = test_request(app_or_url, "GET", "/version", headers=test_class.json_headers, cookies=test_class.cookies) json_body = check_response_basic_info(resp, 200) - return json_body['version'] + return json_body["version"] @staticmethod def check_UpStatus(test_class, method, path, timeout=20): @@ -625,9 +625,9 @@ def check_UpStatus(test_class, method, path, timeout=20): return resp @staticmethod - def check_FormSubmit(test_class, form_match, form_data=None, form_submit='submit', - previous_response=None, path=None, method='GET', timeout=20, - expected_code=200, expected_type='text/html', expect_errors=False, max_redirect=5): + def check_FormSubmit(test_class, form_match, form_data=None, form_submit="submit", + previous_response=None, path=None, method="GET", timeout=20, + expected_code=200, expected_type="text/html", expect_errors=False, max_redirect=5): """ Simulates the submission of a UI form to evaluate the status of the resulting page. Follows any redirect if the submission results into a move to another page request. @@ -654,7 +654,7 @@ def check_FormSubmit(test_class, form_match, form_data=None, form_submit='submit """ app_or_url = get_app_or_url(test_class) if not isinstance(app_or_url, TestApp): - test_class.skipTest(reason='test form submit with remote URL not implemented') + test_class.skipTest(reason="test form submit with remote URL not implemented") if isinstance(previous_response, TestResponse): resp = previous_response else: @@ -682,7 +682,7 @@ def check_FormSubmit(test_class, form_match, form_data=None, form_submit='submit return resp @staticmethod - def check_Unauthorized(test_class, method, path, content_type=JSON_TYPE): + def check_Unauthorized(test_class, method, path, content_type=CONTENT_TYPE_JSON): """ Verifies that Magpie returned an Unauthorized response. Validates that at the bare minimum, no underlying internal error occurred from the API or UI calls. @@ -694,61 +694,61 @@ def check_Unauthorized(test_class, method, path, content_type=JSON_TYPE): @staticmethod def get_AnyServiceOfTestServiceType(test_class): app_or_url = get_app_or_url(test_class) - route = '/services/types/{}'.format(test_class.test_service_type) - resp = test_request(app_or_url, 'GET', route, headers=test_class.json_headers, cookies=test_class.cookies) - json_body = check_response_basic_info(resp, 200, expected_method='GET') - check_val_is_in('services', json_body) - check_val_is_in(test_class.test_service_type, json_body['services']) - check_val_not_equal(len(json_body['services'][test_class.test_service_type]), 0, - msg="Missing any required service of type: `{}`".format(test_class.test_service_type)) - services_dict = json_body['services'][test_class.test_service_type] + route = "/services/types/{}".format(test_class.test_service_type) + resp = test_request(app_or_url, "GET", route, headers=test_class.json_headers, cookies=test_class.cookies) + json_body = check_response_basic_info(resp, 200, expected_method="GET") + check_val_is_in("services", json_body) + check_val_is_in(test_class.test_service_type, json_body["services"]) + check_val_not_equal(len(json_body["services"][test_class.test_service_type]), 0, + msg="Missing any required service of type: '{}'".format(test_class.test_service_type)) + services_dict = json_body["services"][test_class.test_service_type] return list(services_dict.values())[0] @staticmethod def create_TestServiceResource(test_class, data_override=None): app_or_url = get_app_or_url(test_class) TestSetup.create_TestService(test_class) - route = '/services/{svc}/resources'.format(svc=test_class.test_service_name) + route = "/services/{svc}/resources".format(svc=test_class.test_service_name) data = { "resource_name": test_class.test_resource_name, "resource_type": test_class.test_resource_type, } if data_override: data.update(data_override) - resp = test_request(app_or_url, 'POST', route, + resp = test_request(app_or_url, "POST", route, headers=test_class.json_headers, cookies=test_class.cookies, json=data) - return check_response_basic_info(resp, 201, expected_method='POST') + return check_response_basic_info(resp, 201, expected_method="POST") @staticmethod def get_ExistingTestServiceInfo(test_class): app_or_url = get_app_or_url(test_class) - route = '/services/{svc}'.format(svc=test_class.test_service_name) - resp = test_request(app_or_url, 'GET', route, + route = "/services/{svc}".format(svc=test_class.test_service_name) + resp = test_request(app_or_url, "GET", route, headers=test_class.json_headers, cookies=test_class.cookies) json_body = get_json_body(resp) - svc_getter = 'service' - if LooseVersion(test_class.version) < LooseVersion('0.9.1'): + svc_getter = "service" + if LooseVersion(test_class.version) < LooseVersion("0.9.1"): svc_getter = test_class.test_service_name return json_body[svc_getter] @staticmethod def get_TestServiceDirectResources(test_class, ignore_missing_service=False): app_or_url = get_app_or_url(test_class) - route = '/services/{svc}/resources'.format(svc=test_class.test_service_name) - resp = test_request(app_or_url, 'GET', route, + route = "/services/{svc}/resources".format(svc=test_class.test_service_name) + resp = test_request(app_or_url, "GET", route, headers=test_class.json_headers, cookies=test_class.cookies, expect_errors=ignore_missing_service) if ignore_missing_service and resp.status_code == 404: return [] json_body = get_json_body(resp) - resources = json_body[test_class.test_service_name]['resources'] + resources = json_body[test_class.test_service_name]["resources"] return [resources[res] for res in resources] @staticmethod def check_NonExistingTestServiceResource(test_class): resources = TestSetup.get_TestServiceDirectResources(test_class, ignore_missing_service=True) - resources_names = [res['resource_name'] for res in resources] + resources_names = [res["resource_name"] for res in resources] check_val_not_in(test_class.test_resource_name, resources_names) @staticmethod @@ -756,12 +756,12 @@ def delete_TestServiceResource(test_class, override_resource_name=None): app_or_url = get_app_or_url(test_class) resource_name = override_resource_name or test_class.test_resource_name resources = TestSetup.get_TestServiceDirectResources(test_class, ignore_missing_service=True) - test_resource = list(filter(lambda r: r['resource_name'] == resource_name, resources)) + test_resource = list(filter(lambda r: r["resource_name"] == resource_name, resources)) # delete as required, skip if non-existing if len(test_resource) > 0: - resource_id = test_resource[0]['resource_id'] - route = '/services/{svc}/resources/{res_id}'.format(svc=test_class.test_service_name, res_id=resource_id) - resp = test_request(app_or_url, 'DELETE', route, + resource_id = test_resource[0]["resource_id"] + route = "/services/{svc}/resources/{res_id}".format(svc=test_class.test_service_name, res_id=resource_id) + resp = test_request(app_or_url, "DELETE", route, headers=test_class.json_headers, cookies=test_class.cookies) check_val_equal(resp.status_code, 200) @@ -773,24 +773,24 @@ def create_TestService(test_class, override_service_name=None, override_service_ svc_name = override_service_name or test_class.test_service_name svc_type = override_service_type or test_class.test_service_type data = { - u'service_name': svc_name, - u'service_type': svc_type, - u'service_url': u'http://localhost:9000/{}'.format(svc_name) + u"service_name": svc_name, + u"service_type": svc_type, + u"service_url": u"http://localhost:9000/{}".format(svc_name) } - resp = test_request(app_or_url, 'POST', '/services', json=data, + resp = test_request(app_or_url, "POST", "/services", json=data, headers=test_class.json_headers, cookies=test_class.cookies, expect_errors=True) if resp.status_code == 409: - path = '/services/{svc}'.format(svc=svc_name) - resp = test_request(app_or_url, 'GET', path, + path = "/services/{svc}".format(svc=svc_name) + resp = test_request(app_or_url, "GET", path, headers=test_class.json_headers, cookies=test_class.cookies) - body = check_response_basic_info(resp, 200, expected_method='GET') - if LooseVersion(test_class.version) < LooseVersion('0.9.1'): - body.update({'service': body[svc_name]}) + body = check_response_basic_info(resp, 200, expected_method="GET") + if LooseVersion(test_class.version) < LooseVersion("0.9.1"): + body.update({"service": body[svc_name]}) body.pop(svc_name) return body - return check_response_basic_info(resp, 201, expected_method='POST') + return check_response_basic_info(resp, 201, expected_method="POST") @staticmethod def check_NonExistingTestService(test_class, override_service_name=None): @@ -804,11 +804,11 @@ def delete_TestService(test_class, override_service_name=None): app_or_url = get_app_or_url(test_class) service_name = override_service_name or test_class.test_service_name services_info = TestSetup.get_RegisteredServicesList(test_class) - test_service = list(filter(lambda r: r['service_name'] == service_name, services_info)) + test_service = list(filter(lambda r: r["service_name"] == service_name, services_info)) # delete as required, skip if non-existing if len(test_service) > 0: - route = '/services/{svc_name}'.format(svc_name=service_name) - resp = test_request(app_or_url, 'DELETE', route, + route = "/services/{svc_name}".format(svc_name=service_name) + resp = test_request(app_or_url, "DELETE", route, headers=test_class.json_headers, cookies=test_class.cookies) check_val_equal(resp.status_code, 200) @@ -817,26 +817,26 @@ def delete_TestService(test_class, override_service_name=None): @staticmethod def get_RegisteredServicesList(test_class): app_or_url = get_app_or_url(test_class) - resp = test_request(app_or_url, 'GET', '/services', + resp = test_request(app_or_url, "GET", "/services", headers=test_class.json_headers, cookies=test_class.cookies) - json_body = check_response_basic_info(resp, 200, expected_method='GET') + json_body = check_response_basic_info(resp, 200, expected_method="GET") # prepare a flat list of registered services services_list = list() - for svc_type in json_body['services']: - services_of_type = json_body['services'][svc_type] + for svc_type in json_body["services"]: + services_of_type = json_body["services"][svc_type] services_list.extend(services_of_type.values()) return services_list @staticmethod def get_RegisteredUsersList(test_class): app_or_url = get_app_or_url(test_class) - resp = test_request(app_or_url, 'GET', '/users', + resp = test_request(app_or_url, "GET", "/users", headers=test_class.json_headers, cookies=test_class.cookies) - json_body = check_response_basic_info(resp, 200, expected_method='GET') - return json_body['user_names'] + json_body = check_response_basic_info(resp, 200, expected_method="GET") + return json_body["user_names"] @staticmethod def check_NonExistingTestUser(test_class, override_user_name=None): @@ -855,10 +855,10 @@ def create_TestUser(test_class, override_data=None): } if override_data: data.update(override_data) - resp = test_request(app_or_url, 'POST', '/users', + resp = test_request(app_or_url, "POST", "/users", headers=test_class.json_headers, cookies=test_class.cookies, json=data) - return check_response_basic_info(resp, 201, expected_method='POST') + return check_response_basic_info(resp, 201, expected_method="POST") @staticmethod def delete_TestUser(test_class, override_user_name=None): @@ -867,21 +867,21 @@ def delete_TestUser(test_class, override_user_name=None): user_name = override_user_name or test_class.test_user_name # delete as required, skip if non-existing if user_name in users: - route = '/users/{usr}'.format(usr=user_name) - resp = test_request(app_or_url, 'DELETE', route, + route = "/users/{usr}".format(usr=user_name) + resp = test_request(app_or_url, "DELETE", route, headers=test_class.json_headers, cookies=test_class.cookies) - check_response_basic_info(resp, 200, expected_method='DELETE') + check_response_basic_info(resp, 200, expected_method="DELETE") TestSetup.check_NonExistingTestUser(test_class, override_user_name=user_name) @staticmethod def get_RegisteredGroupsList(test_class): app_or_url = get_app_or_url(test_class) - resp = test_request(app_or_url, 'GET', '/groups', + resp = test_request(app_or_url, "GET", "/groups", headers=test_class.json_headers, cookies=test_class.cookies) - json_body = check_response_basic_info(resp, 200, expected_method='GET') - return json_body['group_names'] + json_body = check_response_basic_info(resp, 200, expected_method="GET") + return json_body["group_names"] @staticmethod def check_NonExistingTestGroup(test_class, override_group_name=None): @@ -893,10 +893,10 @@ def check_NonExistingTestGroup(test_class, override_group_name=None): def create_TestGroup(test_class, override_group_name=None): app_or_url = get_app_or_url(test_class) data = {"group_name": override_group_name or test_class.test_group_name} - resp = test_request(app_or_url, 'POST', '/groups', + resp = test_request(app_or_url, "POST", "/groups", headers=test_class.json_headers, cookies=test_class.cookies, json=data) - return check_response_basic_info(resp, 201, expected_method='POST') + return check_response_basic_info(resp, 201, expected_method="POST") @staticmethod def delete_TestGroup(test_class, override_group_name=None): @@ -905,9 +905,9 @@ def delete_TestGroup(test_class, override_group_name=None): group_name = override_group_name or test_class.test_group_name # delete as required, skip if non-existing if group_name in groups: - route = '/groups/{grp}'.format(grp=group_name) - resp = test_request(app_or_url, 'DELETE', route, + route = "/groups/{grp}".format(grp=group_name) + resp = test_request(app_or_url, "DELETE", route, headers=test_class.json_headers, cookies=test_class.cookies) - check_response_basic_info(resp, 200, expected_method='DELETE') + check_response_basic_info(resp, 200, expected_method="DELETE") TestSetup.check_NonExistingTestGroup(test_class, override_group_name=group_name)