---
# System prepended metadata

title: NotificationCenter 通知中心 & 角色權限

---

NotificationCenter 通知中心 & 角色權限 
===

### RBAC(基於角色的權限訪問控制)

![](https://i.imgur.com/rl5qHSQ.png)



https://github.com/casbin/casbin

1. 支持自定義請求的格式，默認的請求格式為{subject, object, action}。
2. 具有訪問控制模型model和策略policy兩個核心概念。
3. 支持RBAC中的多層角色繼承，不止主體可以有角色，資源也可以具有角色。
4. 支持內置的超級用戶例如：root或administrator。超級用戶可以執行任何操作而無需顯式的權限聲明。
5. 支持多種內置的操作符，如keyMatch，方便對路徑式的資源進行管理，如/foo/bar可以映射到/foo*

casbin使用配置文件來設置訪問控制模型

model.conf: 訪問控制模型

policy.csv: 具體的用戶權限配置

sub := "alice" // the user that wants to access a resource.
obj := "data1" // the resource that is going to be accessed.
act := "write" // the operation that the user performs on the resource.

[request_definition]：定義請求時需要以此作為開頭。
r：變數名稱，因為定義了 [request_definition]，該變數就代表了請求。
sub：代表主題，通常主題可以是使用者、角色等。
obj：代表對象，通常對象可以是資源等。
act：代表操作，通常操作會是針對資源所執行的動作名稱。


### NotificationCenter 通知中心


## 需要具備功能
### 依照消息等級，通知到操盤前端
- 通知等級:
    - 警報 Alert
    - 警告 Warning
    - 訊息 Info(Message)

- 通知維度
    - 每個客戶端(Broadcast)
    - 登入的操盤手
    - 每位操盤手的權限高低
    - VIP操盤手
    
- 通知方法:
    - 客戶端彈窗訊息
    - 客戶端畫面右上角小鈴鐺
    - 客戶端跑馬燈
    - Slack群組(內部管理高層)
    - Slack群組(開發人員)
- 用戶ID(userID)與會話ID(sessionID)關聯
    - 當WebSocket建立連接時，將userID與sessionID進行關聯
    - 當WebSocket關閉連接時，刪除userID與sessionID的關聯
    - 當WebSocket建立連接時，前端帶入已登入的JWT Token, WebSocket Server透過JWT Token得到userID, 與sessionID做映射(之後透過userID即可發送使用者維度的訊息)
    

```
userID := getUserIdFromRequest(r)
sessionId2UserIdMap[sessionID] = userID
userId2SessionIdMap[userID] = sessionID
``` 

## Input Function
可以給源頭模組呼叫的function

```
賽事相關

func NotificationMsgMatchEvent(roleList[], level,msg ){} 訊息彈窗 EX: Alert, 紅牌
func NotificationBellMatchEvent(level,msg ){} 小鈴鐺
func NotificationTicker(level,msg ){} 跑馬燈 - admin

內部訊息
func NotificationSlackAdmin(level,msg ){} slack admin group
func NotificationSlackDev(level,msg ){} slack dev group



```


- 通知資料表:

```
// 小鈴鐺
type NotificationCenter struct {
     gorm.Model  `json:"-"`
     UID         uint   `gorm:"index" json:"-"` //  使用者ID
     Msg         string `gorm:"type:varchar(256)" json:"msg"`
     IsRead      bool   `gorm:"default:false" json:"isRead"`
     Level       string `gorm:"type:varchar(256)" json:"level"`
     ActionType  string `gorm:"type:varchar(32)" json:"actionType"`
     ActionValue string `gorm:"type:varchar(64)" json:"actionValue"`
 }
 

// 跑馬燈
type Ticker struct {
    gorm.Model
    Content   string     `gorm:"column:content" json:"content,omitempty"`
    Language  string     `gorm:"column:language"`
    StartTime *time.Time `gorm:"column:start_time"`
    EndTime   *time.Time `gorm:"column:end_time"`
 }


```

高權限者調賠，低權限者不能再修改
or
此操盤手只能調控特定賽事


- 使用者角色權限資料表:


登入需要與RTI做SSO
登入需要2FA

```
// 使用者
CREATE TABLE `user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `username` varchar(20)  NOT NULL COMMENT '帳號',
  `password` varchar(20)  NOT NULL COMMENT '密碼',
  `role_id` int unsigned NOT NULL COMMENT '角色ID',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='使用者登入資訊';

// 角色
CREATE TABLE `role` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `role_name` varchar(20)  NOT NULL COMMENT '角色名稱',
  `role_desc` varchar(20)  NOT NULL COMMENT '角色描述',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色資訊';

// 權限
CREATE TABLE `permission` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `permission` varchar(20)  NOT NULL COMMENT '權限名稱',
  `permission_desc` varchar(20)  NOT NULL COMMENT '權限描述',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='權限資訊';

// 角色權限對照表
CREATE TABLE `role_permission` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `role_id` bigint(20) unsigned NOT NULL  COMMENT '角色ID',
  `permission_id` bigint(20) unsigned NOT NULL COMMENT '權限ID',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  PRIMARY KEY (`id`),
  FOREIGN KEY(role_id) REFERENCES role(id),
  FOREIGN KEY(permission_id) REFERENCES permission(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色權限資訊';

// 使用者角色對照表
CREATE TABLE `user_role` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `user_id` bigint(20) unsigned NOT NULL  COMMENT '使用者ID',
  `role_id` bigint(20) unsigned NOT NULL COMMENT '角色ID',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  PRIMARY KEY (`id`),
  FOREIGN KEY(user_id) REFERENCES user(id),
  FOREIGN KEY(role_id) REFERENCES role(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='使用者角色資訊';
```




```
// 使用者
type User struct {
     gorm.Model
     Username string
     Password string
     RoleID int // role table ID
     AuthSecret       string          `gorm:"type:varchar(128)"`
}

// 角色 role_id
type Role struct {
     gorm.Model
     RoleName string      '角色' EX: SuperAdmin, normal user, 系統管理員
     RoleDescription text '角色權限說明'
}

// 權限 permission_id
type Permission struct {
     gorm.Model
     Permission string      '權限名稱' EX: 可調賠
     PermissionDescription text '權限說明' EX: 可以進行賠率調整
}


// 角色權限對照表
type RolePermission struct {
     gorm.Model
     RoleID bigint (forenkey) -> role.ID
     PermissionID bigint (forenkey) -> Permission.ID
}


// 使用者角色對照表
type UserRole struct {
     gorm.Model
     UserID bigint (forenkey) -> user.ID
     RoleID bigint (forenkey) -> role.ID
}

```