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