Esempio n. 1
0
def get_user_resource_permissions_view(request):
    """
    List all permissions a user has on a specific resource.
    """
    user = ar.get_user_matchdict_checked_or_logged(request)
    resource = ar.get_resource_matchdict_checked(request, "resource_id")
    inherit_groups_perms = asbool(ar.get_query_param(request, "inherit"))
    effective_perms = asbool(ar.get_query_param(request, "effective"))
    return uu.get_user_resource_permissions_response(
        user,
        resource,
        request,
        inherit_groups_permissions=inherit_groups_perms,
        effective_permissions=effective_perms)
Esempio n. 2
0
def get_user_service_permissions_view(request):
    """
    List all permissions a user has on a service.
    """
    user = ar.get_user_matchdict_checked_or_logged(request)
    service = ar.get_service_matchdict_checked(request)
    inherit_groups_perms = asbool(ar.get_query_param(request, "inherit"))
    perms = ax.evaluate_call(
        lambda: uu.get_user_service_permissions(service=service,
                                                user=user,
                                                request=request,
                                                inherit_groups_permissions=
                                                inherit_groups_perms),
        fallback=lambda: request.db.rollback(),
        httpError=HTTPNotFound,
        msgOnFail=s.UserServicePermissions_GET_NotFoundResponseSchema.
        description,
        content={
            u"service_name": str(service.resource_name),
            u"user_name": str(user.user_name)
        })
    return ax.valid_http(
        httpSuccess=HTTPOk,
        detail=s.UserServicePermissions_GET_OkResponseSchema.description,
        content={u"permission_names": sorted(p.value for p in perms)})
Esempio n. 3
0
def get_user_service_resources_view(request):
    """
    List all resources under a service a user has permission on.
    """
    inherit_groups_perms = asbool(ar.get_query_param(request, "inherit"))
    user = ar.get_user_matchdict_checked_or_logged(request)
    service = ar.get_service_matchdict_checked(request)
    service_perms = uu.get_user_service_permissions(
        user,
        service,
        request=request,
        inherit_groups_permissions=inherit_groups_perms)
    resources_perms_dict = uu.get_user_service_resources_permissions_dict(
        user,
        service,
        request=request,
        inherit_groups_permissions=inherit_groups_perms)
    user_svc_res_json = format_service_resources(
        service=service,
        db_session=request.db,
        service_perms=service_perms,
        resources_perms_dict=resources_perms_dict,
        show_all_children=False,
        show_private_url=False,
    )
    return ax.valid_http(
        httpSuccess=HTTPOk,
        detail=s.UserServiceResources_GET_OkResponseSchema.description,
        content={u"service": user_svc_res_json})
Esempio n. 4
0
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(),
        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")
    return su.create_service(service_name,
                             service_type,
                             service_url,
                             service_push,
                             db_session=request.db)
Esempio n. 5
0
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))
    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),
                     fallback=lambda: request.db.rollback(),
                     httpError=HTTPForbidden,
                     msgOnFail="Delete service from resource tree failed.",
                     content=svc_content)

    def remove_service_magpie_and_phoenix(svc, svc_push, db_session):
        db_session.delete(svc)
        if svc_push and svc.type in SERVICES_PHOENIX_ALLOWED:
            sync_services_phoenix(db_session.query(models.Service))

    ax.evaluate_call(
        lambda: remove_service_magpie_and_phoenix(service, service_push,
                                                  request.db),
        fallback=lambda: request.db.rollback(),
        httpError=HTTPForbidden,
        msgOnFail=s.Service_DELETE_ForbiddenResponseSchema.description,
        content=svc_content)
    return ax.valid_http(httpSuccess=HTTPOk,
                         detail=s.Service_DELETE_OkResponseSchema.description)
Esempio n. 6
0
 def __init__(self, request):
     super(MagpieOWSSecurity, self).__init__()
     self.magpie_url = get_magpie_url(request)
     self.settings = get_settings(request)
     self.twitcher_ssl_verify = asbool(
         self.settings.get("twitcher.ows_proxy_ssl_verify", True))
     self.twitcher_protected_path = self.settings.get(
         "twitcher.ows_proxy_protected_path", "/ows")
