From a4b413dadb2f6a6469d8ec9b13d5d1d9b117128b Mon Sep 17 00:00:00 2001 From: ljw <84855512@qq.com> Date: Thu, 19 Sep 2024 10:44:49 +0800 Subject: [PATCH] add oauth loginlog & fix bugs --- README.md | 104 +++-- cmd/apimain.go | 5 +- conf/config.yaml | 9 +- config/gin.go | 1 + config/oauth.go | 13 + docs/admin/admin_docs.go | 636 ++++++++++++++++++++++++++++++ docs/admin/admin_swagger.json | 636 ++++++++++++++++++++++++++++++ docs/admin/admin_swagger.yaml | 386 ++++++++++++++++++ docs/admin_webclient.png | Bin 0 -> 44762 bytes docs/api/api_docs.go | 183 +++++++-- docs/api/api_swagger.json | 183 +++++++-- docs/api/api_swagger.yaml | 119 +++++- docs/pc_login.png | Bin 0 -> 22678 bytes docs/web_admin.png | Bin 45140 -> 28623 bytes docs/web_admin_user.png | Bin 0 -> 18507 bytes docs/web_user.png | Bin 27555 -> 0 bytes docs/webclient_conf.png | Bin 22999 -> 12996 bytes generate_run.go | 3 + go.mod | 12 +- http/controller/admin/login.go | 10 +- http/controller/admin/loginLog.go | 110 ++++++ http/controller/admin/oauth.go | 291 ++++++++++++++ http/controller/admin/user.go | 34 ++ http/controller/api/ab.go | 4 - http/controller/api/login.go | 48 ++- http/controller/api/ouath.go | 222 +++++++++++ http/controller/api/user.go | 10 +- http/controller/api/webClient.go | 2 +- http/controller/web/index.go | 8 +- http/http.go | 11 + http/middleware/rustauth.go | 7 + http/request/admin/login.go | 7 + http/request/admin/oauth.go | 34 ++ http/request/api/oauth.go | 14 + http/request/api/user.go | 16 +- http/response/admin/user.go | 7 +- http/response/api/user.go | 16 +- http/response/api/webClient.go | 30 +- http/router/admin.go | 32 ++ http/router/api.go | 12 +- model/loginLog.go | 23 ++ model/oauth.go | 22 ++ model/userThird.go | 12 + service/loginLog.go | 45 +++ service/oauth.go | 256 ++++++++++++ service/service.go | 2 + service/user.go | 74 +++- utils/tools.go | 12 + 48 files changed, 3477 insertions(+), 184 deletions(-) create mode 100644 config/oauth.go create mode 100644 docs/admin_webclient.png create mode 100644 docs/pc_login.png create mode 100644 docs/web_admin_user.png delete mode 100644 docs/web_user.png create mode 100644 generate_run.go create mode 100644 http/controller/admin/loginLog.go create mode 100644 http/controller/admin/oauth.go create mode 100644 http/controller/api/ouath.go create mode 100644 http/request/admin/oauth.go create mode 100644 http/request/api/oauth.go create mode 100644 model/loginLog.go create mode 100644 model/oauth.go create mode 100644 model/userThird.go create mode 100644 service/loginLog.go create mode 100644 service/oauth.go diff --git a/README.md b/README.md index 76a3057..18d2438 100644 --- a/README.md +++ b/README.md @@ -19,46 +19,66 @@ 2. server端必须指定key,不能用自带的生成的key,否则可能链接不上或者超时 ```bash -hbbs -r -k 123456789 -hbbr -k 123456789 +hbbs -r -k +hbbr -k +``` + +比如 + +```bash +hbbs -r -k abc1234567 +hbbr -k abc1234567 ``` ## 功能 -### **API 服务**: 基本实现了PC端基础的接口。 +### API 服务: 基本实现了PC端基础的接口。 + +#### 登录 + +- 添加了`github`登录,需要在后台配置好就可以用了,具体可看后台OAuth配置 +- 添加了web后台授权登录 + +![pc_login](docs/pc_login.png) + +#### 地址簿 ![pc_ab](docs/pc_ab.png) + +#### 群组,群组分为`共享组`和`普通组`,共享组中所有人都能看到小组成员的地址,普通组只有管理员能看到所有小组成员的地址 + ![pc_gr](docs/pc_gr.png) ### **Web UI**: 使用前后端分离,提供用户友好的管理界面,主要用来管理和展示。 ***前端代码在[rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)*** -***后台访问地址是`http://:21114/_admin/`初次安装管理员为用户名密码为`admin admin`,请即时更改密码*** +***后台访问地址是`http://:21114/_admin/`初次安装管理员为用户名密码为`admin` `admin`,请即时更改密码*** 1. 管理员界面 ![web_admin](docs/web_admin.png) 2. 普通用户界面 - ![web_user](docs/web_user.png) -3. 更改密码在右上角 - + ![web_user](docs/web_admin_user.png) +3. 右上角也可以更改密码 ![web_resetpwd](docs/web_resetpwd.png) 4. 分组可以自定义,方便管理,暂时支持两种类型: `共享组` 和 `普通组` - ![web_admin_gr](docs/web_admin_gr.png) +5. 可以直接打开webclient,方便使用 + ![web_webclient](docs/admin_webclient.png) -### **Web 客户端**: +### **Web Client**: 1. 如果已经登录了后台,web client将自动直接登录 2. 如果没登录后台,点击右上角登录即可,api server已经自动配置好了 -3. 登录后台后,会将地址簿自动保存到web client中,方便使用 ![webclient_conf](docs/webclient_conf.png) +3. 登录后,会自动同步ID服务器和KEY +4. 登录后,会将地址簿自动保存到web client中,方便使用 ### **自动化文档**: 使用 Swag 生成 API 文档,方便开发者理解和使用 API。 -1. 后台文档 /admin/swagger/index.html -2. PC端文档 /swagger/index.html +1. 后台文档 `/admin/swagger/index.html` +2. PC端文档 `/swagger/index.html` ![api_swag](docs/api_swag.png) ## 安装与运行 @@ -72,6 +92,7 @@ gin: api-addr: "0.0.0.0:21114" mode: "release" resources-path: 'resources' + trust-proxy: "" gorm: type: "sqlite" max-idle-conns: 10 @@ -88,36 +109,67 @@ rustdesk: key: "123456789" ``` -### 安装步骤 - -#### docker运行 - -1. 直接docker运行 - -```bash -docker run -d --name rustdesk-api -p 21114:21114 -v /data/rustdesk/api:/app/data lejianwen/rustdesk-api -``` - -- 环境变量,变量名前缀是RUSTDESK_API +* 环境变量,变量名前缀是RUSTDESK_API,环境变量如果存在将覆盖配置文件中的配置 | 变量名 | 说明 | 示例 | |:------------------------------------|:-------------------------------------|-----------------------------| +| -----GIN配置----- | ---------- | ---------- | +| RUSTDESK_API_GIN_TRUST_PROXY | 信任的代理IP列表,以`,`分割,默认信任所有 | 192.168.1.2,192.168.1.3 | | -----------GORM配置------------------ | ------------------------------------ | --------------------------- | | RUSTDESK_API_GORM_TYPE | 数据库类型sqlite或者mysql,默认sqlite | sqlite | | RUSTDESK_API_GORM_MAX_IDLE_CONNS | 数据库最大空闲连接数 | 10 | | RUSTDESK_API_GORM_MAX_OPEN_CONNS | 数据库最大打开连接数 | 100 | -| -----------MYSQL配置----------------- | --------数据库类型为sqlite时不用填------- | ---------- | +| -----MYSQL配置----- | -----数据库类型为sqlite时不用填----- | ---------- | | RUSTDESK_API_MYSQL_USERNAME | mysql用户名 | root | | RUSTDESK_API_MYSQL_PASSWORD | mysql密码 | 111111 | | RUSTDESK_API_MYSQL_ADDR | mysql地址 | 192.168.1.66:3306 | | RUSTDESK_API_MYSQL_DBNAME | mysql数据库名 | rustdesk | -| -----------RUSTDESK配置-------------- | ----------------------------------- | ---------- | +| -----RUSTDESK配置----- | --------------- | ---------- | | RUSTDESK_API_RUSTDESK_ID_SERVER | Rustdesk的id服务器地址 | 192.168.1.66:21116 | | RUSTDESK_API_RUSTDESK_RELAY_SERVER | Rustdesk的relay服务器地址 | 192.168.1.66:21117 | | RUSTDESK_API_RUSTDESK_API_SERVER | Rustdesk的api服务器地址 | http://192.168.1.66:21114 | | RUSTDESK_API_RUSTDESK_KEY | Rustdesk的key | 123456789 | -2. 使用`docker compose`,根据rustdesk提供的示例加上自己的rustdesk-api +### 安装步骤 + +#### docker运行 + +1. 直接docker运行,配置可以通过挂载配置文件`/app/conf/config.yaml`来修改,或者通过环境变量覆盖配置文件中的配置 + +```bash +docker run -d --name rustdesk-api -p 21114:21114 \ +-v /data/rustdesk/api:/app/data \ +-e RUSTDESK_API_RUSTDESK_ID_SERVER=192.168.1.66:21116 \ +-e RUSTDESK_API_RUSTDESK_RELAY_SERVER=192.168.1.66:21117 \ +-e RUSTDESK_API_RUSTDESK_API_SERVER=http://192.168.1.66:21114 \ +-e RUSTDESK_API_RUSTDESK_KEY=123456789 \ +lejianwen/rustdesk-api +``` + +2. 使用`docker compose` + +- 简单示例 + +```docker-compose +services: + rustdesk-api: + container_name: rustdesk-api + environment: + - RUSTDESK_API_RUSTDESK_ID_SERVER=192.168.1.66:21116 + - RUSTDESK_API_RUSTDESK_RELAY_SERVER=192.168.1.66:21117 + - RUSTDESK_API_RUSTDESK_API_SERVER=http://192.168.1.66:21114 + - RUSTDESK_API_RUSTDESK_KEY=123456789 + ports: + - 21114:21114 + image: lejianwen/rustdesk-api + volumes: + - /data/rustdesk/api:/app/data #将数据库挂载出来方便备份 + networks: + - rustdesk-net + restart: unless-stopped +``` + +- 根据rustdesk提供的示例加上自己的rustdesk-api ```docker-compose networks: diff --git a/cmd/apimain.go b/cmd/apimain.go index 21cc313..ec32dbb 100644 --- a/cmd/apimain.go +++ b/cmd/apimain.go @@ -157,7 +157,7 @@ func ApiInitValidator() { } func DatabaseAutoUpdate() { - version := 100 + version := 103 db := global.DB @@ -215,6 +215,9 @@ func Migrate(version uint) { &model.AddressBook{}, &model.Peer{}, &model.Group{}, + &model.UserThird{}, + &model.Oauth{}, + &model.LoginLog{}, ) if err != nil { fmt.Println("migrate err :=>", err) diff --git a/conf/config.yaml b/conf/config.yaml index 976bee4..021a331 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -2,6 +2,7 @@ gin: api-addr: "0.0.0.0:21114" mode: "release" #release,debug,test resources-path: 'resources' #对外静态文件目录 + trust-proxy: "" gorm: type: "sqlite" max-idle-conns: 10 @@ -16,14 +17,14 @@ rustdesk: relay-server: "192.168.1.66:21117" api-server: "http://192.168.1.66:21114" key: "123456789" -redis: - addr: "127.0.0.1:6379" - password: "" - db: 0 logger: path: "./runtime/log.txt" level: "error" #trace,debug,info,warn,error,fatal report-caller: true +redis: + addr: "127.0.0.1:6379" + password: "" + db: 0 cache: type: "file" file-dir: "./runtime/cache" diff --git a/config/gin.go b/config/gin.go index eac5788..1cc0ea9 100644 --- a/config/gin.go +++ b/config/gin.go @@ -5,4 +5,5 @@ type Gin struct { AdminAddr string `mapstructure:"admin-addr"` Mode string ResourcesPath string `mapstructure:"resources-path"` + TrustProxy string `mapstructure:"trust-proxy"` } diff --git a/config/oauth.go b/config/oauth.go new file mode 100644 index 0000000..81108aa --- /dev/null +++ b/config/oauth.go @@ -0,0 +1,13 @@ +package config + +type GithubOauth struct { + ClientId string `mapstructure:"client-id"` + ClientSecret string `mapstructure:"client-secret"` + RedirectUrl string `mapstructure:"redirect-url"` +} + +type GoogleOauth struct { + ClientId string `mapstructure:"client-id"` + ClientSecret string `mapstructure:"client-secret"` + RedirectUrl string `mapstructure:"redirect-url"` +} diff --git a/docs/admin/admin_docs.go b/docs/admin/admin_docs.go index 80db6ec..7d179ff 100644 --- a/docs/admin/admin_docs.go +++ b/docs/admin/admin_docs.go @@ -709,6 +709,172 @@ const docTemplateadmin = `{ } } }, + "/admin/loginLog/delete": { + "post": { + "security": [ + { + "token": [] + } + ], + "description": "登录日志删除", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "登录日志" + ], + "summary": "登录日志删除", + "parameters": [ + { + "description": "登录日志信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.LoginLog" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/loginLog/detail/{id}": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "登录日志详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "登录日志" + ], + "summary": "登录日志详情", + "parameters": [ + { + "type": "integer", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.LoginLog" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/loginLog/list": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "登录日志列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "登录日志" + ], + "summary": "登录日志列表", + "parameters": [ + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "页大小", + "name": "page_size", + "in": "query" + }, + { + "type": "integer", + "description": "用户ID", + "name": "user_id", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.LoginLogList" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, "/admin/logout": { "post": { "description": "登出", @@ -738,6 +904,280 @@ const docTemplateadmin = `{ } } }, + "/admin/oauth/create": { + "post": { + "security": [ + { + "token": [] + } + ], + "description": "创建Oauth", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Oauth" + ], + "summary": "创建Oauth", + "parameters": [ + { + "description": "Oauth信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.OauthForm" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.Oauth" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/oauth/delete": { + "post": { + "security": [ + { + "token": [] + } + ], + "description": "Oauth删除", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Oauth" + ], + "summary": "Oauth删除", + "parameters": [ + { + "description": "Oauth信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.OauthForm" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/oauth/detail/{id}": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "Oauth详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Oauth" + ], + "summary": "Oauth详情", + "parameters": [ + { + "type": "integer", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.Oauth" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/oauth/list": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "Oauth列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Oauth" + ], + "summary": "Oauth列表", + "parameters": [ + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "页大小", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.OauthList" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/oauth/update": { + "post": { + "security": [ + { + "token": [] + } + ], + "description": "Oauth编辑", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Oauth" + ], + "summary": "Oauth编辑", + "parameters": [ + { + "description": "Oauth信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.OauthForm" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.OauthList" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, "/admin/peer/create": { "post": { "security": [ @@ -1646,6 +2086,55 @@ const docTemplateadmin = `{ } } }, + "/admin/user/myOauth": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "我的授权", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户" + ], + "summary": "我的授权", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/admin.UserOauthItem" + } + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, "/admin/user/update": { "post": { "security": [ @@ -1760,6 +2249,9 @@ const docTemplateadmin = `{ "password": { "type": "string" }, + "platform": { + "type": "string" + }, "username": { "type": "string" } @@ -1877,6 +2369,35 @@ const docTemplateadmin = `{ } } }, + "admin.OauthForm": { + "type": "object", + "required": [ + "client_id", + "client_secret", + "op", + "redirect_url" + ], + "properties": { + "auto_register": { + "type": "boolean" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "op": { + "type": "string" + }, + "redirect_url": { + "type": "string" + } + } + }, "admin.PeerForm": { "type": "object", "properties": { @@ -1971,6 +2492,17 @@ const docTemplateadmin = `{ } } }, + "admin.UserOauthItem": { + "type": "object", + "properties": { + "status": { + "type": "integer" + }, + "third_type": { + "type": "string" + } + } + }, "admin.UserPasswordForm": { "type": "object", "required": [ @@ -2110,6 +2642,110 @@ const docTemplateadmin = `{ } } }, + "model.LoginLog": { + "type": "object", + "properties": { + "client": { + "description": "webadmin,webclient,app,", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "ip": { + "type": "string" + }, + "platform": { + "description": "windows,linux,mac,android,ios", + "type": "string" + }, + "type": { + "description": "account,oauth", + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "user_id": { + "type": "integer" + }, + "uuid": { + "type": "string" + } + } + }, + "model.LoginLogList": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/model.LoginLog" + } + }, + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + }, + "model.Oauth": { + "type": "object", + "properties": { + "auto_register": { + "type": "boolean" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "op": { + "type": "string" + }, + "redirect_url": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "model.OauthList": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/model.Oauth" + } + }, + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + }, "model.Peer": { "type": "object", "properties": { diff --git a/docs/admin/admin_swagger.json b/docs/admin/admin_swagger.json index c711955..f0a5677 100644 --- a/docs/admin/admin_swagger.json +++ b/docs/admin/admin_swagger.json @@ -702,6 +702,172 @@ } } }, + "/admin/loginLog/delete": { + "post": { + "security": [ + { + "token": [] + } + ], + "description": "登录日志删除", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "登录日志" + ], + "summary": "登录日志删除", + "parameters": [ + { + "description": "登录日志信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.LoginLog" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/loginLog/detail/{id}": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "登录日志详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "登录日志" + ], + "summary": "登录日志详情", + "parameters": [ + { + "type": "integer", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.LoginLog" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/loginLog/list": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "登录日志列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "登录日志" + ], + "summary": "登录日志列表", + "parameters": [ + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "页大小", + "name": "page_size", + "in": "query" + }, + { + "type": "integer", + "description": "用户ID", + "name": "user_id", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.LoginLogList" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, "/admin/logout": { "post": { "description": "登出", @@ -731,6 +897,280 @@ } } }, + "/admin/oauth/create": { + "post": { + "security": [ + { + "token": [] + } + ], + "description": "创建Oauth", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Oauth" + ], + "summary": "创建Oauth", + "parameters": [ + { + "description": "Oauth信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.OauthForm" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.Oauth" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/oauth/delete": { + "post": { + "security": [ + { + "token": [] + } + ], + "description": "Oauth删除", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Oauth" + ], + "summary": "Oauth删除", + "parameters": [ + { + "description": "Oauth信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.OauthForm" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/oauth/detail/{id}": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "Oauth详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Oauth" + ], + "summary": "Oauth详情", + "parameters": [ + { + "type": "integer", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.Oauth" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/oauth/list": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "Oauth列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Oauth" + ], + "summary": "Oauth列表", + "parameters": [ + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "页大小", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.OauthList" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/admin/oauth/update": { + "post": { + "security": [ + { + "token": [] + } + ], + "description": "Oauth编辑", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Oauth" + ], + "summary": "Oauth编辑", + "parameters": [ + { + "description": "Oauth信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.OauthForm" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.OauthList" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, "/admin/peer/create": { "post": { "security": [ @@ -1639,6 +2079,55 @@ } } }, + "/admin/user/myOauth": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "我的授权", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "用户" + ], + "summary": "我的授权", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/admin.UserOauthItem" + } + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, "/admin/user/update": { "post": { "security": [ @@ -1753,6 +2242,9 @@ "password": { "type": "string" }, + "platform": { + "type": "string" + }, "username": { "type": "string" } @@ -1870,6 +2362,35 @@ } } }, + "admin.OauthForm": { + "type": "object", + "required": [ + "client_id", + "client_secret", + "op", + "redirect_url" + ], + "properties": { + "auto_register": { + "type": "boolean" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "op": { + "type": "string" + }, + "redirect_url": { + "type": "string" + } + } + }, "admin.PeerForm": { "type": "object", "properties": { @@ -1964,6 +2485,17 @@ } } }, + "admin.UserOauthItem": { + "type": "object", + "properties": { + "status": { + "type": "integer" + }, + "third_type": { + "type": "string" + } + } + }, "admin.UserPasswordForm": { "type": "object", "required": [ @@ -2103,6 +2635,110 @@ } } }, + "model.LoginLog": { + "type": "object", + "properties": { + "client": { + "description": "webadmin,webclient,app,", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "ip": { + "type": "string" + }, + "platform": { + "description": "windows,linux,mac,android,ios", + "type": "string" + }, + "type": { + "description": "account,oauth", + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "user_id": { + "type": "integer" + }, + "uuid": { + "type": "string" + } + } + }, + "model.LoginLogList": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/model.LoginLog" + } + }, + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + }, + "model.Oauth": { + "type": "object", + "properties": { + "auto_register": { + "type": "boolean" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "op": { + "type": "string" + }, + "redirect_url": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "model.OauthList": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/model.Oauth" + } + }, + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + }, "model.Peer": { "type": "object", "properties": { diff --git a/docs/admin/admin_swagger.yaml b/docs/admin/admin_swagger.yaml index 0a0584b..5b0dc56 100644 --- a/docs/admin/admin_swagger.yaml +++ b/docs/admin/admin_swagger.yaml @@ -4,6 +4,8 @@ definitions: properties: password: type: string + platform: + type: string username: type: string required: @@ -85,6 +87,26 @@ definitions: username: type: string type: object + admin.OauthForm: + properties: + auto_register: + type: boolean + client_id: + type: string + client_secret: + type: string + id: + type: integer + op: + type: string + redirect_url: + type: string + required: + - client_id + - client_secret + - op + - redirect_url + type: object admin.PeerForm: properties: cpu: @@ -148,6 +170,13 @@ definitions: - status - username type: object + admin.UserOauthItem: + properties: + status: + type: integer + third_type: + type: string + type: object admin.UserPasswordForm: properties: id: @@ -240,6 +269,75 @@ definitions: total: type: integer type: object + model.LoginLog: + properties: + client: + description: webadmin,webclient,app, + type: string + created_at: + type: string + id: + type: integer + ip: + type: string + platform: + description: windows,linux,mac,android,ios + type: string + type: + description: account,oauth + type: string + updated_at: + type: string + user_id: + type: integer + uuid: + type: string + type: object + model.LoginLogList: + properties: + list: + items: + $ref: '#/definitions/model.LoginLog' + type: array + page: + type: integer + page_size: + type: integer + total: + type: integer + type: object + model.Oauth: + properties: + auto_register: + type: boolean + client_id: + type: string + client_secret: + type: string + created_at: + type: string + id: + type: integer + op: + type: string + redirect_url: + type: string + updated_at: + type: string + type: object + model.OauthList: + properties: + list: + items: + $ref: '#/definitions/model.Oauth' + type: array + page: + type: integer + page_size: + type: integer + total: + type: integer + type: object model.Peer: properties: cpu: @@ -782,6 +880,105 @@ paths: summary: 登录 tags: - 登录 + /admin/loginLog/delete: + post: + consumes: + - application/json + description: 登录日志删除 + parameters: + - description: 登录日志信息 + in: body + name: body + required: true + schema: + $ref: '#/definitions/model.LoginLog' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - token: [] + summary: 登录日志删除 + tags: + - 登录日志 + /admin/loginLog/detail/{id}: + get: + consumes: + - application/json + description: 登录日志详情 + parameters: + - description: ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/model.LoginLog' + type: object + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - token: [] + summary: 登录日志详情 + tags: + - 登录日志 + /admin/loginLog/list: + get: + consumes: + - application/json + description: 登录日志列表 + parameters: + - description: 页码 + in: query + name: page + type: integer + - description: 页大小 + in: query + name: page_size + type: integer + - description: 用户ID + in: query + name: user_id + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/model.LoginLogList' + type: object + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - token: [] + summary: 登录日志列表 + tags: + - 登录日志 /admin/logout: post: consumes: @@ -801,6 +998,167 @@ paths: summary: 登出 tags: - 登录 + /admin/oauth/create: + post: + consumes: + - application/json + description: 创建Oauth + parameters: + - description: Oauth信息 + in: body + name: body + required: true + schema: + $ref: '#/definitions/admin.OauthForm' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/model.Oauth' + type: object + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - token: [] + summary: 创建Oauth + tags: + - Oauth + /admin/oauth/delete: + post: + consumes: + - application/json + description: Oauth删除 + parameters: + - description: Oauth信息 + in: body + name: body + required: true + schema: + $ref: '#/definitions/admin.OauthForm' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - token: [] + summary: Oauth删除 + tags: + - Oauth + /admin/oauth/detail/{id}: + get: + consumes: + - application/json + description: Oauth详情 + parameters: + - description: ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/model.Oauth' + type: object + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - token: [] + summary: Oauth详情 + tags: + - Oauth + /admin/oauth/list: + get: + consumes: + - application/json + description: Oauth列表 + parameters: + - description: 页码 + in: query + name: page + type: integer + - description: 页大小 + in: query + name: page_size + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/model.OauthList' + type: object + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - token: [] + summary: Oauth列表 + tags: + - Oauth + /admin/oauth/update: + post: + consumes: + - application/json + description: Oauth编辑 + parameters: + - description: Oauth信息 + in: body + name: body + required: true + schema: + $ref: '#/definitions/admin.OauthForm' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/model.OauthList' + type: object + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - token: [] + summary: Oauth编辑 + tags: + - Oauth /admin/peer/create: post: consumes: @@ -1338,6 +1696,34 @@ paths: summary: 管理员列表 tags: - 用户 + /admin/user/myOauth: + get: + consumes: + - application/json + description: 我的授权 + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + items: + $ref: '#/definitions/admin.UserOauthItem' + type: array + type: object + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - token: [] + summary: 我的授权 + tags: + - 用户 /admin/user/update: post: consumes: diff --git a/docs/admin_webclient.png b/docs/admin_webclient.png new file mode 100644 index 0000000000000000000000000000000000000000..3ac239a763352f8da1a6db4a56d5561f013d3285 GIT binary patch literal 44762 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 ~ zG$e#mn&`aO;Z)>K7}a`M1)qQ|(ZP2}c$Y+utfLiDBkvUB%jCUiz@>wpf`#612H7

