NotificationCenter 通知中心 & 角色權限
===
### RBAC(基於角色的權限訪問控制)

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
}
```