Esempio n. 7
0
 def _default_run(self):
     option_value = asbool(
         get_constant(self._name,
                      default_value=True,
                      raise_missing=False,
                      raise_not_set=False,
                      print_missing=True))
     return True if option_value is None else option_value
Esempio n. 8
0
 def __init__(self, request):
     # type: (Request) -> None
     super(MagpieServiceStore, self).__init__(request)
     self.settings = get_settings(request)
     self.session_factory = request.registry["dbsession_factory"]
     self.magpie_url = get_magpie_url(request)
     self.twitcher_ssl_verify = asbool(
         self.settings.get("twitcher.ows_proxy_ssl_verify", True))
     self.magpie_admin_token = get_admin_cookies(self.settings,
                                                 self.twitcher_ssl_verify)
Esempio n. 9
0
def get_user_services_view(request):
    """
    List all services a user has permissions on.
    """
    user = ar.get_user_matchdict_checked_or_logged(request)
    cascade_resources = asbool(ar.get_query_param(request, "cascade"))
    inherit_groups_perms = asbool(ar.get_query_param(request, "inherit"))
    format_as_list = asbool(ar.get_query_param(request, "list"))

    svc_json = uu.get_user_services(
        user,
        request=request,
        cascade_resources=cascade_resources,
        inherit_groups_permissions=inherit_groups_perms,
        format_as_list=format_as_list)
    return ax.valid_http(
        httpSuccess=HTTPOk,
        content={u"services": svc_json},
        detail=s.UserServices_GET_OkResponseSchema.description)
Esempio n. 10
0
def get_user_resources_view(request):
    """
    List all resources a user has permissions on.
    """
    inherit_groups_perms = asbool(ar.get_query_param(request, "inherit"))
    user = ar.get_user_matchdict_checked_or_logged(request)
    db = request.db

    def build_json_user_resource_tree(usr):
        json_res = {}
        services = ResourceService.all(models.Service, db_session=db)
        for svc in services:
            svc_perms = uu.get_user_service_permissions(
                user=usr,
                service=svc,
                request=request,
                inherit_groups_permissions=inherit_groups_perms)
            if svc.type not in json_res:
                json_res[svc.type] = {}
            res_perms_dict = uu.get_user_service_resources_permissions_dict(
                user=usr,
                service=svc,
                request=request,
                inherit_groups_permissions=inherit_groups_perms)
            json_res[svc.type][svc.resource_name] = format_service_resources(
                svc,
                db_session=db,
                service_perms=svc_perms,
                resources_perms_dict=res_perms_dict,
                show_all_children=False,
                show_private_url=False,
            )
        return json_res

    usr_res_dict = ax.evaluate_call(
        lambda: build_json_user_resource_tree(user),
        fallback=lambda: db.rollback(),
        httpError=HTTPNotFound,
        msgOnFail=s.UserResources_GET_NotFoundResponseSchema.description,
        content={
            u"user_name": user.user_name,
            u"resource_types": [models.Service.resource_type_name]
        })
    return ax.valid_http(
        httpSuccess=HTTPOk,
        content={u"resources": usr_res_dict},
        detail=s.UserResources_GET_OkResponseSchema.description)
Esempio n. 11
0
def delete_resource(request):
    resource = ar.get_resource_matchdict_checked(request)
    service_push = asbool(ar.get_multiformat_post(request, "service_push"))
    res_content = {u"resource": format_resource(resource, basic_info=True)}
    ax.evaluate_call(
        lambda: models.resource_tree_service.delete_branch(resource_id=resource.resource_id, db_session=request.db),
        fallback=lambda: request.db.rollback(), httpError=HTTPForbidden,
        msgOnFail="Delete resource branch from tree service failed.", content=res_content
    )

    def remove_service_magpie_and_phoenix(res, svc_push, db):
        if res.resource_type != "service":
            svc_push = False
        db.delete(res)
        if svc_push:
            sync_services_phoenix(db.query(models.Service))

    ax.evaluate_call(lambda: remove_service_magpie_and_phoenix(resource, service_push, request.db),
                     fallback=lambda: request.db.rollback(), httpError=HTTPForbidden,
                     msgOnFail=s.Resource_DELETE_ForbiddenResponseSchema.description, content=res_content)
    return ax.valid_http(httpSuccess=HTTPOk, detail=s.Resource_DELETE_OkResponseSchema.description)