H;Md)Z8M zzl@AaV@&(;PzWi|=}IYAiV#jdJOlUa2HVBZ$d z36;?&rrue=+P$9fIL4KG{ z9R7F%ISMANv*4EYv!i8F3%6=TDhnrV(2i^Bo@$9+sUS4HhNdiWq$g8G4WmneMo-VR zMUOh;&X3iz8hkxsm2+U$6rB+|xA~_sj&=2lL)^|Ia95ju=OMpZV3c&W$0DV-ruoV< zm8DfkuO3VsyU^4TJnGV*5NqNvTe~#SA$_}~e7O88%(3sIp!2srTf@0b#+J`U_4aRE zf{v%)W&-Mj!R$M6s=d$-gSlARumrcFnSQ>vaz5}c&PP$djlyE?>S^Fs0M)h?uTS2l z50<4Ignv5-n8Ny=bnZQ%YeTmQ7i|-&U?zU!>ix!5#SG46;=f_4V_q%#zdFH=`AoF4 zMm?>3x=o%eE_dG`Zd#OCOp~AKE9Gr8vKx0pW)H5Inb|}G@)HL3N}rtGZ;I4=)*c<- zwB?~RPpgm3D(u|Ot`^sJ4PvcVE7syW^ z#O(~v6$f03VB)@Kq5(4}x?jqr^%u$7$4C!~Yss#&><381tWckuT)b*%fx3B* z>0-sJ`&XlIm%~>6!47@)I-@&aRlT(R;+`nzTo6Nc1+y<9$W$NyZS93MhKMo54Ia5C zc_ZO%MYgtPUl1_%L~$@UjKJ+6<%f&H5(4a*)1Dxnj$Hbhz5Z7Xl=WQ7gnDQ5s%DvA zZeDti7>lWICJW6h`l)#}=i-s0Ct;skT-9USqOhIdceZKcxc`~5?juOR@bEPuV+7po znhfbZlNC&A`y0Iv{XQ2XUie*u_8*2Z`*sVryKakuf(0AXh@ND(CjN_SLfW1v?8UhT z3{y4uzbR3 zUkBCwR5i8KR;XeQ7{k}QSb9$sV1_KxJJ224HOdRcY)J!g);UM*VneEfi5mZjE;z z^uS@h{WL=E1QR_KwzD*u>aXzN8tzNyzAoqDir|d!zx`rHa6ANK6w2EGdnf55Rz6Tg z<}#7<-+t_HN$2Ndmkf`!s(hZU$c0J$9y%s$cixzPcI~TU*RXf(KCV+_$fTx_kAZ9N zy^1p+P|6M3RUTG;Iu?t|4j8nke>coz0KZ9ZPGh@2{FRwfvS$ufX@+P>47$a%HwE_@ zYt{9vUF%5{1%bW-lV|tmh%w?CJbfqL<7iVgp3ugh>W@Gp#M85mxPLn6IU&{t4yx(H z8!JM4=>fQ1$`@pyMN(V;)f8v8nT)cbL@jC5> z{+NTU(9mRcMglQs2))+K`-vPW%2}MIXk+V>kNJKgUFjjXVkBM#SM)*pB7J^b-XPx2 zg$jHFlk?87HoV2-n8~Ms8xF!1BKs`1u^Qib(FM^+nuK)v{kbt|Dx#wI)rQ4Pb@Npp z&w50Ki3`jk%BaxPn@g$FUO!*M9$WQEkTym^r@Vt0Zn!}CAY!h8tKI!^*C*68pbb0q z*u6{jZNqzyWq3-5e>-GAKGyi>;ww!i)hC@cPz%34U`+b{2Rr=IKGh{RKhi2cg3A{D ztca+CCubq@`qtT7O_9?nLoB%o?3yi&*svYkd8aX=m>$n@BQ>7q&Dj?xFh=fV9!Dl} z!}F-s8D@E#w+S3oI0YtvlIy{qGE2FP$+9lOywpW{3zthBD%4s|#%QAR?Cy+LOtw&4 z?~+Rwpu?5*S)XQiF;dRH=cmB_=Ql3J;V8Pxw@m!3{HRd_ec5ciMZ6;|f7wI-m+TiR zaBE_#6*80*d>NPm4cx<1`s80&JDBK)y10x#@Q^azNw=kLE?Oerte`@OOjY-SxwTEW zRB&h*S93fx65fOk{-C(S*q5|OpuJ&ZVOxK6O#MydD_;2zot;L=qEZjqsgXDHZ4yX| z?Uk*kS{tf&sEdt0(lSvPjSl$~+8u>*Pb^My=rs`9r)57cq~YyyQISq!eD4av#{Lk? zA_us&{DFVBKC+9G5%vC>wQWFQ>gj^2A6Oih>}lX_}%8GKxpAN-Eu@!9L3;oF+#)xy>3q9Z$f$J2}c<3@2dr1k1PVr0Op{&&zm^; zES9J0NaVl5PvUw>Vaup(1xD>g2zltP)JrQJH+#&dP`bN=-XciV0S^9$IZX9@u#3)S z4wvAU6NQ7W-=$}4s2FeItbz)+3TcT=QBd6#3%AGQDMx?BzB`PTfzl+>S%o}$3!|aqx6xncdl9UeD;2cI0$KYg zIiymwwpKlVHCTNeS?F9h%8NNU_-<0kEd-n~o0Aq?kXt<;E z4~pD2Ot3FW8J8-wH&(B>JiZMn#7{D&cxW@Tjd1(rN=d|qT|ngP&5#b}ZJU7p-SYLN z=W~Y^MPr*A<4=pm`}fAFn;}t!D^#W8u!Y8m{25U^d#i^%_Bp$PO5N{&!VonadMxz{ zobZ}2!0kU!O7B)}TL#qIod?q4+^)%Mz<%;>orDwWCnzv!nC;~JO_n5xHqE6~-$LxS z4yyPlEk%hFJh@i7s1!f8F3qV(I%`Hn1I0phm%sI!eBTqGk`?*cr#vOxzVnkK1}q5( z5oX-RkI{qD@dH*4#09m#eN>kqWSH^U{yPjk@rcWK9KIcs^^*C~2&~;BBs?aUDSz6# zMGGiD;7R-;WisAvtAjBuqg>#`H!ZBa?P7|!`d29mt0W1-cQ!84M2UQ}n2BNXMejgi z&TGX-SN{mmyFfpF0MLzIVj@ty9)5Kbw;xE`O_mR`ttD_fwQAu-@Az0W0NdGmK$zW) zPe5TY`=c62MIzO4?tU+B-7b+9UtX(=$=XNUf?3mYK*;}t!$2u8ueIGRsePYKot`^x zxwU*>1%=|14dS2MN9Hr3Vc+uX$GG5;BP375$r4d*1U{iFZdDDj^1>3)v)O{1b?n8! z2mBO4S%w`GDi^I#H00vH%CF8aim0D2zHE!oZFW8!nu!qixxgVkHRE8O%;z>hg7%^f z!0XOVu#H`wlOF~7!#%f(=de$jr zM+-;93#bX4h#zL+Ru_FGT_3sx4!(+yL3DGZV(o>+87A>o2@hm$zAwt}QD`2d6SH#5uPu24PSA!tZl1cs5hW&msAeTqHE?=Zelj1ds z&jmDE3`|()Bgjll{Q7`UJ=G=Nzwr(>&H>Ju6i1#LE|mRN@TCMVn~OP)x~n3VjA}q9 z8~eplBS#^1Q_C&NQ6@((ijia0YT{DvSGQBkxA(DkS9dquov4HHY3L5$LeETh+tQYx zy0u3=&AUP>t_fXZhMZ15sL=A}&9yQLVsOXRnNTu!LCBNK#eyA=Px3RXByRMRe9x{B zw@P0!yKJ;-R@*I^wLqE}8xZ}h(yry4nU11i`w8*wxg`acx%fjKJtW4DhlS297o2X_ z1)dN%hqm(J{OZT6A&CZRcK}!9{usIM+ZB=-&zX{02f7BI=`K+_wk%_%$Ck0obi$T7 zSu5`iMw;$-fWKn|CYAmqqz1?heEs~$5{gloFQ>*kQ0(@NxmxpUGaZ$d8|FIdJ8?m$ z027Q=h7mRwa?JZNIG?Lr!a>XU0@w26)9`AsrD;z!@wk&w?T>c0PlK%X*)j)UM6`8Y z$?;}xWP}E!SRM>cYZ>fO=1ayCJ5_GG2p-&yjcL52;Jw$leH%z|i54nIpPpaA@C_lB zsoV|_yuBTJeV2SivNBenouM-R7__MkSUkpG4_)O(9t6RJy*pegZtL!T>eeb+pt^On zj$R73-$cEj_G_T~vdX1CUitIe2_<1{O`F{L4<7}k?z3eLm{_t@jLl7f<8NSs$Sa1b z=Ys>6`c?_1F5l`D11)syyhFlM1L}{5dh-3J;23Ds^_0F>#PPW!F#dbqGrZQ zuPtOsp7fsY$4>>-r9HmDdE`I8k&f+!2o>~zx|s5Cp&dI5K%ZA`#HB`IU9zQf*Y+?W zWT1k`@X|VRav@Gp;ZGK8-Q?ZJT?Y6$E@k6xD3QHzrOxIS;d-5&nz#}>aHPs8bYd0~ zRG6I7_5J`{yUc#JqIQr*Q4F=yg|(N|6U?x?wghDLd2NYWHV_$XK;E|RkdR7tIShuD zxlNScoYr>MC%;yYpD{1MkBV;?^f!`N7?Qt92OBbB5>n$A;~l^stfAM`?->Q%oC_{O zs!al6qV8wqwG~Un7zS6htvYm~JYiZJZ$_?zU;PVQSB^fyJ(D4g5D0rMIRs6VDqD|F z(7yJ50nPXQFTo<#s6RB-+Dz*T5Yq z=hc8znWzPMv>i{elJ&<&ijxFCDeNu=nS`(}Hk7wedBt@H;ct~3))@t@m83^8 zR;Z6cqr;r;3!$&#tShO7i#2fO*H+rbnkG#jjY7=Gf(}Wq3=!oVzs1D;AZMwpJG(|n z5(bkC37NQp_VAOt=|a!SIlH@({2zVAR0p78%kNmVK ztU9ap_M9h|&)!NdH{`aQBC<->6yRO6)N)5#c(w|=$_#0j z2@+#R;4vR&ESt28{5@`K;DMM<1I-7EUNj1bJg@|fZ)U%oj>H7{p%5IF+ zv2>!>Z6#jA)fm>`=@)kUi1f)GgcxDAnkbwyai$mfgBwn9lgUa0pi+G#IGWL*5asNp z)Y_L$Uk?#@8_O1N#pD4<=la^204j`pZgXFCT8U?aLW3hXaW}l|Ry3~0S66@orZ0Cy zZ0{)K+r?IA_==W51&I!DLOU@GNEd=BKD;3!LZ|Fh?|_u)khA3KPFp zJioD0#;O|YP4en{r%#$GMmhy%eGox{ruDH^~3|l3*S34shMMDd?D67wLg8@ z`3BcNPdY>S$6=fAWV?xKWW&vQ%Zvhr7EW0piXQ)<@@flU`LCi;;9Ky#o*5x-j4L!5ZxUj2_0c+I5I*Om9AUBHl@mT2x8voQ70zQyF+9T=cHx<|P~UYxa8&GsI0sG~h%5-y`fW z+-l$YE!h#4*{Zgh4Vw^Vzgi3SQ*VrPbp9xpgLqDD3kyG%wF@f>wyuzBW9u7@#Lt5B zxMsK%*T()FGjC6s`|nxOFh^Khi$E!+C%48|p&6SMTmALP-+=gry^s{rR1zS4F|m0p z&a~(5diFco_c&WLpg5?xK8DVwDon~(C3EBSk=)lwu1@-ZfeNU&&J;r&?ucwP#{Dq- zEnrRd5F^6K+7F&nxFT}O$TrC)$h9B`*TilEM0$fO+QcFVC6UTW`k7j2Nvbb^ZRMKo zy!jTU`+GK5T&P2aLMHs&!;WsLyilB`xvpkeAG;-L$ThjO1slbf zP_88jFUeBAErw1M;1CXP$BQkYKjdNzyk>fKkdAb)`Ub)rbBE$MoZTLdp+su2zA zrPJGmwi;04eTI!8qx%PvZaZOY-CZ}@bcAEJbj9xRC@OFQ${pd>-%@WRuInDgs_0W^ z52}3DcCG-Su?83SNvR(L`uo=zU=RFm_-PQ(l1mbRQu(Bbuk96X|5h1z(4@0=WlC54 zt~BESM@rz%oDGfM}hm(hLy2-$KmQzDMcm_r7e<+5|~R(yW)NW64_#+FREC zb(?tqS3Y`x>;)nTU-Nk`$q~gg)Ga*a<$Pfu~yzX(> zeJ&89E~7?JZNP z3&V56%Om_L+tFVR!7^vRRuJ%?9AT`D!&%#$_G6zu_?J&#+}n;H7{rqI@M@mw`Dq_8 zJ_U*w#LTUeYhuibMe$YM+JRw}*`N0fu26N0OO^Y8GQ#mQ&jt8{X#$B{CcL>znBBf? zV4U)Wh-q9rNeS9Ni`B`CLL*dlmy>reZl0(KjZ8?|)y6-%ow&4bx_Qf&bAl)ax3cTV z6;J|Zwc3e-vI z%Mn_JS6)&^x0%KBWt?TV4}20_1VFc*$w_x8$#lx(`Br=42z0C?n}vxFzqs#{+%f>( z`g|>t5RK!LDIBVto-7WmH`rQRa_F-FBN2GVNouc2Du;Dv8Qs&g+I1gj97_WK@N@d z@a#8o*q@D)kD53$7*>b(1JgO9NjL#Q_GmIRIBZErP7sHD+r1k}f(LID7Dtdx%w~x%s*N@`k?;i)DP! zo4@^?vxhy!bC&#AyQ|+(X$9vh2q6!x}m6gKq0NBw^+RG&P! z`J;`95ZsgA<11Zjpd10T6-lvILRp_a@Ed6LR|I8_Y+Mot1h94jV7r0q*NFc*@GSB0-l^V)KAe^+8=2jUrZ8&H`Np(HHH=HpOTcxL#EQn4SuXcK4=~g~8ztF~2yc-}wF{emaSWwx)m-it8V5n$b852r0g zxp$GL+2_ScAL5V=T7FlN)v$8ZTp;_st?uzk^tBwP8gmnT!b z1mxJ*rS@>nYZe#k(Uc^(QVy9SZ{#v|sE|K?*j?SBi#AdkhBai&f2{#!Ga+CvJnyus z{GsHDQ4MsqYp+Ar)P<9y>scD0kS5?4=v~9!1`?BDr~xH0sr=z_X$7u{Uu?xQC8XYN=CWV!2Qj#6vJX>Li3v3s{cN?6x z3PH6|Z@zFG)I@Rn;6)cNClF+H_926+zr=wn_9;--pqP}NpQo6xp%I58>bq0kZ-`TRkswYG?0I9;84Ma?R!9bvR4<@Ck%o zNpba(Uk<_`hzN0q!xm==_>VY5c-kyM(J0}+R$MlUfQK*4>ICUWK1fwL3?-;(`5Rd* zso&?@Kn8VG#6DG4I2)fZ9>27YU=jssMnP=uZ-`Y*HYnio3c~&llJ$Im+G+5VdzDZB zoYPK#UZkDOfaotyDVpStZ5DDH|D$x3yaU2=dpOW?aZ@@$yHZ+QV__VAK@!g>dH00c zqZFM_vIUAL9KH@XS5bb51ni+P#D+@;^np!`EYs$SzmDeBm3!MEXTp*@_EDCE|3UysVIUz9<93rNYa0e0oJ z{2grpt~?tNc3UOj@I8Bsyb{R@r&z?QhY_wS-wGU@85L7;H3~iN+@16lY037*XsvqZ zfOZhY{bg?sLHm`(UnhLH9GL6>xh9%XU4RBDWuwv#D5WXAidJ1_#r$gGNnv?+^+A{* zOX7WZ=Cgl{0L9L4fp9ZQ^{U8t{wvk0Ud4;cTxf`46nE^4FAO|yOPi_E%l3kJjtTn_ zhV)P@fUYmJ2ZqIs__g+Dx0+GFJSv_(RDD@7+-?P^Jx#WsWCScic#{INc)qr zy+fRI#kqe}jvyxc8KF~MQddsXf_tWfqM-Q?U4j+Q>nsnz!b2K4)GrWkZmAr!PNrJ{x1t4u!rFB$H;&l<-$-NVY)tqEW4~l=FwF0 zqk_KKt2Ft0RWn7qH_ZJU3k@@=2MRgzHZwB(-j>FA@1Eo_mDLkg2%>Spx8MkZv$q!R z6})oLrGW(R$6foEOCgb79PYeS?>C!QMuNMy7VZ~d9Cb^9?fNvLNJ_oH%?UbS!Y;*- zt}i_38#7__DL4Wb7~%#gYZRh)Ng{gpsy+z1ecJN?<5R2!m;&Nn&9*^4r1K0G-^Dc_ z&rLY~1%Yy9qOCMipIp1wkwTayU#XMT{3O@v*BB6;UEdguf(*$h2f{nqupAD-zykoM zpKTv{kzyB_6ZFvVBZp>O<}&2T!wYQ?shEv}xDz}8HYi>43hS1w%AnBj!(k17Sotx{S25j^EON{zDn-wJr*JzJ$g+VXur2!!Q0Hnd z=SN3OoRM`VWI8AK-|o#8Itf_zxPwQ?n*lr`Qe4eantMlJ`#M0?)#QeD-d$Q8m!AVq znu#~6TYWetTgci|K((hMPJ(kM8@GbOB3$3bpc!S53v6F8$O+rZKu&nbC{CBOreL3z zN^7#RIH^FHV2~{|VvQ3>cXYGM4J~{Q!l2gf&()}^*;3y}p7h{m_z~ z)o0AeH$P-6lqlodT0qBFUMCkrlqb0U=Oo<%?8%K#@QJ~^%OG!{{pG|l0JL!;o!pBL z067xdIGdIucl4$*vKu5z>jRinuW!|gZ$Yc?8z7EmNHzqEU(nS@%&5z{__51%rpHzC zeWS4Qd>$77IqWN%=+=5^*ft^Ugb)(gu@yB8RGT47K{riLl{4)9)>Fd9Nk1q^8(bR=o4;807rEy zTaNc>Fmc}akQIl%5%UtOwAd4qT+|K{(DKjD`cSdbwq*`41(Q}OLv(PGXM181_mJgp zCtncuHhb1Sy+p#tg{}o&85^W`QWN*x(|g z{H67^Ty&tEd=HWAAq@Cj3>9Xp#@wZCWH}*oF|X2GCdR8J9XcE-UJbZ?=HZ~UK*>VT zWlpUlQ*i;nKCJX<$3f~@9Fn97${5WM<4j_MBvg?dj5iXG!0->VNqwuSmH{R7H8tBw z`}@Aa9N7@PC~Ps8yjC7E8n)#;`t%t3M9X6c0iJ++dv{0pd*F%4&nU|Vk{h8DLi-Bd zx8!*fsne{+3c>+I@DuS;8m#hL!X@OI_A50eha`j)+E9_aWNa%(VF{Iox6ZQ>zg;A# z%05EVf{+V-Bn^hghnNm@^TaT2mOkTaCss~3!EpL?DEn!#1&4qg!Jf(>e3Zgs5Ef2& z4IwJ3HVM#NXG#@EI=6Ny@0>!D{G@H43xAdY48N0ce^RxccspGQr6^AWNz(lCe=~Wedc8o z8#n6#e)5ISGA4n3ysxy@@NHP#Hm-BJ6i*IOy1qA%%N5qDgtzCPMaaz|myYoG76Wi~ zpa$}$p3sZ83Y!(hB>=8^yPdj8D!n(vS{sE6Aud!zNILz)F&5A&XJH*{>mk@|f8UFi zFh4p$Sm)9_lWC{<32}-(Dmze;M__C?Eri6b4D)*HABWc?&iY8W;;!_#W~(Re z0whaE-#mb(m>kPK2cVTnS<2ElXJ8P3JlbfX9JwoGNn2VfRn5hBU>_JGB0Uu|<0b@) zFy?=Aa|`{n{Id4Bv7^%3v2BA?GOH;KxS1vNa3U!5vYCmH@?7C*n}=u@2Wgsb2A2*w zpNnyZIdGfVo9r=w!2Tk6BxOmA3A6KKhsIKgy-mXL>~2uz5KsF$ahDvF{`UZ8+pmnr zz_F4lK{>+_vWz10eRg}@*E`+nZVovJaX9ceXw<@z?wIesRi^3NbLQ_9j61xpIT- zU@>SI(HamY;WfdyJD1EY#)BXCV}~- zkw>-LIUfo|@Vr-8fqB9gGpEErfscn?)uYIzb#aM&=ZnbhznIP$pc7a~rGw#58rIrB zGAqK$$)-#VI*$dGfGm&@D#nYY_AtjpgDT#w81OFjAF!u)eu5jvvRFY$AI$IkI0Ch(BEyj0BtKL3;Wb@p$fI}n@FwU-pIQ_KkSW64?1|-CkSW% z3AZWt09ZJGB0GNAnK2bJ4vPTaG!Rt3xG!%Sx)n;$ebRBG=D#i43!N`uh*W4* z)0SQ&uKFp8^!>|w@n=urVe?UQ@A5sC_zK(CYF`j+!cK$EaX5MIyv^Y_)R z1QLofRav+zAvmMNQqyut(PtDX3UaI-8)F>K(!QoQdVpuMOaIGfcl(!@=X z_I_<9XZ4>4z0IYuCJ7r9V)R2l16I%0P107s@aaT%;mp_L0)V(>JLX>epb;J zC}%H7{^rdQ4fGm!9K?-(84sQMohXy-z1yHjSlUMeILPO?Llb%iiYd8&P~xMDr&!s` z(x<&Lq(=X~yX?XK4oel@?`&-cY`@N_rO1}!pbY=7q}fjt#yNZd)ue4cHfG)=L?nZL zxdui2W8bV04tCQ^0`?uv-_0HK(pVEJ-S2Uwx}3c%>)&XZv}zwgQbF^+3mMt?>BmJrc*pCpFC)ey%n5YV*fWnN<`-9$j%fG zG2K6DmTH|{)xpji3qFM4zX(}X5?8s&-VawU58}{AlFVN$hi{;DCYDRvfb3fC>-24I zD!xALzq`W!BE#p4gfI*b>_nM?S~bT5qsr8ZwU4h->L@mMklsz0{pTo`#p%%T1Lz5f zSq5%_uj%MU;usj9Oa^~U$}uVficA)^Jl$P_oc-@t_@N2bLa0#}+aEw^atV+eg19)5Fxrum%vlN)P6^5XD$PB;GiK$Y0sbe*M6{$R_q z-1;XsQYn_+*Qm&6yxoW#%JqjkX%_V&@hycG0dAp@6e+x^hf!ZRfJ)g-qH^h=ZPqjz zRmDlu$4TSUJfC|fzfcH|H+F_|MB+=~G~M;#UlN@RZnj>c5uzMUbOS9vihEzQcuQc#f%4+Fy>(neGKqa62v~#lI<}np_?!}UJ``2< zh=1&Yx0a#A2=pF(MtAafbtyJS=PbWwIJ%qHyYt5{bS7x-l6c>^fsFmB&?TmvAjhS? z=5qt(mYI{mmffgehX;t?UrI@4uXAj$j@k5ufjBjfT6ay}+0P#765a4AcV~okHMw{3 zi&SeZ7Q&jW@9=({D7p3Lk7^1S!h2u|1$M;&Q$(kFsm|m$Qz0 zbeyi6{?NVMlbcldHk6s30^JYa>~rMrE`)Pg=XKp)xS!%%W&es$JgGDOHu&UHc~a9j z{X8qI_wneX32CQqd(!x~LsYa4OR*w~RM82JlMnKw9nve1u^~C3A*SV&UgVLX@%n~; zobJj*tgi*{5r@I+6R_eMNmB~fF|?=xzgp609V+Q2Q9EH-338>tg5PLU{rIRCQioMM zi;pI8UQV?n1uZ>$HbHw7!I(qaQaixLKUE|dG3vA?eglp@UpR@{e@Icl1WVxDnO&ZPjQa zu}|WscrEH^bDRrGUQUymxb^C@)&Q?%jrbPcbMh`t*V#_)s%8(jZg^4amB*zK$O{5< zzRm7#0dW0idFe57^=fVMKlxA6KPC>x_5aQYB1n!4LECRFcvnajrSKLSs#kgYv6+3%m^hi4IAEopGlK73mKMrd)ShF9lmLt!D$25j7| z!@An4a@z>Y-*I|63O1`#bSEmVwDj%bwexHWzYovg(n4!=6?GcW`G~dqgw9<*nqrm} zhl(s6Xaz`grSm^@K>mJ0;bG{6_`R(KG#1f`L7!aq#$gMzAdB@)KIw>HLT3f#mv}tvf)Ef$z;3!MydT^{#$zZ*jCU9g6cTDi zJL8&2WwM(WKp`7!O_Vo^hF5Zly>|0>p^eTm4~EN;$tz@{f#gT--$`G0GKDU!?LL`< z?FMS8aS)0l97^xpo+?nm(}GTm1zgU_`gkmeU_hWlS%0EIY)yvTG0&FiGAO@^>5wC~#Fr@LP8*wroy0$=OhDsm-Qagjf@dgl^e0l|i%!q2$f50_xk6Edf2*I+ z;*^B}0?I``bC1#nu8QNpqjGcfN|guvbU(pv7)NG7#o`*=rqC94b~n@#wm1MKl`GOk zym;2hA%noYVC-WDom2p#+Z}~Hw>qaIdP$}#xs2`S9nB9O6!N3hn7GSdWLoJ_#0;^! zVFE+k!(fP;uo<|x?unRcQG_cxa5Mykx;PU5-tcEQK$Ed9s4Dz@f9?aI%}Z_Kgcjs) z%%_&1fjbZLwFbsO;z1Ucmaisjr_IY16>33~XC_ZZ4DA;k-oG@r&7#n>d43)gc{+!- z&nzEVW`usYxAX5x4X~eY#dzCz)*!wDY8hn^Y`UThe+Jna*g@gjLim9nHYSqy@e>Qb z9kPo>#)6%5lj+OOu?cOsS>4ju$!DN%C?+YTHNM?} z5WM~+;UBAHc=^M3Bt27c8|mX5D&X=wB21%CN4k!|A(CD>C$YpPLt*_@CsE8Jx!d^mjD_WODG85W$P~=8gWO9^5H8cA;>w4*91>Lzp;tOhh*nB zN9TQ`TPhvaA^6%;iG)I9PDZF9x&bg%s4pq@prR|&cUen7?);0pgwFPtG*D2+^cixS znOf2#4{4xdf8qEt4$-UKffv9YHE1cbG084E^_)xFGW~Nw#<2KoZUWmxGnn*(-9`gf zEVq1vB6>cI-J8(KA-tpAB=smMb~DWZR#r*;#g|>08Ee)@z8gZf95S^|2o<&mTA9VL zpE_+HXia`34g8sQo!Oe=Y6h~MI zssCkOmYpN)IMPNfP!Dr1b;tMSrVI<+8<}2b{=v2X38fh_a)ova06zc3OaG6Q_Bg#p z{XaDEl0=yg>pw8@c~8x8ChKZB)?dOcf=L{GwD=>`<1psF;|oZEIR2bLox8LLl+1iq zU5rYlnTaaPE|mT18oVy!lR+C8qy6j4eE%!Tpl^$~oK#RLg(t34IW}AHyyB>EJ4V^F zWQN3Om-}+gdC&YY-?k~H3$%5Ds+1EA(NJ)3OKe(Fg5G+J)AiU?fiy>YPx+V(0Q2~1 z<)F8V#fo2wG1_h06a+iKps*kRyTAm=9OM*_&gdd-sd?e6b&j+?nd5$_}M6F5w!|5(PSkH;(iM%CZ_8?U!LPXL_T8`p;-U#D~7R zF%c_fvLk_P_ww`8rXf7lCA+q`WGSaNB>#R_nFVVh4ujs~knxHW;sKecdycY$tL61N zo%NbCu*U5ME^ai~`o%Dqf#^r>jgifAx)mEQ_(di+ln@M&fg4W3x(gsnkyR;8x{ph% zxj8CMk}9e&tUb2RgHm6rzN`nGL^BVJfa-lI+j9J=j-^>wS>tcyi&;Tu_9+KBz~Amw zCYQ`yHbtz~a(hT#A&;3*d6SWTV#~&?mHmgujL5&wRHzR#QF%Mf5;SI&vk8yPom*9j z5jjb*zX>kfj*XgWRg1!cLhNn(e1z)K4}O}87XuZepslaSciK-PP|dR6BF{Ye?kVZz zKp9`<y8WCFdG4o4<6Gt)V>vyhf(hE=U0c}WWB8tgPf&NKIbys73D*?F9~dvXDTi$O(9f^O6d z1Mc$`#%U`s_Q#%rg_Ui8-!MV3x#|wam}=Hf=LUV2Yir_uI}CUlWP_bkqv~TpkMO@F z04Y>9@bLz5qnD~N_UW=iJ^zwu;y`KMZ?_Yb1Fs*5Mq1cEHx9NdYBiR=k~ek}^byfn zL&@;~<(Fvn@pS0kbSCbh6K}iQxo+*X61GunO|8C?TS14hW_D)stk;Y)5|w>1qS_;(3lWEa!0dAt(u@uq*l-{F?nmB=qD=vmEUW&nR)QTKgwLzkJU3EAc-!k@v|P~z z6_Cfd>e;)LeSYVejKWPj)BG|ARc{{-z-|F7yEaDo+ab*$TU^H76FMmE4TdYc7(iIheK#(YNhZ-<#%Hm3*~G zdGaCU$t$lMq-f1*yC^yva*Fqp=Iv`ATQ@7YU(cyEZ>TdcU#p}sv{$L0?ux#hr|gs5 zCS+t-<;{9^P}eGAYDOz$i6-XM5}B{R|7J!Ls2btVW9;*+c7L^YhGCZ80`0d3hjhP> zIHn}$|ErH-{Xc$9>wi!1pMH`IL4(KiGh;BAryqLntv!>xzxJZL zdu+!0ww%(nkuDUjS68`p5ZE8oy zvw>IAR%_tCQ!);?4P__&|Ni)Y6AUoP)%Rm#&#c;y&AeuJtkgxlYjhKP!;#&9Lw!uQ|DCHZo7%eC;cWSQ!GCI3;5;L@{jkKn2^&p ztowdvwBHbxl5$nGUmRl~P}g1E*}yCMaX$6B6{Df+w_8E=dCgH<*cX3pntDUHe*eJo zw6k`9|IP37r(Ztu+BJ9Un!o35zIyw~uUkK+G;OuJw0L9b?ajwN-h8g^#HXh$s2fhD z-Kpq(8pnvqk}fN9*(iA)7szOxN-h!dFV8EL|F%X}L+zPi?)v(n?gUL*p~^?38a_=W zDebk?Kcx|nUOjKa!GTAHAJ2caVd8Ilwx^J8(5W!0*i9wWM5yA*Djsa;yd6L9=ePG* zOJ^9bV=57+SL7dJ9`f>1kpFLQFK>UUc~YTT9hSSHmHpY*ljENM&eL%$1%RQZK&&OZJc5^(HXZto3<|NbSza8yp$WH2IG+Fx_SI`g*1R#Z?m0#a_Ezye?7z%H(f?@w}R+jAvLVt>K`c8KlQ&YCTI%v z*id~#rLFdY_;>o$Kc~)}occ<OwaX<~ntBN7$xoW0s+_*ZDAa{L%arMjWDdy?0}{-cT^D7jrZD8~cS z-afXzX7Vv{fkEE)A)aHFc-oLz!`i}yrx>iMy8g?|$@WSzCzh9PbM!gPlw78Lg{;--`ISXrD9W#AuI>@v zE`6OhYPMtG$%*8Kle^HoH{$#Z#|^jj=+6_nSgaHmQaOsVbrBJ!Jt&;p$#i^zd)c}q z9wh|Txkn7yC99QByrueu=5Qi9RNaT2FEV8@NQ0-Fm(6iZ@xNNn`Rlgk8|4blVVHxx zJu}HJD6V5vXTtnc&bGjC9DZK+0pd`w{ zNVvjZm#i!zH8<&tY_AWm8;W(e_jhd=gOb6;j{qB2Ie;Bu9K zs_`t@(_WJ#j(oUwj%QmNREd5`&nAx%1ni2Sv3_La*V|)cFr4}Z_nLd z^n*dE*g@ZmLULV4hb*XS(fZT+fd&Gvh5i#eb@|DZ50IMs`cY3aCV4S!h}wfXyRW>3 zE8FY}P7>n9896+bbXAGo^GJNmb;`k6N8}GE`18gJjiW;W=_#5IdrW0yfl0*BP4Bpq~y31<~i^t5rF@*Kg z?X(-WY0(Ca=^}0A7cIhVgvTtyuT$!qERF{oY;TDc0oBW;>4vgh7f7Q?O@`t~JO8J&FXdLB^On$0

