当前位置: 首页 > 面试题库 >

存储用户帐户权限的最佳方法?

东郭鸿福
2023-03-14
问题内容

我的权限记录绑定到我的应用程序中的每个帐户。每个帐户可以具有一个或多个基于帐户类型的权限记录。这是示例:

<cfquery name="qryUserPerm" datasource="#Application.dsn#">
    SELECT AccessType, AccessLevel, State, City, Building
    FROM Permissions
    WHERE AccountID = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(session.AccountID)#">
</cfquery>

上面的查询将为其中一个帐户产生这样的数据:

RecID   AccountID   AccessType  AccessLevel State     City    Building
70      285A637D82B9    F            B        NY    New York    8010
71      285A637D82B9    F            B        NY    New York    5412
73      285A637D82B9    F            B        NY    New York    6103
74      285A637D82B9    F            B        NY    New York    3106

正如您在上方看到的,此帐户已分配了4条记录。访问类型可以是“完全”F或“仅查看” V。访问级别可以是州“ S”,城市“ C”或建筑物“
B”。用户一次只能分配一个访问级别,因此,例如,不存在用户可以分配城市和州级别的情况。我的问题是,针对特定访问级别从查询组织数据的最佳方法是什么?在这种情况下,我必须合并列表或数组中的4条记录。州级别只能分配一个权限记录,城市和建筑物可以具有多个记录。这是我所拥有的示例:

<cfset local.permissionType = "">
<cfset local.permissionLevel = "">
<cfset local.permissionList = "">

<cfloop query="qryUserPerm">
    <cfif qryUserPerm.AccessLevel EQ "S">
         <cfset local.permissionType = qryUserPerm.AccessType>
         <cfset local.permissionLevel = qryUserPerm.AccessLevel>
         <cfset local.permissionList = listAppend(permissionList, "", ",")>
    <cfelseif qryUserPerm.AccessLevel EQ "C">
         <cfset local.permissionType = qryUserPerm.AccessType>
         <cfset local.permissionLevel = qryUserPerm.AccessLevel>
         <cfset local.permissionList = listAppend(permissionList, qryUserPerm.City, ",")>
    <cfelseif qryUserPerm.AccessLevel EQ "B">
         <cfset local.permissionType = qryUserPerm.AccessType>
         <cfset local.permissionLevel = qryUserPerm.AccessLevel>
         <cfset local.permissionList = listAppend(permissionList, qryUserPerm.Building, ",")>
    <cfelse>
         <cfset local.permissionType = "">
         <cfset local.permissionLevel = "">
         <cfset local.permissionList = listAppend(permissionList, "", ",")>
    </cfif>
</cfloop>

这似乎是多余的,以保持permissionTypepermissionLevel环路内,但我不知道现在更好的办法来避免这种情况。同样,如果我必须比较权限列表,这会使过程非常困难。我必须运行相同的过程并构建列表,以便与Session.premissionList当前登录的用户更改其权限的情况进行比较。有什么办法可以将这些记录与SQL合并?还是这种方法是更好的选择?


问题答案:

这可以在SQL本身中完成,这可能比处理代码中的数据更有效。

随着数据的一个问题是StateCityBuilding列必须逆转置,然后被变成了逗号分隔的列表。

由于使用的是SQL 2008,因此可以访问所需的功能。

查询是:http :
//sqlfiddle.com/#!18/0f4f7/1

; WITH cte AS (
  SELECT
      AccountID, AccessType, AccessLevel
      , CASE AccessLevel
          WHEN 'S' THEN State
          WHEN 'C' THEN City
          WHEN 'B' THEN Building
        END AS Permissions
  FROM Permissions
  WHERE AccountID = 
    <cfqueryparam cfsqltype="cf_sql_integer" value="#session.AccountID#"> 
    /* Dynamic variable here */
)
SELECT DISTINCT AccountID, AccessType, AccessLevel
  , CASE 
      WHEN AccessLevel = 'S' THEN Permissions 
      ELSE LEFT(ca.pl, COALESCE(LEN(ca.pl),0)-1)
    END AS PermissionList
FROM cte
CROSS APPLY (
  SELECT p.Permissions + ', '
  FROM cte p
  WHERE p.AccountID = cte.AccountID
    AND p.AccessType = cte.AccessType
    AND p.AccessLevel = cte.AccessLevel
  FOR XML PATH('')
) ca (pl)     ;