Esempio n. 12
0
def update_resource(request):
    """
    Update a resource information.
    """
    resource = ar.get_resource_matchdict_checked(request, "resource_id")
    service_push = asbool(ar.get_multiformat_post(request, "service_push"))
    res_old_name = resource.resource_name
    res_new_name = ar.get_value_multiformat_post_checked(request, "resource_name")

    def rename_service_magpie_and_phoenix(res, new_name, svc_push, db):
        if res.resource_type != "service":
            svc_push = False
        res.resource_name = new_name
        if svc_push:
            sync_services_phoenix(db.query(models.Service))

    ax.evaluate_call(lambda: rename_service_magpie_and_phoenix(resource, res_new_name, service_push, request.db),
                     fallback=lambda: request.db.rollback(), httpError=HTTPForbidden,
                     msgOnFail=s.Resource_PUT_ForbiddenResponseSchema.description,
                     content={u"resource_id": resource.resource_id, u"resource_name": resource.resource_name,
                              u"old_resource_name": res_old_name, u"new_resource_name": res_new_name})
    return ax.valid_http(httpSuccess=HTTPOk, detail=s.Resource_PUT_OkResponseSchema.description,
                         content={u"resource_id": resource.resource_id, u"resource_name": resource.resource_name,
                                  u"old_resource_name": res_old_name, u"new_resource_name": res_new_name})
Esempio n. 13
0
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_GROUP = MAGPIE_ANONYMOUS_USER  # left for backward compatibility of migration scripts
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))            # run db migration on startup
MAGPIE_DB_MIGRATION_ATTEMPTS = int(os.getenv("MAGPIE_DB_MIGRATION_ATTEMPTS", 5))
MAGPIE_LOG_LEVEL = os.getenv("MAGPIE_LOG_LEVEL", _get_default_log_level())      # log level to apply to the loggers
MAGPIE_LOG_PRINT = asbool(os.getenv("MAGPIE_LOG_PRINT", False))                 # log also forces print to the console
MAGPIE_LOG_REQUEST = asbool(os.getenv("MAGPIE_LOG_REQUEST", True))              # log detail of every incoming request
MAGPIE_LOG_EXCEPTION = asbool(os.getenv("MAGPIE_LOG_EXCEPTION", True))          # log detail of generated exceptions
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
Esempio n. 14
0
def run_database_migration_when_ready(settings, db_session=None):
    # type: (SettingsType, Optional[Session]) -> None
    """
    Runs db migration if requested by config and need from revisions.
    """

    db_ready = False
    if asbool(
            get_constant("MAGPIE_DB_MIGRATION",
                         settings,
                         "magpie.db_migration",
                         default_value=True,
                         raise_missing=False,
                         raise_not_set=False,
                         print_missing=True)):
        attempts = int(
            get_constant("MAGPIE_DB_MIGRATION_ATTEMPTS",
                         settings,
                         "magpie.db_migration_attempts",
                         default_value=5,
                         raise_missing=False,
                         raise_not_set=False,
                         print_missing=True))

        print_log("Running database migration (as required)...")
        attempts = max(
            attempts, 2
        )  # enforce at least 2 attempts, 1 for db creation and one for actual migration
        for i in range(1, attempts + 1):
            try:
                with warnings.catch_warnings():
                    warnings.simplefilter("ignore", category=sa_exc.SAWarning)
                    run_database_migration(db_session)
            except ImportError as e:
                print_log(
                    "Database migration produced [{!r}] (ignored).".format(e),
                    level=logging.WARNING)
                pass
            except Exception as e:
                if i <= attempts:
                    print_log(
                        "Database migration failed [{!r}]. Retrying... ({}/{})"
                        .format(e, i, attempts))
                    time.sleep(2)
                    continue
                else:
                    raise_log("Database migration failed [{!r}]".format(e),
                              exception=RuntimeError)

            db_ready = is_database_ready(db_session)
            if not db_ready:
                print_log("Database not ready. Retrying... ({}/{})".format(
                    i, attempts))
                time.sleep(2)
                continue
            break
    else:
        db_ready = is_database_ready(db_session)
    if not db_ready:
        time.sleep(2)
        raise_log("Database not ready", exception=RuntimeError)