p`)6G 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 HI}iK~cnEBn literal 45140 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

^^T)8?MWse*#D)#cbn-}_eXnq;#jI{S=< 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 literal 0 HcmV?d00001 diff --git a/docs/web_user.png b/docs/web_user.png deleted file mode 100644 index dd405d8e15cb5d876d95723f4f32c75ce0f491c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27555 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

a;dQC* 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 N49yIRFWq_a-vF~y4qE^K literal 22999 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

  • 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 0 { + response.Success(c, u) + return + } + response.Fail(c, 101, "信息不存在") + return +} + +// List 列表 +// @Tags 登录日志 +// @Summary 登录日志列表 +// @Description 登录日志列表 +// @Accept json +// @Produce json +// @Param page query int false "页码" +// @Param page_size query int false "页大小" +// @Param user_id query int false "用户ID" +// @Success 200 {object} response.Response{data=model.LoginLogList} +// @Failure 500 {object} response.Response +// @Router /admin/loginLog/list [get] +// @Security token +func (ct *LoginLog) List(c *gin.Context) { + query := &admin.LoginLogQuery{} + if err := c.ShouldBindQuery(query); err != nil { + response.Fail(c, 101, "参数错误") + return + } + u := service.AllService.UserService.CurUser(c) + if !service.AllService.UserService.IsAdmin(u) || query.IsMy == 1 { + query.UserId = int(u.Id) + } + res := service.AllService.LoginLogService.List(query.Page, query.PageSize, func(tx *gorm.DB) { + if query.UserId > 0 { + tx.Where("user_id = ?", query.UserId) + } + }) + response.Success(c, res) +} + +// Delete 删除 +// @Tags 登录日志 +// @Summary 登录日志删除 +// @Description 登录日志删除 +// @Accept json +// @Produce json +// @Param body body model.LoginLog true "登录日志信息" +// @Success 200 {object} response.Response +// @Failure 500 {object} response.Response +// @Router /admin/loginLog/delete [post] +// @Security token +func (ct *LoginLog) Delete(c *gin.Context) { + f := &model.LoginLog{} + if err := c.ShouldBindJSON(f); err != nil { + response.Fail(c, 101, "系统错误") + return + } + id := f.Id + errList := global.Validator.ValidVar(id, "required,gt=0") + if len(errList) > 0 { + response.Fail(c, 101, errList[0]) + return + } + l := service.AllService.LoginLogService.InfoById(f.Id) + u := service.AllService.UserService.CurUser(c) + if !service.AllService.UserService.IsAdmin(u) && l.UserId != u.Id { + response.Fail(c, 101, "无权限") + return + } + if l.Id > 0 { + err := service.AllService.LoginLogService.Delete(l) + if err == nil { + response.Success(c, nil) + return + } + response.Fail(c, 101, err.Error()) + return + } + response.Fail(c, 101, "信息不存在") +} diff --git a/http/controller/admin/oauth.go b/http/controller/admin/oauth.go new file mode 100644 index 0000000..5bb3f39 --- /dev/null +++ b/http/controller/admin/oauth.go @@ -0,0 +1,291 @@ +package admin + +import ( + "Gwen/global" + "Gwen/http/request/admin" + adminReq "Gwen/http/request/admin" + "Gwen/http/response" + "Gwen/model" + "Gwen/service" + "github.com/gin-gonic/gin" + "strconv" +) + +type Oauth struct { +} + +// Info +func (o *Oauth) Info(c *gin.Context) { + code := c.Query("code") + if code == "" { + response.Fail(c, 101, "参数错误") + return + } + v := service.AllService.OauthService.GetOauthCache(code) + if v == nil { + response.Fail(c, 101, "信息不存在") + return + } + response.Success(c, v) +} + +func (o *Oauth) ToBind(c *gin.Context) { + f := &adminReq.BindOauthForm{} + err := c.ShouldBindJSON(f) + if err != nil { + response.Fail(c, 101, "参数错误") + return + } + u := service.AllService.UserService.CurUser(c) + + utr := service.AllService.UserService.UserThirdInfo(u.Id, f.Op) + if utr.Id > 0 { + response.Fail(c, 101, "已绑定过了") + return + } + + err, code, url := service.AllService.OauthService.BeginAuth(f.Op) + if err != nil { + response.Error(c, err.Error()) + return + } + + service.AllService.OauthService.SetOauthCache(code, &service.OauthCacheItem{ + Action: service.OauthActionTypeBind, + Op: f.Op, + UserId: u.Id, + }, 5*60) + + response.Success(c, gin.H{ + "code": code, + "url": url, + }) +} + +// Confirm 确认授权登录 +func (o *Oauth) Confirm(c *gin.Context) { + j := &adminReq.OauthConfirmForm{} + err := c.ShouldBindJSON(j) + if err != nil { + response.Fail(c, 101, "参数错误"+err.Error()) + return + } + if j.Code == "" { + response.Fail(c, 101, "参数错误: code 不存在") + return + } + v := service.AllService.OauthService.GetOauthCache(j.Code) + if v == nil { + response.Fail(c, 101, "授权已过期") + return + } + u := service.AllService.UserService.CurUser(c) + v.UserId = u.Id + service.AllService.OauthService.SetOauthCache(j.Code, v, 0) + response.Success(c, v) +} + +func (o *Oauth) BindConfirm(c *gin.Context) { + j := &adminReq.OauthConfirmForm{} + err := c.ShouldBindJSON(j) + if err != nil { + response.Fail(c, 101, "参数错误"+err.Error()) + return + } + if j.Code == "" { + response.Fail(c, 101, "参数错误: code 不存在") + return + } + v := service.AllService.OauthService.GetOauthCache(j.Code) + if v == nil { + response.Fail(c, 101, "授权已过期") + return + } + u := service.AllService.UserService.CurUser(c) + err = service.AllService.OauthService.BindGithubUser(v.ThirdOpenId, v.ThirdOpenId, u.Id) + if err != nil { + response.Fail(c, 101, "绑定失败,请重试") + return + } + + v.UserId = u.Id + service.AllService.OauthService.SetOauthCache(j.Code, v, 0) + response.Success(c, v) +} + +func (o *Oauth) Unbind(c *gin.Context) { + f := &adminReq.UnBindOauthForm{} + err := c.ShouldBindJSON(f) + if err != nil { + response.Fail(c, 101, "参数错误") + return + } + u := service.AllService.UserService.CurUser(c) + utr := service.AllService.UserService.UserThirdInfo(u.Id, f.Op) + if utr.Id == 0 { + response.Fail(c, 101, "未绑定") + return + } + if f.Op == model.OauthTypeGithub { + err = service.AllService.OauthService.UnBindGithubUser(u.Id) + if err != nil { + response.Fail(c, 101, "解绑失败") + return + } + } + response.Success(c, nil) +} + +// Detail Oauth +// @Tags Oauth +// @Summary Oauth详情 +// @Description Oauth详情 +// @Accept json +// @Produce json +// @Param id path int true "ID" +// @Success 200 {object} response.Response{data=model.Oauth} +// @Failure 500 {object} response.Response +// @Router /admin/oauth/detail/{id} [get] +// @Security token +func (o *Oauth) Detail(c *gin.Context) { + id := c.Param("id") + iid, _ := strconv.Atoi(id) + u := service.AllService.OauthService.InfoById(uint(iid)) + if u.Id > 0 { + response.Success(c, u) + return + } + response.Fail(c, 101, "信息不存在") + return +} + +// Create 创建Oauth +// @Tags Oauth +// @Summary 创建Oauth +// @Description 创建Oauth +// @Accept json +// @Produce json +// @Param body body admin.OauthForm true "Oauth信息" +// @Success 200 {object} response.Response{data=model.Oauth} +// @Failure 500 {object} response.Response +// @Router /admin/oauth/create [post] +// @Security token +func (o *Oauth) Create(c *gin.Context) { + f := &admin.OauthForm{} + if err := c.ShouldBindJSON(f); err != nil { + response.Fail(c, 101, "参数错误"+err.Error()) + return + } + errList := global.Validator.ValidStruct(f) + if len(errList) > 0 { + response.Fail(c, 101, errList[0]) + return + } + + ex := service.AllService.OauthService.InfoByOp(f.Op) + if ex.Id > 0 { + response.Fail(c, 101, "已存在"+f.Op) + return + } + + u := f.ToOauth() + err := service.AllService.OauthService.Create(u) + if err != nil { + response.Fail(c, 101, "创建失败") + return + } + response.Success(c, u) +} + +// List 列表 +// @Tags Oauth +// @Summary Oauth列表 +// @Description Oauth列表 +// @Accept json +// @Produce json +// @Param page query int false "页码" +// @Param page_size query int false "页大小" +// @Success 200 {object} response.Response{data=model.OauthList} +// @Failure 500 {object} response.Response +// @Router /admin/oauth/list [get] +// @Security token +func (o *Oauth) List(c *gin.Context) { + query := &admin.PageQuery{} + if err := c.ShouldBindQuery(query); err != nil { + response.Fail(c, 101, "参数错误") + return + } + res := service.AllService.OauthService.List(query.Page, query.PageSize, nil) + response.Success(c, res) +} + +// Update 编辑 +// @Tags Oauth +// @Summary Oauth编辑 +// @Description Oauth编辑 +// @Accept json +// @Produce json +// @Param body body admin.OauthForm true "Oauth信息" +// @Success 200 {object} response.Response{data=model.OauthList} +// @Failure 500 {object} response.Response +// @Router /admin/oauth/update [post] +// @Security token +func (o *Oauth) Update(c *gin.Context) { + f := &admin.OauthForm{} + if err := c.ShouldBindJSON(f); err != nil { + response.Fail(c, 101, "参数错误") + return + } + if f.Id == 0 { + response.Fail(c, 101, "参数错误") + return + } + errList := global.Validator.ValidStruct(f) + if len(errList) > 0 { + response.Fail(c, 101, errList[0]) + return + } + u := f.ToOauth() + err := service.AllService.OauthService.Update(u) + if err != nil { + response.Fail(c, 101, "更新失败") + return + } + response.Success(c, nil) +} + +// Delete 删除 +// @Tags Oauth +// @Summary Oauth删除 +// @Description Oauth删除 +// @Accept json +// @Produce json +// @Param body body admin.OauthForm true "Oauth信息" +// @Success 200 {object} response.Response +// @Failure 500 {object} response.Response +// @Router /admin/oauth/delete [post] +// @Security token +func (o *Oauth) Delete(c *gin.Context) { + f := &admin.OauthForm{} + if err := c.ShouldBindJSON(f); err != nil { + response.Fail(c, 101, "系统错误") + return + } + id := f.Id + errList := global.Validator.ValidVar(id, "required,gt=0") + if len(errList) > 0 { + response.Fail(c, 101, errList[0]) + return + } + u := service.AllService.OauthService.InfoById(f.Id) + if u.Id > 0 { + err := service.AllService.OauthService.Delete(u) + if err == nil { + response.Success(c, nil) + return + } + response.Fail(c, 101, err.Error()) + return + } + response.Fail(c, 101, "信息不存在") +} diff --git a/http/controller/admin/user.go b/http/controller/admin/user.go index 45bcce6..18b03a3 100644 --- a/http/controller/admin/user.go +++ b/http/controller/admin/user.go @@ -259,3 +259,37 @@ func (ct *User) ChangeCurPwd(c *gin.Context) { } response.Success(c, nil) } + +// MyOauth +// @Tags 用户 +// @Summary 我的授权 +// @Description 我的授权 +// @Accept json +// @Produce json +// @Success 200 {object} response.Response{data=[]adResp.UserOauthItem} +// @Failure 500 {object} response.Response +// @Router /admin/user/myOauth [get] +// @Security token +func (ct *User) MyOauth(c *gin.Context) { + u := service.AllService.UserService.CurUser(c) + oal := service.AllService.OauthService.List(1, 100, nil) + ops := make([]string, 0) + for _, oa := range oal.Oauths { + ops = append(ops, oa.Op) + } + uts := service.AllService.UserService.UserThirdsByUserId(u.Id) + var res []*adResp.UserOauthItem + for _, oa := range oal.Oauths { + item := &adResp.UserOauthItem{ + ThirdType: oa.Op, + } + for _, ut := range uts { + if ut.ThirdType == oa.Op { + item.Status = 1 + break + } + } + res = append(res, item) + } + response.Success(c, res) +} diff --git a/http/controller/api/ab.go b/http/controller/api/ab.go index ddfb026..6d19408 100644 --- a/http/controller/api/ab.go +++ b/http/controller/api/ab.go @@ -7,7 +7,6 @@ import ( "Gwen/model" "Gwen/service" "encoding/json" - "fmt" "github.com/gin-gonic/gin" "net/http" ) @@ -66,7 +65,6 @@ func (a *Ab) UpAb(c *gin.Context) { abf := &requstform.AddressBookForm{} err := c.ShouldBindJSON(&abf) if err != nil { - fmt.Println(err) response.Error(c, "参数错误") return } @@ -93,7 +91,6 @@ func (a *Ab) UpAb(c *gin.Context) { tc := map[string]uint{} err = json.Unmarshal([]byte(abd.TagColors), &tc) if err != nil { - fmt.Println(err) response.Error(c, "系统错误") return } else { @@ -134,7 +131,6 @@ func (a *Ab) TagAdd(c *gin.Context) { t := &model.Tag{} err := c.ShouldBindJSON(t) if err != nil { - fmt.Println(err) response.Error(c, "参数错误") return diff --git a/http/controller/api/login.go b/http/controller/api/login.go index 5fd1c65..088e45e 100644 --- a/http/controller/api/login.go +++ b/http/controller/api/login.go @@ -5,7 +5,9 @@ import ( "Gwen/http/request/api" "Gwen/http/response" apiResp "Gwen/http/response/api" + "Gwen/model" "Gwen/service" + "encoding/json" "github.com/gin-gonic/gin" "net/http" ) @@ -26,8 +28,9 @@ type Login struct { func (l *Login) Login(c *gin.Context) { f := &api.LoginForm{} err := c.ShouldBindJSON(f) + //fmt.Println(f) if err != nil { - response.Error(c, "系统错误") + response.Error(c, "参数错误") return } @@ -44,7 +47,20 @@ func (l *Login) Login(c *gin.Context) { return } - ut := service.AllService.UserService.Login(u) + //根据refer判断是webclient还是app + ref := c.GetHeader("referer") + if ref != "" { + f.DeviceInfo.Type = "webclient" + } + + ut := service.AllService.UserService.Login(u, &model.LoginLog{ + UserId: u.Id, + Client: f.DeviceInfo.Type, + Uuid: f.Uuid, + Ip: c.ClientIP(), + Type: model.LoginLogTypeAccount, + Platform: f.DeviceInfo.Os, + }) c.JSON(http.StatusOK, apiResp.LoginRes{ AccessToken: ut.Token, @@ -63,11 +79,31 @@ func (l *Login) Login(c *gin.Context) { // @Failure 500 {object} response.ErrorResponse // @Router /login-options [post] func (l *Login) LoginOptions(c *gin.Context) { - test := []string{ - //"common-oidc/[{\"name\":\"google\"},{\"name\":\"github\"},{\"name\":\"facebook\"},{\"name\":\"网页授权登录\",\"icon\":\"\"}]", - //"oidc/myapp", + oauthOks := []string{} + err, _ := service.AllService.OauthService.GetOauthConfig(model.OauthTypeGithub) + if err == nil { + oauthOks = append(oauthOks, model.OauthTypeGithub) } - c.JSON(http.StatusOK, test) + err, _ = service.AllService.OauthService.GetOauthConfig(model.OauthTypeGoogle) + if err == nil { + oauthOks = append(oauthOks, model.OauthTypeGoogle) + } + oauthOks = append(oauthOks, model.OauthTypeWebauth) + var oidcItems []map[string]string + for _, v := range oauthOks { + oidcItems = append(oidcItems, map[string]string{"name": v}) + } + common, err := json.Marshal(oidcItems) + if err != nil { + response.Error(c, "参数错误") + return + } + var res []string + res = append(res, "common-oidc/"+string(common)) + for _, v := range oauthOks { + res = append(res, "oidc/"+v) + } + c.JSON(http.StatusOK, res) } // Logout diff --git a/http/controller/api/ouath.go b/http/controller/api/ouath.go new file mode 100644 index 0000000..6744119 --- /dev/null +++ b/http/controller/api/ouath.go @@ -0,0 +1,222 @@ +package api + +import ( + "Gwen/global" + "Gwen/http/request/api" + "Gwen/http/response" + apiResp "Gwen/http/response/api" + "Gwen/model" + "Gwen/service" + "github.com/gin-gonic/gin" + "net/http" + "strconv" +) + +type Oauth struct { +} + +// OidcAuth +// @Tags Oauth +// @Summary OidcAuth +// @Description OidcAuth +// @Accept json +// @Produce json +// @Success 200 {object} apiResp.LoginRes +// @Failure 500 {object} response.ErrorResponse +// @Router /oidc/auth [post] +func (o *Oauth) OidcAuth(c *gin.Context) { + f := &api.OidcAuthRequest{} + err := c.ShouldBindJSON(&f) + if err != nil { + response.Error(c, "参数错误") + return + } + if f.Op != model.OauthTypeWebauth && f.Op != model.OauthTypeGoogle && f.Op != model.OauthTypeGithub { + response.Error(c, "参数错误") + return + } + + err, code, url := service.AllService.OauthService.BeginAuth(f.Op) + if err != nil { + response.Error(c, err.Error()) + return + } + + service.AllService.OauthService.SetOauthCache(code, &service.OauthCacheItem{ + Action: service.OauthActionTypeLogin, + Id: f.Id, + Op: f.Op, + Uuid: f.Uuid, + DeviceName: f.DeviceInfo.Name, + DeviceOs: f.DeviceInfo.Os, + DeviceType: f.DeviceInfo.Type, + }, 5*60) + //fmt.Println("code url", code, url) + c.JSON(http.StatusOK, gin.H{ + "code": code, + "url": url, + }) +} + +// OidcAuthQuery +// @Tags Oauth +// @Summary OidcAuthQuery +// @Description OidcAuthQuery +// @Accept json +// @Produce json +// @Success 200 {object} apiResp.LoginRes +// @Failure 500 {object} response.ErrorResponse +// @Router /oidc/auth-query [get] +func (o *Oauth) OidcAuthQuery(c *gin.Context) { + q := &api.OidcAuthQuery{} + err := c.ShouldBindQuery(q) + if err != nil { + response.Error(c, "参数错误") + return + } + v := service.AllService.OauthService.GetOauthCache(q.Code) + if v == nil { + response.Error(c, "授权已过期,请重新授权") + return + } + if v.UserId == 0 { + //正在授权 + c.JSON(http.StatusOK, gin.H{}) + return + } + u := service.AllService.UserService.InfoById(v.UserId) + //fmt.Println("auth success u", u) + if u.Id > 0 { + service.AllService.OauthService.DeleteOauthCache(q.Code) + ut := service.AllService.UserService.Login(u, &model.LoginLog{ + UserId: u.Id, + Client: v.DeviceType, + Uuid: v.Uuid, + Ip: c.ClientIP(), + Type: model.LoginLogTypeOauth, + Platform: v.DeviceOs, + }) + c.JSON(http.StatusOK, apiResp.LoginRes{ + AccessToken: ut.Token, + Type: "access_token", + User: *(&apiResp.UserPayload{}).FromUser(u), + }) + return + } + response.Error(c, "用户不存在") +} + +// OauthCallback 回调 +// @Tags Oauth +// @Summary OauthCallback +// @Description OauthCallback +// @Accept json +// @Produce json +// @Success 200 {object} apiResp.LoginRes +// @Failure 500 {object} response.ErrorResponse +// @Router /oauth/callback [get] +func (o *Oauth) OauthCallback(c *gin.Context) { + state := c.Query("state") + if state == "" { + c.String(http.StatusInternalServerError, "state为空") + return + } + + cacheKey := state + //从缓存中获取 + v := service.AllService.OauthService.GetOauthCache(cacheKey) + if v == nil { + c.String(http.StatusInternalServerError, "授权已过期,请重新授权") + return + } + + ty := v.Op + ac := v.Action + //fmt.Println("ty ac ", ty, ac) + if ty == model.OauthTypeGithub { + code := c.Query("code") + err, userData := service.AllService.OauthService.GithubCallback(code) + if err != nil { + c.String(http.StatusInternalServerError, "授权失败:"+err.Error()) + return + } + if ac == service.OauthActionTypeBind { + //fmt.Println("bind", ty, userData) + utr := service.AllService.OauthService.UserThirdInfo(ty, strconv.Itoa(userData.Id)) + if utr.UserId > 0 { + c.String(http.StatusInternalServerError, "已经绑定其他账号") + return + } + //绑定 + u := service.AllService.UserService.InfoById(v.UserId) + if u == nil { + c.String(http.StatusInternalServerError, "用户不存在") + return + } + //绑定github + err = service.AllService.OauthService.BindGithubUser(strconv.Itoa(userData.Id), userData.Login, v.UserId) + if err != nil { + c.String(http.StatusInternalServerError, "绑定失败") + return + } + c.String(http.StatusOK, "绑定成功") + return + } + //登录 + if ac == service.OauthActionTypeLogin { + if v.UserId != 0 { + c.String(http.StatusInternalServerError, "授权已经成功") + return + } + u := service.AllService.UserService.InfoByGithubId(strconv.Itoa(userData.Id)) + if u == nil { + oa := service.AllService.OauthService.InfoByOp(ty) + if !*oa.AutoRegister { + //c.String(http.StatusInternalServerError, "还未绑定用户,请先绑定") + v.ThirdName = userData.Login + v.ThirdOpenId = strconv.Itoa(userData.Id) + url := global.Config.Rustdesk.ApiServer + "/_admin/#/oauth/bind/" + cacheKey + c.Redirect(http.StatusFound, url) + return + } + + //自动注册 + u = service.AllService.UserService.RegisterByGithub(userData.Login, int64(userData.Id)) + if u.Id == 0 { + c.String(http.StatusInternalServerError, "注册失败") + return + } + } + + v.UserId = u.Id + service.AllService.OauthService.SetOauthCache(cacheKey, v, 0) + c.String(http.StatusOK, "授权成功") + return + } + + //返回js + c.Header("Content-Type", "text/html; charset=utf-8") + c.String(http.StatusOK, "授权错误") + //up := &apiResp.UserPayload{} + //c.JSON(http.StatusOK, apiResp.LoginRes{ + // AccessToken: ut.Token, + // Type: "access_token", + // User: *up.FromUser(u), + //}) + + } + +} + +// WebOauthLogin +// @Tags Oauth +// @Summary WebOauthLogin +// @Description WebOauthLogin +// @Accept json +// @Produce json +// @Success 200 {string} string +// @Failure 500 {string} string +// @Router /oauth/login [get] +func (o *Oauth) WebOauthLogin(c *gin.Context) { + +} diff --git a/http/controller/api/user.go b/http/controller/api/user.go index a8ccc20..b89071f 100644 --- a/http/controller/api/user.go +++ b/http/controller/api/user.go @@ -21,11 +21,11 @@ type User struct { // @Failure 500 {object} response.Response // @Router /currentUser [get] // @Security token -func (u *User) currentUser(c *gin.Context) { - user := service.AllService.UserService.CurUser(c) - up := (&apiResp.UserPayload{}).FromUser(user) - c.JSON(http.StatusOK, up) -} +//func (u *User) currentUser(c *gin.Context) { +// user := service.AllService.UserService.CurUser(c) +// up := (&apiResp.UserPayload{}).FromUser(user) +// c.JSON(http.StatusOK, up) +//} // Info 用户信息 // @Tags 用户 diff --git a/http/controller/api/webClient.go b/http/controller/api/webClient.go index 34c73c0..b9b36c9 100644 --- a/http/controller/api/webClient.go +++ b/http/controller/api/webClient.go @@ -36,7 +36,7 @@ func (i *WebClient) ServerConfig(c *gin.Context) { gin.H{ "id_server": global.Config.Rustdesk.IdServer, "key": global.Config.Rustdesk.Key, - //"peers": peers, + "peers": peers, }, ) } diff --git a/http/controller/web/index.go b/http/controller/web/index.go index 7e549ec..cee6467 100644 --- a/http/controller/web/index.go +++ b/http/controller/web/index.go @@ -53,7 +53,13 @@ const autoWriteServer = () => { } if (res.data.peers) { - localStorage.setItem('peers', JSON.stringify(res.data.peers)) + oldPeers = JSON.parse(localStorage.getItem('peers')) || {} + Object.keys(res.data.peers).forEach(k => { + if(!oldPeers[k]) { + oldPeers[k] = res.data.peers[k] + } + }) + localStorage.setItem('peers', JSON.stringify(oldPeers)) } } }) diff --git a/http/http.go b/http/http.go index 3908339..6104805 100644 --- a/http/http.go +++ b/http/http.go @@ -7,12 +7,23 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "net/http" + "strings" ) func ApiInit() { gin.SetMode(global.Config.Gin.Mode) g := gin.New() + //[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. + //Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details. + if global.Config.Gin.TrustProxy != "" { + pro := strings.Split(global.Config.Gin.TrustProxy, ",") + err := g.SetTrustedProxies(pro) + if err != nil { + panic(err) + } + } + if global.Config.Gin.Mode == gin.ReleaseMode { //修改gin Recovery日志 输出为logger的输出点 if global.Logger != nil { diff --git a/http/middleware/rustauth.go b/http/middleware/rustauth.go index a627968..bc4639d 100644 --- a/http/middleware/rustauth.go +++ b/http/middleware/rustauth.go @@ -17,6 +17,13 @@ func RustAuth() gin.HandlerFunc { c.Abort() return } + if len(token) <= 7 { + c.JSON(401, gin.H{ + "error": "Unauthorized", + }) + c.Abort() + return + } //提取token,格式是Bearer {token} //这里只是简单的提取 token = token[7:] diff --git a/http/request/admin/login.go b/http/request/admin/login.go index 691f7a7..002ef78 100644 --- a/http/request/admin/login.go +++ b/http/request/admin/login.go @@ -3,4 +3,11 @@ package admin type Login struct { Username string `json:"username" validate:"required" label:"用户名"` Password string `json:"password,omitempty" validate:"required" label:"密码"` + Platform string `json:"platform" label:"平台"` +} + +type LoginLogQuery struct { + UserId int `form:"user_id"` + IsMy int `form:"is_my"` + PageQuery } diff --git a/http/request/admin/oauth.go b/http/request/admin/oauth.go new file mode 100644 index 0000000..11698ee --- /dev/null +++ b/http/request/admin/oauth.go @@ -0,0 +1,34 @@ +package admin + +import "Gwen/model" + +type BindOauthForm struct { + Op string `json:"op" binding:"required"` +} + +type OauthConfirmForm struct { + Code string `json:"code" binding:"required"` +} +type UnBindOauthForm struct { + Op string `json:"op" binding:"required"` +} +type OauthForm struct { + Id uint `json:"id"` + Op string `json:"op" validate:"required"` + ClientId string `json:"client_id" validate:"required"` + ClientSecret string `json:"client_secret" validate:"required"` + RedirectUrl string `json:"redirect_url" validate:"required"` + AutoRegister *bool `json:"auto_register"` +} + +func (of *OauthForm) ToOauth() *model.Oauth { + oa := &model.Oauth{ + Op: of.Op, + ClientId: of.ClientId, + ClientSecret: of.ClientSecret, + RedirectUrl: of.RedirectUrl, + AutoRegister: of.AutoRegister, + } + oa.Id = of.Id + return oa +} diff --git a/http/request/api/oauth.go b/http/request/api/oauth.go new file mode 100644 index 0000000..823deb7 --- /dev/null +++ b/http/request/api/oauth.go @@ -0,0 +1,14 @@ +package api + +type OidcAuthRequest struct { + DeviceInfo DeviceInfoInLogin `json:"deviceInfo" label:"设备信息"` + Id string `json:"id" label:"id"` + Op string `json:"op" label:"op"` + Uuid string `json:"uuid" label:"uuid"` +} + +type OidcAuthQuery struct { + Code string `json:"code" form:"code" label:"code"` + Id string `json:"id" form:"id" label:"id"` + Uuid string `json:"uuid" form:"uuid" label:"uuid"` +} diff --git a/http/request/api/user.go b/http/request/api/user.go index 13a0eb4..6327191 100644 --- a/http/request/api/user.go +++ b/http/request/api/user.go @@ -21,9 +21,21 @@ package api bytes hwid = 14; } */ + +type DeviceInfoInLogin struct { + Name string `json:"name" label:"name"` + Os string `json:"os" label:"os"` + Type string `json:"type" label:"type"` +} + type LoginForm struct { - Username string `json:"username" validate:"required,gte=4,lte=10" label:"用户名"` - Password string `json:"password,omitempty" validate:"gte=4,lte=20" label:"密码"` + AutoLogin bool `json:"autoLogin" label:"自动登录"` + DeviceInfo DeviceInfoInLogin `json:"deviceInfo" label:"设备信息"` + Id string `json:"id" label:"id"` + Type string `json:"type" label:"type"` + Uuid string `json:"uuid" label:"uuid"` + Username string `json:"username" validate:"required,gte=4,lte=10" label:"用户名"` + Password string `json:"password,omitempty" validate:"gte=4,lte=20" label:"密码"` } type UserListQuery struct { diff --git a/http/response/admin/user.go b/http/response/admin/user.go index 27e92a9..488ebe9 100644 --- a/http/response/admin/user.go +++ b/http/response/admin/user.go @@ -8,6 +8,11 @@ type LoginPayload struct { } var UserRouteNames = []string{ - "MyTagList", "MyAddressBookList", + "MyTagList", "MyAddressBookList", "MyInfo", } var AdminRouteNames = []string{"*"} + +type UserOauthItem struct { + ThirdType string `json:"third_type"` + Status int `json:"status"` +} diff --git a/http/response/api/user.go b/http/response/api/user.go index dcea9b7..b48a4be 100644 --- a/http/response/api/user.go +++ b/http/response/api/user.go @@ -19,17 +19,19 @@ UserStatus status; bool isAdmin = false; */ type UserPayload struct { - Name string `json:"name"` - Email string `json:"email"` - Note string `json:"note"` - IsAdmin *bool `json:"is_admin"` - Status int `json:"status"` + Name string `json:"name"` + Email string `json:"email"` + Note string `json:"note"` + IsAdmin *bool `json:"is_admin"` + Status int `json:"status"` + Info map[string]interface{} `json:"info"` } func (up *UserPayload) FromUser(user *model.User) *UserPayload { up.Name = user.Username up.IsAdmin = user.IsAdmin up.Status = int(user.Status) + up.Info = map[string]interface{}{} return up } @@ -50,6 +52,6 @@ type LoginRes struct { Type string `json:"type"` AccessToken string `json:"access_token"` User UserPayload `json:"user"` - Secret string `json:"secret"` - TfaType string `json:"tfa_type"` + Secret string `json:"secret,omitempty"` + TfaType string `json:"tfa_type,omitempty"` } diff --git a/http/response/api/webClient.go b/http/response/api/webClient.go index 9245e91..39a4575 100644 --- a/http/response/api/webClient.go +++ b/http/response/api/webClient.go @@ -5,33 +5,6 @@ import ( "time" ) -// type T struct { -// Field1 struct { -// ViewStyle string `json:"view-style"` -// Tm int64 `json:"tm"` -// Info struct { -// Username string `json:"username"` -// Hostname string `json:"hostname"` -// Platform string `json:"platform"` -// Displays []struct { -// X int `json:"x"` -// Y int `json:"y"` -// Width int `json:"width"` -// Height int `json:"height"` -// Name string `json:"name"` -// Online bool `json:"online"` -// } `json:"displays"` -// CurrentDisplay int `json:"current_display"` -// SasEnabled bool `json:"sas_enabled"` -// Version string `json:"version"` -// ConnId int `json:"conn_id"` -// Features struct { -// PrivacyMode bool `json:"privacy_mode"` -// } `json:"features"` -// } `json:"info"` -// } `json:"1799928825"` -// } - type WebClientPeerPayload struct { ViewStyle string `json:"view-style"` Tm int64 `json:"tm"` @@ -46,7 +19,8 @@ type WebClientPeerInfoPayload struct { func (wcpp *WebClientPeerPayload) FromAddressBook(a *model.AddressBook) { wcpp.ViewStyle = "shrink" - wcpp.Tm = time.Now().UnixNano() + //24小时前 + wcpp.Tm = time.Now().Add(-time.Hour * 24).UnixNano() wcpp.Info = WebClientPeerInfoPayload{ Username: a.Username, Hostname: a.Hostname, diff --git a/http/router/admin.go b/http/router/admin.go index df93210..ea89e39 100644 --- a/http/router/admin.go +++ b/http/router/admin.go @@ -25,6 +25,8 @@ func Init(g *gin.Engine) { TagBind(adg) AddressBookBind(adg) PeerBind(adg) + OauthBind(adg) + LoginLogBind(adg) rs := &admin.Rustdesk{} adg.GET("/server-config", rs.ServerConfig) @@ -44,6 +46,7 @@ func UserBind(rg *gin.RouterGroup) { cont := &admin.User{} aR.GET("/current", cont.Current) aR.POST("/changeCurPwd", cont.ChangeCurPwd) + aR.POST("/myOauth", cont.MyOauth) } aRP := rg.Group("/user").Use(middleware.AdminPrivilege()) { @@ -104,6 +107,35 @@ func PeerBind(rg *gin.RouterGroup) { } } +func OauthBind(rg *gin.RouterGroup) { + aR := rg.Group("/oauth") + { + cont := &admin.Oauth{} + aR.POST("/confirm", cont.Confirm) + aR.POST("/bind", cont.ToBind) + aR.POST("/bindConfirm", cont.BindConfirm) + aR.POST("/unbind", cont.Unbind) + aR.GET("/info", cont.Info) + } + arp := aR.Use(middleware.AdminPrivilege()) + { + cont := &admin.Oauth{} + arp.GET("/list", cont.List) + arp.GET("/detail/:id", cont.Detail) + arp.POST("/create", cont.Create) + arp.POST("/update", cont.Update) + arp.POST("/delete", cont.Delete) + + } + +} +func LoginLogBind(rg *gin.RouterGroup) { + aR := rg.Group("/login_log") + cont := &admin.LoginLog{} + aR.GET("/list", cont.List) + aR.POST("/delete", cont.Delete) +} + /* func FileBind(rg *gin.RouterGroup) { aR := rg.Group("/file") diff --git a/http/router/api.go b/http/router/api.go index aa4695f..1341f47 100644 --- a/http/router/api.go +++ b/http/router/api.go @@ -19,7 +19,7 @@ func ApiInit(g *gin.Engine) { frg := g.Group("/api") - frg.Use(middleware.Cors()) + //frg.Use(middleware.Cors()) frg.OPTIONS("/*any", nil) i := &api.Index{} @@ -34,6 +34,16 @@ func ApiInit(g *gin.Engine) { frg.POST("/login", l.Login) } + { + o := &api.Oauth{} + // [method:POST] [uri:/api/oidc/auth] + frg.POST("/oidc/auth", o.OidcAuth) + // [method:GET] [uri:/api/oidc/auth-query?code=abc&id=xxxxx&uuid=xxxxx] + frg.GET("/oidc/auth-query", o.OidcAuthQuery) + //api/oauth/callback + frg.GET("/oauth/callback", o.OauthCallback) + frg.GET("/oauth/login", o.OauthCallback) + } { pe := &api.Peer{} //提交系统信息 diff --git a/model/loginLog.go b/model/loginLog.go new file mode 100644 index 0000000..8405c2f --- /dev/null +++ b/model/loginLog.go @@ -0,0 +1,23 @@ +package model + +type LoginLog struct { + IdModel + UserId uint `json:"user_id"` + Client string `json:"client"` //webadmin,webclient,app, + Uuid string `json:"uuid"` + Ip string `json:"ip"` + Type string `json:"type"` //account,oauth + Platform string `json:"platform"` //windows,linux,mac,android,ios + + TimeModel +} + +const ( + LoginLogTypeAccount = "account" + LoginLogTypeOauth = "oauth" +) + +type LoginLogList struct { + LoginLogs []*LoginLog `json:"list"` + Pagination +} diff --git a/model/oauth.go b/model/oauth.go new file mode 100644 index 0000000..64de80c --- /dev/null +++ b/model/oauth.go @@ -0,0 +1,22 @@ +package model + +type Oauth struct { + IdModel + Op string `json:"op"` + ClientId string `json:"client_id"` + ClientSecret string `json:"client_secret"` + RedirectUrl string `json:"redirect_url"` + AutoRegister *bool `json:"auto_register"` + TimeModel +} + +const ( + OauthTypeGithub = "github" + OauthTypeGoogle = "google" + OauthTypeWebauth = "webauth" +) + +type OauthList struct { + Oauths []*Oauth `json:"list"` + Pagination +} diff --git a/model/userThird.go b/model/userThird.go new file mode 100644 index 0000000..4e967b9 --- /dev/null +++ b/model/userThird.go @@ -0,0 +1,12 @@ +package model + +type UserThird struct { + IdModel + UserId uint `json:"user_id" gorm:"not null;index"` + OpenId string `json:"open_id" gorm:"not null;index"` + UnionId string `json:"union_id" gorm:"not null;"` + ThirdType string `json:"third_type" gorm:"not null;"` + ThirdEmail string `json:"third_email"` + ThirdName string `json:"third_name"` + TimeModel +} diff --git a/service/loginLog.go b/service/loginLog.go new file mode 100644 index 0000000..96ec23b --- /dev/null +++ b/service/loginLog.go @@ -0,0 +1,45 @@ +package service + +import ( + "Gwen/global" + "Gwen/model" + "gorm.io/gorm" +) + +type LoginLogService struct { +} + +// InfoById 根据用户id取用户信息 +func (us *LoginLogService) InfoById(id uint) *model.LoginLog { + u := &model.LoginLog{} + global.DB.Where("id = ?", id).First(u) + return u +} + +func (us *LoginLogService) List(page, pageSize uint, where func(tx *gorm.DB)) (res *model.LoginLogList) { + res = &model.LoginLogList{} + res.Page = int64(page) + res.PageSize = int64(pageSize) + tx := global.DB.Model(&model.LoginLog{}) + if where != nil { + where(tx) + } + tx.Count(&res.Total) + tx.Scopes(Paginate(page, pageSize)) + tx.Find(&res.LoginLogs) + return +} + +// Create 创建 +func (us *LoginLogService) Create(u *model.LoginLog) error { + res := global.DB.Create(u).Error + return res +} +func (us *LoginLogService) Delete(u *model.LoginLog) error { + return global.DB.Delete(u).Error +} + +// Update 更新 +func (us *LoginLogService) Update(u *model.LoginLog) error { + return global.DB.Model(u).Updates(u).Error +} diff --git a/service/oauth.go b/service/oauth.go new file mode 100644 index 0000000..19f4352 --- /dev/null +++ b/service/oauth.go @@ -0,0 +1,256 @@ +package service + +import ( + "Gwen/global" + "Gwen/model" + "Gwen/utils" + "context" + "encoding/json" + "errors" + "fmt" + "golang.org/x/oauth2" + "golang.org/x/oauth2/github" + "golang.org/x/oauth2/google" + "gorm.io/gorm" + "io" + "strconv" + "sync" + "time" +) + +type OauthService struct { +} + +type GithubUserdata struct { + AvatarUrl string `json:"avatar_url"` + Bio string `json:"bio"` + Blog string `json:"blog"` + Collaborators int `json:"collaborators"` + Company interface{} `json:"company"` + CreatedAt time.Time `json:"created_at"` + DiskUsage int `json:"disk_usage"` + Email interface{} `json:"email"` + EventsUrl string `json:"events_url"` + Followers int `json:"followers"` + FollowersUrl string `json:"followers_url"` + Following int `json:"following"` + FollowingUrl string `json:"following_url"` + GistsUrl string `json:"gists_url"` + GravatarId string `json:"gravatar_id"` + Hireable interface{} `json:"hireable"` + HtmlUrl string `json:"html_url"` + Id int `json:"id"` + Location interface{} `json:"location"` + Login string `json:"login"` + Name string `json:"name"` + NodeId string `json:"node_id"` + NotificationEmail interface{} `json:"notification_email"` + OrganizationsUrl string `json:"organizations_url"` + OwnedPrivateRepos int `json:"owned_private_repos"` + Plan struct { + Collaborators int `json:"collaborators"` + Name string `json:"name"` + PrivateRepos int `json:"private_repos"` + Space int `json:"space"` + } `json:"plan"` + PrivateGists int `json:"private_gists"` + PublicGists int `json:"public_gists"` + PublicRepos int `json:"public_repos"` + ReceivedEventsUrl string `json:"received_events_url"` + ReposUrl string `json:"repos_url"` + SiteAdmin bool `json:"site_admin"` + StarredUrl string `json:"starred_url"` + SubscriptionsUrl string `json:"subscriptions_url"` + TotalPrivateRepos int `json:"total_private_repos"` + //TwitterUsername interface{} `json:"twitter_username"` + TwoFactorAuthentication bool `json:"two_factor_authentication"` + Type string `json:"type"` + UpdatedAt time.Time `json:"updated_at"` + Url string `json:"url"` +} + +type OauthCacheItem struct { + UserId uint `json:"user_id"` + Id string `json:"id"` //rustdesk的设备ID + Op string `json:"op"` + Action string `json:"action"` + Uuid string `json:"uuid"` + DeviceName string `json:"device_name"` + DeviceOs string `json:"device_os"` + DeviceType string `json:"device_type"` + ThirdOpenId string `json:"third_open_id"` + ThirdName string `json:"third_name"` + ThirdEmail string `json:"third_email"` +} + +var OauthCache = &sync.Map{} + +const ( + OauthActionTypeLogin = "login" + OauthActionTypeBind = "bind" +) + +func (os *OauthService) GetOauthCache(key string) *OauthCacheItem { + v, ok := OauthCache.Load(key) + if !ok { + return nil + } + return v.(*OauthCacheItem) +} + +func (os *OauthService) SetOauthCache(key string, item *OauthCacheItem, expire uint) { + OauthCache.Store(key, item) + if expire > 0 { + go func() { + time.Sleep(time.Duration(expire) * time.Second) + os.DeleteOauthCache(key) + }() + } +} + +func (os *OauthService) DeleteOauthCache(key string) { + OauthCache.Delete(key) +} + +func (os *OauthService) BeginAuth(op string) (error error, code, url string) { + code = utils.RandomString(10) + strconv.FormatInt(time.Now().Unix(), 10) + + if op == model.OauthTypeWebauth { + url = global.Config.Rustdesk.ApiServer + "/_admin/#/oauth/" + code + //url = "http://localhost:8888/_admin/#/oauth/" + code + return nil, code, url + } + err, conf := os.GetOauthConfig(op) + if err == nil { + return err, code, conf.AuthCodeURL(code) + } + + return errors.New("op错误"), code, "" +} + +// GetOauthConfig 获取配置 +func (os *OauthService) GetOauthConfig(op string) (error, *oauth2.Config) { + if op == model.OauthTypeGithub { + g := os.InfoByOp(model.OauthTypeGithub) + if g.Id == 0 || g.ClientId == "" || g.ClientSecret == "" || g.RedirectUrl == "" { + return errors.New("配置不存在"), nil + } + return nil, &oauth2.Config{ + ClientID: g.ClientId, + ClientSecret: g.ClientSecret, + RedirectURL: g.RedirectUrl, + Endpoint: github.Endpoint, + Scopes: []string{"read:user", "user:email"}, + } + } + if op == model.OauthTypeGoogle { + g := os.InfoByOp(model.OauthTypeGoogle) + if g.Id == 0 || g.ClientId == "" || g.ClientSecret == "" || g.RedirectUrl == "" { + return errors.New("配置不存在"), nil + } + return nil, &oauth2.Config{ + ClientID: g.ClientId, + ClientSecret: g.ClientSecret, + RedirectURL: g.RedirectUrl, + Endpoint: google.Endpoint, + Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email"}, + } + } + return errors.New("op错误"), nil +} + +func (os *OauthService) GithubCallback(code string) (error error, userData *GithubUserdata) { + err, oauthConfig := os.GetOauthConfig(model.OauthTypeGithub) + if err != nil { + return err, nil + } + token, err := oauthConfig.Exchange(context.Background(), code) + if err != nil { + global.Logger.Warn(fmt.Printf("oauthConfig.Exchange() failed: %s\n", err)) + error = errors.New("获取token失败") + return + } + + // 创建一个 HTTP 客户端,并将 access_token 添加到 Authorization 头中 + client := oauthConfig.Client(context.Background(), token) + resp, err := client.Get("https://api.github.com/user") + if err != nil { + global.Logger.Warn("failed getting user info: %s\n", err) + error = errors.New("获取user info失败") + return + } + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + global.Logger.Warn("failed closing response body: %s\n", err) + } + }(resp.Body) + + // 在这里处理 GitHub 用户信息 + if err := json.NewDecoder(resp.Body).Decode(&userData); err != nil { + global.Logger.Warn("failed decoding user info: %s\n", err) + error = errors.New("解析user info失败") + return + } + return +} + +func (os *OauthService) UserThirdInfo(op, openid string) *model.UserThird { + ut := &model.UserThird{} + global.DB.Where("open_id = ? and third_type = ?", openid, op).First(ut) + return ut +} + +func (os *OauthService) BindGithubUser(openid, username string, userId uint) error { + utr := &model.UserThird{ + OpenId: openid, + ThirdType: model.OauthTypeGithub, + ThirdName: username, + UserId: userId, + } + return global.DB.Create(utr).Error +} +func (os *OauthService) UnBindGithubUser(userid uint) error { + return global.DB.Where("user_id = ? and third_type = ?", userid, model.OauthTypeGithub).Delete(&model.UserThird{}).Error +} + +// InfoById 根据id取用户信息 +func (os *OauthService) InfoById(id uint) *model.Oauth { + u := &model.Oauth{} + global.DB.Where("id = ?", id).First(u) + return u +} + +// InfoByOp 根据op取用户信息 +func (os *OauthService) InfoByOp(op string) *model.Oauth { + u := &model.Oauth{} + global.DB.Where("op = ?", op).First(u) + return u +} +func (os *OauthService) List(page, pageSize uint, where func(tx *gorm.DB)) (res *model.OauthList) { + res = &model.OauthList{} + res.Page = int64(page) + res.PageSize = int64(pageSize) + tx := global.DB.Model(&model.Oauth{}) + if where != nil { + where(tx) + } + tx.Count(&res.Total) + tx.Scopes(Paginate(page, pageSize)) + tx.Find(&res.Oauths) + return +} + +// Create 创建 +func (os *OauthService) Create(u *model.Oauth) error { + res := global.DB.Create(u).Error + return res +} +func (os *OauthService) Delete(u *model.Oauth) error { + return global.DB.Delete(u).Error +} + +// Update 更新 +func (os *OauthService) Update(u *model.Oauth) error { + return global.DB.Model(u).Updates(u).Error +} diff --git a/service/service.go b/service/service.go index a8a4f03..c25388d 100644 --- a/service/service.go +++ b/service/service.go @@ -13,6 +13,8 @@ type Service struct { *TagService *PeerService *GroupService + *OauthService + *LoginLogService } func New() *Service { diff --git a/service/user.go b/service/user.go index 9b36b40..aeff619 100644 --- a/service/user.go +++ b/service/user.go @@ -7,6 +7,8 @@ import ( "Gwen/utils" "github.com/gin-gonic/gin" "gorm.io/gorm" + "math/rand" + "strconv" "time" ) @@ -51,11 +53,11 @@ func (us *UserService) InfoByAccessToken(token string) *model.User { // GenerateToken 生成token func (us *UserService) GenerateToken(u *model.User) string { - return utils.Md5(u.Username + u.Password + time.Now().String()) + return utils.Md5(u.Username + time.Now().String()) } // Login 登录 -func (us *UserService) Login(u *model.User) *model.UserToken { +func (us *UserService) Login(u *model.User, llog *model.LoginLog) *model.UserToken { token := us.GenerateToken(u) ut := &model.UserToken{ UserId: u.Id, @@ -63,6 +65,7 @@ func (us *UserService) Login(u *model.User) *model.UserToken { ExpiredAt: time.Now().Add(time.Hour * 24 * 7).Unix(), } global.DB.Create(ut) + global.DB.Create(llog) return ut } @@ -169,3 +172,70 @@ func (us *UserService) RouteNames(u *model.User) []string { } return adResp.UserRouteNames } + +// InfoByGithubId 根据githubid取用户信息 +func (us *UserService) InfoByGithubId(githubId string) *model.User { + ut := AllService.OauthService.UserThirdInfo(model.OauthTypeGithub, githubId) + if ut.Id == 0 { + return nil + } + u := us.InfoById(ut.UserId) + if u.Id == 0 { + return nil + } + return u +} + +// RegisterByGithub 注册 +func (us *UserService) RegisterByGithub(githubName string, githubId int64) *model.User { + tx := global.DB.Begin() + ut := &model.UserThird{ + OpenId: strconv.FormatInt(githubId, 10), + ThirdName: githubName, + ThirdType: model.OauthTypeGithub, + } + //global.DB.Where("open_id = ?", githubId).First(ut) + //这种情况不应该出现,如果出现说明有bug + //if ut.Id != 0 { + // u := &model.User{} + // global.DB.Where("id = ?", ut.UserId).First(u) + // tx.Commit() + // return u + //} + + username := us.GenerateUsernameByOauth(githubName) + u := &model.User{ + Username: username, + GroupId: 1, + } + global.DB.Create(u) + + ut.UserId = u.Id + global.DB.Create(ut) + + tx.Commit() + return u +} + +// GenerateUsernameByOauth 生成用户名 +func (us *UserService) GenerateUsernameByOauth(name string) string { + u := &model.User{} + global.DB.Where("username = ?", name).First(u) + if u.Id == 0 { + return name + } + name = name + strconv.FormatInt(rand.Int63n(10), 10) + return us.GenerateUsernameByOauth(name) +} + +// UserThirdsByUserId +func (us *UserService) UserThirdsByUserId(userId uint) (res []*model.UserThird) { + global.DB.Where("user_id = ?", userId).Find(&res) + return res +} + +func (us *UserService) UserThirdInfo(userId uint, op string) *model.UserThird { + ut := &model.UserThird{} + global.DB.Where("user_id = ? and third_type = ?", userId, op).First(ut) + return ut +} diff --git a/utils/tools.go b/utils/tools.go index c58e275..fcb69ba 100644 --- a/utils/tools.go +++ b/utils/tools.go @@ -4,6 +4,7 @@ import ( "crypto/md5" "encoding/json" "fmt" + "math/rand" "reflect" "runtime/debug" ) @@ -61,3 +62,14 @@ func SafeGo(f interface{}, params ...interface{}) { funcValue.Call(paramsValue) }() } + +// RandomString 生成随机字符串 +func RandomString(n int) string { + const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + length := len(letterBytes) + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Intn(length)] + } + return string(b) +}