我先从CTE开始,以建立Permissions基于的“不可透视的”列表AccessLevel。如果可以将其放在SQL视图中,则可以在WHERE此处省略该语句,并在调用视图时调用它。如果可以将View放入数据库,则将是我的首选。

之后,我有CTE,我只是选择了基列(AccountIDAccessTypeAccessLevel,然后我CROSS APPLY一个逗号分隔的列表Permissions。我用FOR XML PATH('')构建一个逗号分隔的列表。

如果能够将其转换为视图,那将是一个简单的过程

<cfquery name="qryUserPerm" datasource="#Application.dsn#">
    SELECT AccessType, AccessLevel, PermissionList
    FROM myPermissionsView
    WHERE AccountID = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(session.AccountID)#">
</cfquery>

如果不是,则必须尝试在cfquery标记内运行上述完整查询。

这应该给您返回一个数据集,例如:

| AccessType | AccessLevel |         PermissionList |
|------------|-------------|------------------------|
|          F |           B | 8010, 5412, 6103, 3106 |

您只有一个结果可以使用,而不必循环。

================================================== ====================

如果您想采用代码内方法,我仍然建议您尝试使用它cfscript来构建结构。但是,如果您可以有多个AccessLevel,则结果可能与您认为的不一样。您必须仔细检查您的数据。

  local.permissionType = q2.AccessType ;
  local.permissionLevel = q2.AccessLevel ;

  switch( q2.AccessLevel ) {
    case "S" :  local.permissionList = q2.State ;
      break ;
    case "C" :  local.permissionList = ListRemoveDuplicates(ValueList(q2.City)) ;
      break ;
    case "B" :  local.permissionList = ListRemoveDuplicates(ValueList(q2.Building)) ;
      break ;
  }

https://trycf.com/gist/e811ec86f0d5a52fd9ce703f897cb5aa/acf2016?theme=monokai



 类似资料:
  • 我正在尝试使用django-storages为带有服务帐户json文件的google云存储桶授予权限。但是,只有当我向所有具有对象视图权限的用户授予访问权限时,才能访问桶中的项目。我如何限制桶的公共访问。

  • 问题内容: 我正在努力为正在创建的应用设置登录系统。 我可以为用户登录或注销设置cookie。我认为,如果用户已登录,测试每个视图都不是一个非常优雅的解决方案,并且我担心这里和那里的页面可能会掉入裂缝(这是一个相当大的应用程序)。 我在想最好的方法是以某种方式拦截路由更改并检查用户是否已登录,否则将其发送到登录/创建用户页面。我发现了一些方法,但是似乎没有正式记录。有没有人在现实世界中使用过这种方

  • 问题内容: 我的应用程序中有一个添加用户选项。我想将用户密码以哈希格式存储在数据库中。密码以纯文本格式存储在框架随附的示例代码中。经过一番搜索,我发现在play2中实现了一个Crypto.encryptAES()函数,可用于保护密码。 我的问题是使用它的最佳地点是什么?以及如何使用它来创建最可维护的代码? 问题答案: 我个人将在模型中执行此操作。我的领域有吸气剂,所以在方法中: 该只是为多目的散列

  • 我正试图从Python脚本中获得一个服务帐户来在Google Cloud Storage中创建Blob,但我遇到了凭据问题。 如果我将环境变量设置为 然后重新运行脚本。但是,我希望它在创建帐户的脚本的一个实例中运行,并继续在桶中创建必要的文件。如果我知道我的json凭据文件在哪里,我如何访问my_bucket。

  • 产出: 因此上传的文件自动具有两个权限:1。服务帐户是“所有者”2。我的主要帐户是“作家” 的确,我可以在web界面上看到文件,编辑文件,删除文件等,但是,由于服务帐户是所有者,文件是在服务帐户存储配额中计算的,所以这并不能解决我的问题,即我的备份应用程序仍然不能使用超过15GB的文件。 顺便说一句,在谷歌帮助转移文件所有权中,他们说“如果你是谷歌应用程序的用户,你不能将所有权转移给你域外的其他人

  • 我测试了在新的Azure门户中创建经典存储帐户(manage.windowsazure.com)和“新”存储帐户。将它们设置为类似的,并运行相同的代码来创建和配置队列。但指标仅显示门户中的经典存储帐户(能够在新门户中看到这两个帐户) 我已经像这样设置了ServiceProperties,并且可以在获取服务属性或查看Azure门户时成功地看到保存的这些更改。 当我使用Microsoft Azure