Esempio n. 15
0
def authomatic_config(request=None):

    defaults_config = {
        'popup': True,
    }

    openid_config = {
        'openid': {
            'class_': openid.OpenID,
            'display_name': 'OpenID',
        },
    }

    esgf_config = {
        'dkrz': {
            'class_': esgfopenid.ESGFOpenID,
            'hostname': 'esgf-data.dkrz.de',
            'provider_url': 'https://{hostname}/esgf-idp/openid/{username}',
            'display_name': 'DKRZ',
        },
        'ipsl': {
            'class_': esgfopenid.ESGFOpenID,
            'hostname': 'providers-node.ipsl.fr',
            'display_name': 'IPSL',
        },
        'badc': {
            'class_': esgfopenid.ESGFOpenID,
            'hostname': 'ceda.ac.uk',
            'provider_url': 'https://{hostname}/openid/{username}',
            'display_name': 'BADC',
        },
        'pcmdi': {
            'class_': esgfopenid.ESGFOpenID,
            'hostname': 'providers-node.llnl.gov',
            'display_name': 'PCMDI',
        },
        'smhi': {
            'class_': esgfopenid.ESGFOpenID,
            'hostname': 'esg-dn1.nsc.liu.se',
            'display_name': 'SMHI',
        },
    }

    _get_const_info = dict(raise_missing=False,
                           raise_not_set=False,
                           print_missing=True)
    oauth2_config = {
        'github': {
            'class_':
            oauth2.GitHub,
            'display_name':
            'GitHub',
            'consumer_key':
            get_constant('GITHUB_CLIENT_ID', **_get_const_info),
            'consumer_secret':
            get_constant('GITHUB_CLIENT_SECRET', **_get_const_info),
            'redirect_uri':
            request.application_url if request else None,
            # 'redirect_uri': '{}/providers/github/signin'.format(request.application_url) if request else None,
            'access_headers': {
                'User-Agent': 'Magpie'
            },
            'id':
            provider_id(),
            '_apis': {
                'Get your events':
                ('GET', 'https://api.github.com/users/{user.username}/events'),
                'Get your watched repos':
                ('GET', 'https://api.github.com/user/subscriptions'),
            },
        },
        'wso2': {
            'class_':
            wso2.WSO2,
            'display_name':
            'WSO2',
            'hostname':
            get_constant('WSO2_HOSTNAME', **_get_const_info),
            'consumer_key':
            get_constant('WSO2_CLIENT_ID', **_get_const_info),
            'consumer_secret':
            get_constant('WSO2_CLIENT_SECRET', **_get_const_info),
            'certificate_file':
            get_constant('WSO2_CERTIFICATE_FILE', **_get_const_info)
            or None,  # replace if == ''
            'ssl_verify':
            asbool(
                get_constant('WSO2_SSL_VERIFY',
                             default_value=True,
                             **_get_const_info)),
            'redirect_uri':
            '{}/providers/wso2/signin'.format(request.application_url)
            if request else None,
            'id':
            provider_id(),
        }
    }

    # Concatenate the configs.
    config = {}  # type: JSON
    config.update(oauth2_config)
    config.update(openid_config)
    config.update(esgf_config)
    config['__defaults__'] = defaults_config
    return config
