2018/04/24

SampleCMS 帳號與權限系統元件說明:客製化權限判斷

接續上一篇 元件提供的功能與使用方式 結尾提到的,(帳號設定頁)"使用的方法 CanEditThisPage() 之所以不用傳入擁有者資訊是因為管理頁共用元件實作了介面 ICustomEmployeeAuthorizationResult,透過實作的介面方法 InitialAuthorizationResult(bool isTopPageOfOperation, EmployeeAuthorizations authorizations) 將擁有者資訊交給了帳號與權限元件",本篇繼續說明介面 ICustomEmployeeAuthorizationResult 的作用以及需負責的工作。

帳號與權限元件透過介面 ICustomEmployeeAuthorizationResult 開放給外部元件自訂帳號授權結果,透過這個介面取得作業選項子項目的擁有者資訊做為權限判斷條件,或者是取回外部元件自訂的權限判斷結果取代原本的結果值。

下列為帳號與權限元件初始化授權結果的程式碼,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/// <summary>
/// 初始化最上層頁面授權結果
/// </summary>
public void InitialAuthorizationResultOfTopPage()
{
    InitialAuthorizationResult(true);
}
 
/// <summary>
/// 初始化下層頁面授權結果
/// </summary>
public void InitialAuthorizationResultOfSubPages()
{
    InitialAuthorizationResult(false);
}
 
/// <summary>
/// 初始化授權結果
/// </summary>
protected virtual void InitialAuthorizationResult(bool isTopPageOfOperation)
{
    this.isTopPageOfOperation = isTopPageOfOperation;
 
    //取得指定作業代碼的後端身分可使用權限
    IDataAccessCommand cmd = DataAccessCommandFactory.GetDataAccessCommand(DBs.MainDB);
    spEmployeeRoleOperationsDesc_GetDataOfOp cmdInfo = new spEmployeeRoleOperationsDesc_GetDataOfOp()
    {
        OpId = opIdOfPage,
        RoleName = roleName
    };
 
    DataSet dsRoleOp = cmd.ExecuteDataset(cmdInfo);
 
    //從資料集載入身分的授權設定
    LoadRoleAuthorizationsFrom(dsRoleOp);
 
    if (custEmpAuthResult != null)
    {
        //自訂帳號授權結果
        EmployeeAuthorizationsWithOwnerInfoOfDataExamined authAndOwner = custEmpAuthResult.InitialAuthorizationResult(isTopPageOfOperation, authorizations);
        ownerAccountOfDataExamined = authAndOwner.OwnerAccountOfDataExamined;
        ownerDeptIdOfDataExamined = authAndOwner.OwnerDeptIdOfDataExamined;
        this.authorizations = authAndOwner;
 
        if (authAndOwner.IsTopPageOfOperationChanged)
        {
            this.isTopPageOfOperation = authAndOwner.IsTopPageOfOperation;
        }
 
        return;
    }
}

Line 1~15: InitialAuthorizationResultOfTopPage() 與 InitialAuthorizationResultOfSubPages() 的差別只在 this.isTopPageOfOperation 是 true 或 false。

Line 24~35: 依照目前的作業選項代碼 opId 和登入者的身分 roleName 從資料庫取得授權設定並且暫存。

Line 37~51: 本篇重點,客製化權限判斷。

Line 40: 將暫存的授權設定提供給外部元件,取回自訂帳號授權結果。

Line 41, 42: 暫存外部元件提供的擁有者資訊。

Line 43: 使用外部元件提供的授權設定,取代暫存的授權設定。
(類別 EmployeeAuthorizationsWithOwnerInfoOfDataExamined 繼承自 EmployeeAuthorizations)

Line 45~48: 如果外部元件有更改 isTopPageOfOperation 值,改用外部元件指定的值。
(例如:帳號與權限元件原本被指定以「作業選項」的授權值做權限判斷,但是外部元件認為要改用「作業選項的子項目」的授權值做權限判斷)

上述 Line 41, 42 取得的擁有者資訊,會被用在 CanEditThisPage() ,以下為 CanEditThisPage() 的程式碼,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/// <summary>
/// 檢查是否可編輯此頁面
/// </summary>
public virtual bool CanEditThisPage()
{
    return CanEditThisPage(isTopPageOfOperation, ownerAccountOfDataExamined, ownerDeptIdOfDataExamined);
}
 
