def get_group_resource_permissions_response(group, resource, db_session): # type: (models.Group, models.Resource, Session) -> HTTPException """ Get validated response with group resource permissions as content. :returns: valid HTTP response on successful operations. :raises HTTPException: error HTTP response of corresponding situation. """ def get_grp_res_perms(grp, res, db): if res.owner_group_id == grp.id: # FIXME: no 'magpie.models.Resource.permissions' - ok for now because no owner handling... return models.RESOURCE_TYPE_DICT[res.type].permissions perms = db.query(models.GroupResourcePermission) \ .filter(models.GroupResourcePermission.resource_id == res.resource_id) \ .filter(models.GroupResourcePermission.group_id == grp.id) return [PermissionSet(p, typ=PermissionType.APPLIED) for p in perms] group_permissions = ax.evaluate_call( lambda: format_permissions( get_grp_res_perms(group, resource, db_session), PermissionType. APPLIED), http_error=HTTPInternalServerError, msg_on_fail=s. GroupResourcePermissions_InternalServerErrorResponseSchema.description, content={ "group": repr(group), "resource": repr(resource) }) return ax.valid_http( http_success=HTTPOk, detail=s.GroupResourcePermissions_GET_OkResponseSchema.description, content=group_permissions)
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", "inherited"])) resolve_groups_perms = asbool( ar.get_query_param(request, ["resolve", "resolved"])) perm_type = PermissionType.INHERITED if inherit_groups_perms else PermissionType.DIRECT perms = ax.evaluate_call( lambda: uu.get_user_service_permissions( service=service, user=user, request=request, inherit_groups_permissions=inherit_groups_perms, resolve_groups_permissions=resolve_groups_perms), fallback=lambda: request.db.rollback(), http_error=HTTPNotFound, msg_on_fail=s.UserServicePermissions_GET_NotFoundResponseSchema. description, content={ "service_name": str(service.resource_name), "user_name": str(user.user_name) }) return ax.valid_http( http_success=HTTPOk, content=format_permissions(perms, perm_type), detail=s.UserServicePermissions_GET_OkResponseSchema.description)
def fmt_svc(): svc_info = { "public_url": str(get_twitcher_protected_service_url(service.resource_name)), "service_name": str(service.resource_name), "service_type": str(service.type), "service_sync_type": str(service.sync_type) if service.sync_type is not None else service.sync_type, "resource_id": service.resource_id, } if show_private_url: svc_info["service_url"] = str(service.url) if basic_info: return svc_info if show_configuration: svc_info["configuration"] = service.configuration perms = SERVICE_TYPE_DICT[ service.type].permissions if permissions is None else permissions svc_info.update(format_permissions(perms, permission_type)) if show_resources_allowed: svc_info["resource_types_allowed"] = sorted( SERVICE_TYPE_DICT[service.type].resource_type_names) svc_info["resource_child_allowed"] = SERVICE_TYPE_DICT[ service.type].child_resource_allowed return svc_info
def fmt_svc(svc, perms): svc_info = { u"public_url": str(get_twitcher_protected_service_url(svc.resource_name)), u"service_name": str(svc.resource_name), 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, } if perms is None: # user/group permission specify empty list perms = SERVICE_TYPE_DICT[svc.type].permissions svc_info[u"permission_names"] = format_permissions(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_type_names) svc_info[u"resource_child_allowed"] = SERVICE_TYPE_DICT[ svc.type].child_resource_allowed return svc_info
def get_resource_permissions_view(request): """ List all applicable permissions for a resource. """ resource = ar.get_resource_matchdict_checked(request, "resource_id") res_perm = ax.evaluate_call(lambda: ru.get_resource_permissions(resource, db_session=request.db), fallback=lambda: request.db.rollback(), httpError=HTTPBadRequest, msgOnFail=s.ResourcePermissions_GET_BadRequestResponseSchema.description, content={u"resource": rf.format_resource(resource, basic_info=True)}) return ax.valid_http(httpSuccess=HTTPOk, detail=s.ResourcePermissions_GET_OkResponseSchema.description, content={u"permission_names": format_permissions(res_perm)})
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: [p.value for p in SERVICE_TYPE_DICT[service.type].permissions], fallback=request.db.rollback(), http_error=HTTPBadRequest, content=svc_content, msg_on_fail=s.ServicePermissions_GET_BadRequestResponseSchema.description) return ax.valid_http(http_success=HTTPOk, detail=s.ServicePermissions_GET_OkResponseSchema.description, content=format_permissions(svc_perms, PermissionType.ALLOWED))
def format_service_resource_type(resource_class, service_class): # type: (Type[Resource], Type[ServiceInterface]) -> JSON svc_res_info = { "resource_type": resource_class.resource_type_name, "resource_child_allowed": resource_class.child_resource_allowed, } svc_res_perm = service_class.get_resource_permissions( resource_class.resource_type_name) svc_res_info.update( format_permissions(svc_res_perm, PermissionType.ALLOWED)) return svc_res_info
def format_service_resource_type(resource_class, service_class): # type: (Type[Resource], Type[ServiceInterface]) -> JSON return { u"resource_type": resource_class.resource_type_name, u"resource_child_allowed": resource_class.child_resource_allowed, u"permission_names": format_permissions( service_class.get_resource_permissions( resource_class.resource_type_name)), }
def get_usr_res_perms(): if resource.owner_user_id == user.id: res_perm_list = models.RESOURCE_TYPE_DICT[ resource.type].permissions else: if effective_permissions: svc = get_resource_root_service(resource, request) res_perm_list = svc.effective_permissions(resource, user) else: res_perm_list = ResourceService.perms_for_user( resource, user, db_session=db_session) if not inherit_groups_permissions: res_perm_list = filter_user_permission(res_perm_list, user) return format_permissions(res_perm_list)
def get_group_service_permissions_response(group, service, db_session): # type: (models.Group, models.Service, Session) -> HTTPException """ Get validated response of found group service permissions. :returns: valid HTTP response on successful operations. :raises HTTPException: error HTTP response of corresponding situation. """ svc_perms_found = ax.evaluate_call( lambda: format_permissions(get_group_service_permissions(group, service, db_session)), httpError=HTTPInternalServerError, msgOnFail=s.GroupServicePermissions_GET_InternalServerErrorResponseSchema.description, content={u"group": format_group(group, basic_info=True), u"service": format_service(service)}) return ax.valid_http(httpSuccess=HTTPOk, detail=s.GroupServicePermissions_GET_OkResponseSchema.description, content={u"permission_names": svc_perms_found})
def fmt_res(res, perms, info): result = { u"resource_name": str(res.resource_name), u"resource_display_name": str(res.resource_display_name or res.resource_name), u"resource_type": str(res.resource_type), u"resource_id": res.resource_id } if not info: result.update({ u"parent_id": res.parent_id, u"root_service_id": res.root_service_id, u"children": {}, u"permission_names": list() if perms is None else format_permissions(perms) }) return result
def fmt_res(): result = { "resource_name": str(resource.resource_name), "resource_display_name": str(resource.resource_display_name or resource.resource_name), "resource_type": str(resource.resource_type), "resource_id": resource.resource_id } if not basic_info: result.update({ "parent_id": resource.parent_id, "root_service_id": resource.root_service_id, "children": {}, }) result.update(format_permissions(permissions, permission_type)) return result
def get_group_resource_permissions_response(group, resource, db_session): # type: (models.Group, models.Resource, Session) -> HTTPException """ Get validated response with group resource permissions as content. :returns: valid HTTP response on successful operations. :raises HTTPException: error HTTP response of corresponding situation. """ def get_grp_res_perms(grp, res, db): if res.owner_group_id == grp.id: return models.RESOURCE_TYPE_DICT[res.type].permissions perms = db.query(models.GroupResourcePermission) \ .filter(models.GroupResourcePermission.resource_id == res.resource_id) \ .filter(models.GroupResourcePermission.group_id == grp.id) return [convert_permission(p) for p in perms] group_perm_names = ax.evaluate_call( lambda: format_permissions(get_grp_res_perms(group, resource, db_session)), httpError=HTTPInternalServerError, msgOnFail=s.GroupResourcePermissions_InternalServerErrorResponseSchema.description, content={u"group": repr(group), u"resource": repr(resource)}) return ax.valid_http(httpSuccess=HTTPOk, detail=s.GroupResourcePermissions_GET_OkResponseSchema.description, content={u"permission_names": group_perm_names})
def get_usr_res_perms(): perm_type = None perm_unique = True res_perm_list = [] if resource.owner_user_id == user.id: # FIXME: no 'magpie.models.Resource.permissions' - ok for now because no owner handling... perm_type = PermissionType.OWNED res_perm_list = models.RESOURCE_TYPE_DICT[resource.type].permissions else: if effective_permissions: svc = ru.get_resource_root_service_impl(resource, request) res_perm_list = svc.effective_permissions(user, resource) perm_type = PermissionType.EFFECTIVE else: if inherit_groups_permissions or resolve_groups_permissions: perm_unique = resolve_groups_permissions # allow duplicates from distinct groups if not resolved res_perm_list = ResourceService.perms_for_user(resource, user, db_session=db_session) res_perm_list = regroup_permissions_by_resource(res_perm_list, resolve=resolve_groups_permissions) res_perm_list = res_perm_list.get(resource.resource_id, []) perm_type = PermissionType.INHERITED else: res_perm_list = ResourceService.direct_perms_for_user(resource, user, db_session=db_session) perm_type = PermissionType.DIRECT return format_permissions(res_perm_list, perm_type, force_unique=perm_unique)
def test_format_permissions_allowed(self): """ Validate that formats are also respected, but with additional auto-expansion of all *modifier* combinations on permission names when requesting :attr:`PermissionType.ALLOWED` permissions. .. seealso:: :meth:`test_format_permissions_applied` """ utils.warn_version(__meta__.__version__, "permission format validation", "3.0", skip=True) # add duplicates with extra modifiers only to test removal # provide in random order to validate proper sorting # use multiple permission implementation to validate they are still handled test_perms = [ PermissionSet(Permission.READ, Access.DENY, Scope.RECURSIVE), PermissionSet(Permission.READ, Access.DENY, Scope.MATCH), PermissionSet(Permission.READ, Access.ALLOW, Scope.RECURSIVE), PermissionSet(Permission.READ, Access.ALLOW, Scope.MATCH), Permission.READ, "write-match", # old implicit format Permission.WRITE, ] format_perms = format_permissions(test_perms, PermissionType.ALLOWED) expect_names = [ Permission.READ.value + "-" + Scope.MATCH.value, str(PermissionSet(Permission.READ, Access.ALLOW, Scope.MATCH)), Permission.READ.value, str(PermissionSet(Permission.READ, Access.ALLOW, Scope.RECURSIVE)), # no implicit name for denied str(PermissionSet(Permission.READ, Access.DENY, Scope.MATCH)), str(PermissionSet(Permission.READ, Access.DENY, Scope.RECURSIVE)), Permission.WRITE.value + "-" + Scope.MATCH.value, str(PermissionSet(Permission.WRITE, Access.ALLOW, Scope.MATCH)), Permission.WRITE.value, str(PermissionSet(Permission.WRITE, Access.ALLOW, Scope.RECURSIVE)), # no implicit name for denied str(PermissionSet(Permission.WRITE, Access.DENY, Scope.MATCH)), str(PermissionSet(Permission.WRITE, Access.DENY, Scope.RECURSIVE)), ] expect_perms = [ PermissionSet(Permission.READ, Access.ALLOW, Scope.MATCH, PermissionType.ALLOWED).json(), PermissionSet(Permission.READ, Access.ALLOW, Scope.RECURSIVE, PermissionType.ALLOWED).json(), PermissionSet(Permission.READ, Access.DENY, Scope.MATCH, PermissionType.ALLOWED).json(), PermissionSet(Permission.READ, Access.DENY, Scope.RECURSIVE, PermissionType.ALLOWED).json(), PermissionSet(Permission.WRITE, Access.ALLOW, Scope.MATCH, PermissionType.ALLOWED).json(), PermissionSet(Permission.WRITE, Access.ALLOW, Scope.RECURSIVE, PermissionType.ALLOWED).json(), PermissionSet(Permission.WRITE, Access.DENY, Scope.MATCH, PermissionType.ALLOWED).json(), PermissionSet(Permission.WRITE, Access.DENY, Scope.RECURSIVE, PermissionType.ALLOWED).json(), ] utils.check_all_equal(format_perms["permission_names"], expect_names, any_order=False) utils.check_all_equal(format_perms["permissions"], expect_perms, any_order=False)
def test_format_permissions_applied(self): """ Validate that provided permission sets are formatted as intended, with both implicit and explicit variants, and with both name strings and detailed JSON objects. """ utils.warn_version(__meta__.__version__, "permission format validation", "3.0", skip=True) usr_perm = models.UserPermission() usr_perm.perm_name = Permission.GET_FEATURE.value grp_perm = models.GroupPermission() grp_perm.perm_name = "write-match" # using string for backward compatibility dup_perm = Permission.READ.value # only one should remain in result dup_usr_perm = models.UserPermission() dup_usr_perm.perm_name = dup_perm # also only one remains although different type only_perm = Permission.GET_CAPABILITIES deny_match_perm = PermissionSet(Permission.GET_LEGEND_GRAPHIC, Access.DENY, Scope.MATCH) deny_str_perm = Permission.GET_MAP.value + "-" + Access.DENY.value deny_recur_perm = PermissionSet(Permission.GET_METADATA, Access.DENY, Scope.RECURSIVE) # purposely use a random order to test sorting simultaneously to duplicate removal any_perms = [ deny_match_perm, dup_perm, only_perm, usr_perm, dup_usr_perm, grp_perm, deny_str_perm, deny_recur_perm, deny_recur_perm ] perm_type = PermissionType.DIRECT # anything else than 'allowed' to only get 'applied' permissions format_perms = format_permissions(any_perms, perm_type) expect_names = [ # both implicit/explicit variants added for backward compatibility and new format for each applicable case only_perm.value, str(PermissionSet(only_perm, Access.ALLOW, Scope.RECURSIVE)), usr_perm.perm_name, str(PermissionSet(usr_perm.perm_name)), # deny only have explicit representation str(deny_match_perm), str(PermissionSet(deny_str_perm, Access.DENY, Scope.RECURSIVE)), str( PermissionSet(deny_recur_perm.name, deny_recur_perm.access, Scope.RECURSIVE)), dup_perm, # only one, other not present str(PermissionSet(dup_perm, Access.ALLOW, Scope.RECURSIVE)), grp_perm.perm_name, str(PermissionSet(grp_perm.perm_name, Access.ALLOW, Scope.MATCH)), ] expect_perms = [ PermissionSet(Permission.GET_CAPABILITIES, Access.ALLOW, Scope.RECURSIVE, perm_type).json(), PermissionSet(Permission.GET_FEATURE, Access.ALLOW, Scope.RECURSIVE, perm_type).json(), PermissionSet(Permission.GET_LEGEND_GRAPHIC, Access.DENY, Scope.MATCH, perm_type).json(), PermissionSet(Permission.GET_MAP, Access.DENY, Scope.RECURSIVE, perm_type).json(), PermissionSet(Permission.GET_METADATA, Access.DENY, Scope.RECURSIVE, perm_type).json(), PermissionSet(Permission.READ, Access.ALLOW, Scope.RECURSIVE, perm_type).json(), PermissionSet(Permission.WRITE, Access.ALLOW, Scope.MATCH, perm_type).json(), ] utils.check_all_equal(format_perms["permission_names"], expect_names, any_order=False) utils.check_all_equal(format_perms["permissions"], expect_perms, any_order=False)