Esempio n. 16
0
    def edit_service(self):
        cur_svc_type = self.request.matchdict["cur_svc_type"]
        service_name = self.request.matchdict["service_name"]
        service_data = self.get_service_data(service_name)
        service_url = service_data["service_url"]
        service_perm = service_data["permission_names"]
        service_id = service_data["resource_id"]
        # apply default state if arriving on the page for the first time
        # future editions on the page will transfer the last saved state
        service_push_show = cur_svc_type in register.SERVICES_PHOENIX_ALLOWED
        service_push = asbool(
            self.request.POST.get("service_push", service_push_show))

        service_info = {
            u"edit_mode":
            u"no_edit",
            u"service_name":
            service_name,
            u"service_url":
            service_url,
            u"public_url":
            register.get_twitcher_protected_service_url(service_name),
            u"service_perm":
            service_perm,
            u"service_id":
            service_id,
            u"service_push":
            service_push,
            u"service_push_show":
            service_push_show,
            u"cur_svc_type":
            cur_svc_type
        }

        if "edit_name" in self.request.POST:
            service_info["edit_mode"] = u"edit_name"

        if "save_name" in self.request.POST:
            new_svc_name = self.request.POST.get("new_svc_name")
            if service_name != new_svc_name and new_svc_name != "":
                self.update_service_name(service_name, new_svc_name,
                                         service_push)
                service_info["service_name"] = new_svc_name
                service_info[
                    "public_url"] = register.get_twitcher_protected_service_url(
                        new_svc_name),
            service_info["edit_mode"] = u"no_edit"
            # return directly to "regenerate" the URL with the modified name
            return HTTPFound(
                self.request.route_url("edit_service", **service_info))

        if "edit_url" in self.request.POST:
            service_info["edit_mode"] = u"edit_url"

        if "save_url" in self.request.POST:
            new_svc_url = self.request.POST.get("new_svc_url")
            if service_url != new_svc_url and new_svc_url != "":
                self.update_service_url(service_name, new_svc_url,
                                        service_push)
                service_info["service_url"] = new_svc_url
            service_info["edit_mode"] = u"no_edit"

        if "delete" in self.request.POST:
            service_data = json.dumps({u"service_push": service_push})
            path = schemas.ServiceAPI.path.format(service_name=service_name)
            resp = request_api(self.request, path, "DELETE", data=service_data)
            check_response(resp)
            return HTTPFound(
                self.request.route_url("view_services", **service_info))

        if "delete_child" in self.request.POST:
            resource_id = self.request.POST.get("resource_id")
            path = schemas.ResourceAPI.path.format(resource_id=resource_id)
            resp = request_api(self.request, path, "DELETE")
            check_response(resp)

        if "add_child" in self.request.POST:
            service_info["resource_id"] = self.request.POST.get("resource_id")
            return HTTPFound(
                self.request.route_url("add_resource", **service_info))

        resources, resources_id_type = self.get_service_resources(service_name)
        path = schemas.ServiceAPI.path.format(service_name=service_name)
        resp = request_api(self.request, path, "GET")
        check_response(resp)
        svc_body = get_json(resp)["service"]

        # 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[
            "service_no_child"] = not svc_body["resource_child_allowed"]
        return add_template_data(self.request, service_info)