/// <summary>
/// 檢查是否可編輯此頁面
/// </summary>
public virtual bool CanEditThisPage(bool useTopRule, string ownerAccount, int ownerDeptId)
{
    bool result = false;
 
    if (useTopRule)
    {
        result = authorizations.CanEdit;
    }
    else
    {
        if (authorizations.CanEditSubItemOfOthers)
        {
            result = true;
        }
        else if (authorizations.CanEditSubItemOfCrew
            && deptId > 0
            && deptId == ownerDeptId)
        {
            result = true;
        }
        else if (authorizations.CanEditSubItemOfSelf
            && empAccount != ""
            && empAccount == ownerAccount)
        {
            result = true;
        }
    }
 
    return result;
}

Line 6: 使用暫存的擁有者資訊做為條件做權限判斷。

以上為介面 ICustomEmployeeAuthorizationResult 在帳號與權限元件之中的作用。


接著說明實作介面 ICustomEmployeeAuthorizationResult 的外部元件需負責的工作,
以「帳號管理」專屬的管理頁共用元件 AccountCommonOfBackend 為例,下列為實作介面的程式碼,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
[Description("後台帳號管理頁的共用元件")]
public class AccountCommonOfBackend : BackendPageCommon, ICustomEmployeeAuthorizationResult
{
    // ...略...
 
    #region ICustomEmployeeAuthorizationResult
 
    public EmployeeAuthorizationsWithOwnerInfoOfDataExamined InitialAuthorizationResult(bool isTopPageOfOperation, EmployeeAuthorizations authorizations)
    {
        EmployeeAuthorizationsWithOwnerInfoOfDataExamined authAndOwner = new EmployeeAuthorizationsWithOwnerInfoOfDataExamined(authorizations);
 
        if (!isTopPageOfOperation)
        {
            // get owner info for config-form
            IDataAccessCommand cmd = DataAccessCommandFactory.GetDataAccessCommand(DBs.MainDB);
            spEmployee_GetAccountOfId cmdInfo = new spEmployee_GetAccountOfId()
            {
                EmpId = qsEmpId
            };
 
            string errCode = "-1";
            string empAccount = cmd.ExecuteScalar<string>(cmdInfo, errCode);
            string dbErrMsg = cmd.GetErrMsg();
 
            DataSet ds = null;
            if (empAccount != errCode)
            {
                accountOfData = empAccount;
                spEmployee_GetData cmdInfoGetData = new spEmployee_GetData()
                {
                    EmpAccount = empAccount
                };
 
                ds = cmd.ExecuteDataset(cmdInfoGetData);
                dbErrMsg = cmd.GetErrMsg();
 
                if (ds != null && ds.Tables[0].Rows.Count > 0)
                {
                    DataRow drFirst = ds.Tables[0].Rows[0];
 
                    authAndOwner.OwnerAccountOfDataExamined = drFirst.ToSafeStr("OwnerAccount");
                    authAndOwner.OwnerDeptIdOfDataExamined = Convert.ToInt32(drFirst["OwnerDeptId"]);
                }
            }
        }
 
        return authAndOwner;
    }
 
    #endregion
}

Line 10: 預設要回傳的授權結果 EmployeeAuthorizationsWithOwnerInfoOfDataExamined 物件,預設值同傳入的 EmployeeAuthorizations 物件。

Line 12: 若使用的是「作業選項的子項目」的規則,才需要去資料庫取得擁有者資訊。

Line 15~23: 使用網址參數 EmpId 到資料庫取得對應的帳號 EmpAccount。

Line 28: 暫存取回的 EmpAccount,預留給其他功能。

Line 29~43: 使用 EmpAccount 到資料庫取得帳號的擁有者資訊,並且放入要回傳的結果物件裡。

Line 47: 回傳結果。

總結外部元件需負責的工作有兩項,
  1. 回傳的授權結果 EmployeeAuthorizationsWithOwnerInfoOfDataExamined 物件不管外部元件有無更改授權設定值,一定要有回傳值。若沒有更改授權設定值,要從傳入的 EmployeeAuthorizations 物件複製相同的值再回傳。
  2. 負責取得展示層網頁程式指定的「作業選項的子項目」資料擁有者資訊。




沒有留言:

張貼留言