Esempio n. 17
0
    def edit_user(self):
        user_name = self.request.matchdict["user_name"]
        cur_svc_type = self.request.matchdict["cur_svc_type"]
        inherit_grp_perms = self.request.matchdict.get(
            "inherit_groups_permissions", False)

        own_groups = self.get_user_groups(user_name)
        all_groups = self.get_all_groups(
            first_default_group=get_constant("MAGPIE_USERS_GROUP"))

        # TODO:
        #   Until the api is modified to make it possible to request from the RemoteResource table,
        #   we have to access the database directly here
        session = self.request.db

        try:
            # The service type is "default". This function replaces cur_svc_type with the first service type.
            svc_types, cur_svc_type, services = self.get_services(cur_svc_type)
        except Exception as e:
            raise HTTPBadRequest(detail=repr(e))

        user_path = schemas.UserAPI.path.format(user_name=user_name)
        user_resp = request_api(self.request, user_path, "GET")
        check_response(user_resp)
        user_info = get_json(user_resp)["user"]
        user_info[u"edit_mode"] = u"no_edit"
        user_info[u"own_groups"] = own_groups
        user_info[u"groups"] = all_groups
        user_info[u"inherit_groups_permissions"] = inherit_grp_perms
        error_message = ""

        # In case of update, changes are not reflected when calling
        # get_user_or_group_resources_permissions_dict so we must take care
        # of them
        res_id = None
        removed_perms = None
        new_perms = None

        if self.request.method == "POST":
            res_id = self.request.POST.get(u"resource_id")
            is_edit_group_membership = False
            is_save_user_info = False
            requires_update_name = False

            if u"inherit_groups_permissions" in self.request.POST:
                inherit_grp_perms = asbool(
                    self.request.POST[u"inherit_groups_permissions"])
                user_info[u"inherit_groups_permissions"] = inherit_grp_perms

            if u"delete" in self.request.POST:
                resp = request_api(self.request, user_path, "DELETE")
                check_response(resp)
                return HTTPFound(self.request.route_url("view_users"))
            elif u"goto_service" in self.request.POST:
                return self.goto_service(res_id)
            elif u"clean_resource" in self.request.POST:
                # "clean_resource" must be above "edit_permissions" because they"re in the same form.
                self.delete_resource(res_id)
            elif u"edit_permissions" in self.request.POST:
                if not res_id or res_id == "None":
                    remote_id = int(self.request.POST.get("remote_id"))
                    services_names = [
                        s["service_name"] for s in services.values()
                    ]
                    res_id = self.add_remote_resource(cur_svc_type,
                                                      services_names,
                                                      user_name,
                                                      remote_id,
                                                      is_user=True)

                removed_perms, new_perms = \
                    self.edit_user_or_group_resource_permissions(user_name, res_id, is_user=True)
            elif u"edit_group_membership" in self.request.POST:
                is_edit_group_membership = True
            elif u"edit_username" in self.request.POST:
                user_info[u"edit_mode"] = u"edit_username"
            elif u"edit_password" in self.request.POST:
                user_info[u"edit_mode"] = u"edit_password"
            elif u"edit_email" in self.request.POST:
                user_info[u"edit_mode"] = u"edit_email"
            elif u"save_username" in self.request.POST:
                user_info[u"user_name"] = self.request.POST.get(
                    u"new_user_name")
                is_save_user_info = True
                requires_update_name = True
            elif u"save_password" in self.request.POST:
                user_info[u"password"] = self.request.POST.get(
                    u"new_user_password")
                is_save_user_info = True
            elif u"save_email" in self.request.POST:
                user_info[u"email"] = self.request.POST.get(u"new_user_email")
                is_save_user_info = True
            elif u"force_sync" in self.request.POST:
                errors = []
                for service_info in services.values():
                    # noinspection PyBroadException
                    try:
                        sync_resources.fetch_single_service(
                            service_info["resource_id"], session)
                    except Exception:
                        errors.append(service_info["service_name"])
                if errors:
                    error_message += self.make_sync_error_message(errors)
            elif u"clean_all" in self.request.POST:
                ids_to_clean = self.request.POST.get("ids_to_clean").split(";")
                for id_ in ids_to_clean:
                    self.delete_resource(id_)

            if is_save_user_info:
                resp = request_api(self.request,
                                   user_path,
                                   "PUT",
                                   data=user_info)
                check_response(resp)
                # need to commit updates since we are using the same session
                # otherwise, updated user doesn't exist yet in the db for next calls
                self.request.tm.commit()

            # always remove password from output
            user_info.pop(u"password", None)

            if requires_update_name:
                # re-fetch user groups as current user-group will have changed on new user_name
                user_name = user_info[u"user_name"]
                user_info[u"own_groups"] = self.get_user_groups(user_name)
                # return immediately with updated URL to user with new name
                users_url = self.request.route_url("edit_user",
                                                   user_name=user_name,
                                                   cur_svc_type=cur_svc_type)
                return HTTPMovedPermanently(location=users_url)

            # edits to groups checkboxes
            if is_edit_group_membership:
                selected_groups = self.request.POST.getall("member")
                removed_groups = list(set(own_groups) - set(selected_groups))
                new_groups = list(set(selected_groups) - set(own_groups))
                for group in removed_groups:
                    path = schemas.UserGroupAPI.path.format(
                        user_name=user_name, group_name=group)
                    resp = request_api(self.request, path, "DELETE")
                    check_response(resp)
                for group in new_groups:
                    path = schemas.UserGroupsAPI.path.format(
                        user_name=user_name)
                    data = {"group_name": group}
                    resp = request_api(self.request, path, "POST", data=data)
                    check_response(resp)
                user_info[u"own_groups"] = self.get_user_groups(user_name)

        # display resources permissions per service type tab
        try:
            res_perm_names, res_perms = self.get_user_or_group_resources_permissions_dict(
                user_name,
                services,
                cur_svc_type,
                is_user=True,
                is_inherit_groups_permissions=inherit_grp_perms)
        except Exception as e:
            raise HTTPBadRequest(detail=repr(e))

        if res_id and (removed_perms or new_perms):
            self.update_user_or_group_resources_permissions_dict(
                res_perms, res_id, removed_perms, new_perms)

        sync_types = [s["service_sync_type"] for s in services.values()]
        sync_implemented = any(s in sync_resources.SYNC_SERVICES_TYPES
                               for s in sync_types)

        info = self.get_remote_resources_info(res_perms, services, session)
        res_perms, ids_to_clean, last_sync_humanized, out_of_sync = info

        if out_of_sync:
            error_message = self.make_sync_error_message(out_of_sync)

        user_info[u"error_message"] = error_message
        user_info[u"ids_to_clean"] = ";".join(ids_to_clean)
        user_info[u"last_sync"] = last_sync_humanized
        user_info[u"sync_implemented"] = sync_implemented
        user_info[u"out_of_sync"] = out_of_sync
        user_info[u"cur_svc_type"] = cur_svc_type
        user_info[u"svc_types"] = svc_types
        user_info[u"resources"] = res_perms
        user_info[u"permissions"] = res_perm_names
        return add_template_data(self.request, data=user_info)
Esempio n. 18
0
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))

    def select_update(new_value, 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,
        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",
        httpError=HTTPBadRequest,
        msgOnFail=s.Service_PUT_BadRequestResponseSchema.description)

    if svc_name != service.resource_name:
        all_svc_names = list()
        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)})

    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 = 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
    }
    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)
                         })
Esempio n. 19
0
def main(global_config=None, **settings):
    """
    This function returns a Pyramid WSGI application.
    """
    config_ini = get_constant("MAGPIE_INI_FILE_PATH", raise_missing=True)

    print_log("Setting up loggers...", LOGGER)
    log_lvl = get_constant("MAGPIE_LOG_LEVEL", settings, "magpie.log_level", default_value="INFO",
                           raise_missing=False, raise_not_set=False, print_missing=True)
    LOGGER.setLevel(log_lvl)
    sa_settings = db.set_sqlalchemy_log_level(log_lvl)

    print_log("Looking for db migration requirement...", LOGGER)
    db.run_database_migration_when_ready(settings)  # cannot pass db session as it might not even exist yet!

    # HACK:
    #   migration can cause sqlalchemy engine to reset its internal logger level, although it is properly set
    #   to 'echo=False' because engines are re-created as needed... (ie: missing db)
    #   apply configs to re-enforce the logging level of `sqlalchemy.engine.base.Engine`"""
    db.set_sqlalchemy_log_level(log_lvl)
    # fetch db session here, otherwise, any following db engine connection will re-initialize
    # with a new engine class and logging settings don't get re-evaluated/applied
    db_session = db.get_db_session_from_config_ini(config_ini, settings_override=sa_settings)

    print_log("Register default users...", LOGGER)
    register_default_users(db_session=db_session, settings=settings)

    print_log("Register configuration providers...", logger=LOGGER)
    push_phoenix = asbool(get_constant("PHOENIX_PUSH", settings, settings_name="magpie.phoenix_push",
                                       raise_missing=False, raise_not_set=False, print_missing=True))
    prov_cfg = get_constant("MAGPIE_PROVIDERS_CONFIG_PATH", default_value="",
                            raise_missing=False, raise_not_set=False, print_missing=True)
    if os.path.isfile(prov_cfg):
        magpie_register_services_from_config(prov_cfg, push_to_phoenix=push_phoenix,
                                             force_update=True, disable_getcapabilities=False, db_session=db_session)
    else:
        print_log("No configuration file found for providers registration, skipping...", LOGGER, logging.WARN)

    print_log("Register configuration permissions...", LOGGER)
    perm_cfg = get_constant("MAGPIE_PERMISSIONS_CONFIG_PATH", default_value="",
                            raise_missing=False, raise_not_set=False, print_missing=True)
    if os.path.isfile(perm_cfg):
        magpie_register_permissions_from_config(get_constant("MAGPIE_PERMISSIONS_CONFIG_PATH"), db_session=db_session)
    else:
        print_log("No configuration file found for permissions registration, skipping...", LOGGER, logging.WARN)

    print_log("Running configurations setup...", LOGGER)
    patch_magpie_url(settings)

    # avoid cornice conflicting with magpie exception views
    settings["handle_exceptions"] = False

    config = get_auth_config(settings)
    set_cache_regions_from_settings(settings)

    # Don't use scan otherwise modules like 'magpie.adapter' are
    # automatically found and cause import errors on missing packages
    config.include("magpie")
    # config.scan("magpie")

    print_log("Starting Magpie app...", LOGGER)
    wsgi_app = config.make_wsgi_app()
    return wsgi_app