Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2948eaaa5c | ||
|
|
8641ba5c0c | ||
|
|
60b7a18fe7 | ||
|
|
ca068816ae | ||
|
|
06648d9a6c | ||
|
|
8a8abd5163 |
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@@ -66,7 +66,7 @@ jobs:
|
||||
- name: Set up Go environment
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.22' # 选择 Go 版本
|
||||
go-version: '1.23' # 选择 Go 版本
|
||||
|
||||
- name: Set up npm
|
||||
uses: actions/setup-node@v2
|
||||
@@ -147,6 +147,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Generate Changelog
|
||||
if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push'
|
||||
run: npx changelogithub # or changelogithub@0.12 if ensure the stable result
|
||||
env:
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
|
||||
2
.github/workflows/build_test.yml
vendored
2
.github/workflows/build_test.yml
vendored
@@ -61,7 +61,7 @@ jobs:
|
||||
- name: Set up Go environment
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.22' # 选择 Go 版本
|
||||
go-version: '1.23' # 选择 Go 版本
|
||||
|
||||
- name: Set up npm
|
||||
uses: actions/setup-node@v2
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/lejianwen/rustdesk-api/v2/config"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
@@ -140,18 +141,40 @@ func InitGlobal() {
|
||||
}
|
||||
//gorm
|
||||
if global.Config.Gorm.Type == config.TypeMysql {
|
||||
dns := global.Config.Mysql.Username + ":" + global.Config.Mysql.Password + "@(" + global.Config.Mysql.Addr + ")/" + global.Config.Mysql.Dbname + "?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
|
||||
dsn := fmt.Sprintf("%s:%s@(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
|
||||
global.Config.Mysql.Username,
|
||||
global.Config.Mysql.Password,
|
||||
global.Config.Mysql.Addr,
|
||||
global.Config.Mysql.Dbname,
|
||||
)
|
||||
|
||||
global.DB = orm.NewMysql(&orm.MysqlConfig{
|
||||
Dns: dns,
|
||||
Dsn: dsn,
|
||||
MaxIdleConns: global.Config.Gorm.MaxIdleConns,
|
||||
MaxOpenConns: global.Config.Gorm.MaxOpenConns,
|
||||
})
|
||||
}, global.Logger)
|
||||
} else if global.Config.Gorm.Type == config.TypePostgresql {
|
||||
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s TimeZone=%s",
|
||||
global.Config.Postgresql.Host,
|
||||
global.Config.Postgresql.Port,
|
||||
global.Config.Postgresql.User,
|
||||
global.Config.Postgresql.Password,
|
||||
global.Config.Postgresql.Dbname,
|
||||
global.Config.Postgresql.Sslmode,
|
||||
global.Config.Postgresql.TimeZone,
|
||||
)
|
||||
global.DB = orm.NewPostgresql(&orm.PostgresqlConfig{
|
||||
Dsn: dsn,
|
||||
MaxIdleConns: global.Config.Gorm.MaxIdleConns,
|
||||
MaxOpenConns: global.Config.Gorm.MaxOpenConns,
|
||||
}, global.Logger)
|
||||
} else {
|
||||
//sqlite
|
||||
global.DB = orm.NewSqlite(&orm.SqliteConfig{
|
||||
MaxIdleConns: global.Config.Gorm.MaxIdleConns,
|
||||
MaxOpenConns: global.Config.Gorm.MaxOpenConns,
|
||||
})
|
||||
}, global.Logger)
|
||||
}
|
||||
|
||||
//validator
|
||||
@@ -197,11 +220,17 @@ func DatabaseAutoUpdate() {
|
||||
if dbName == "" {
|
||||
dbName = global.Config.Mysql.Dbname
|
||||
// 移除 DSN 中的数据库名称,以便初始连接时不指定数据库
|
||||
dsnWithoutDB := global.Config.Mysql.Username + ":" + global.Config.Mysql.Password + "@(" + global.Config.Mysql.Addr + ")/?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
dsnWithoutDB := fmt.Sprintf("%s:%s@(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
|
||||
global.Config.Mysql.Username,
|
||||
global.Config.Mysql.Password,
|
||||
global.Config.Mysql.Addr,
|
||||
"",
|
||||
)
|
||||
|
||||
//新链接
|
||||
dbWithoutDB := orm.NewMysql(&orm.MysqlConfig{
|
||||
Dns: dsnWithoutDB,
|
||||
})
|
||||
Dsn: dsnWithoutDB,
|
||||
}, global.Logger)
|
||||
// 获取底层的 *sql.DB 对象,并确保在程序退出时关闭连接
|
||||
sqlDBWithoutDB, err := dbWithoutDB.DB()
|
||||
if err != nil {
|
||||
|
||||
@@ -11,7 +11,7 @@ app:
|
||||
disable-pwd-login: false #禁用密码登录
|
||||
|
||||
admin:
|
||||
title: "RustDesk Api Admin"
|
||||
title: "RustDesk API Admin"
|
||||
hello-file: "./conf/admin/hello.html" #优先使用file
|
||||
hello: ""
|
||||
# ID Server and Relay Server ports https://github.com/lejianwen/rustdesk-api/issues/257
|
||||
@@ -31,6 +31,16 @@ mysql:
|
||||
password: ""
|
||||
addr: ""
|
||||
dbname: ""
|
||||
|
||||
postgresql:
|
||||
host: "127.0.0.1"
|
||||
port: "5432"
|
||||
user: ""
|
||||
password: ""
|
||||
dbname: "postgres"
|
||||
sslmode: "disable" # disable, require, verify-ca, verify-full
|
||||
time-zone: "Asia/Shanghai" # Time zone for PostgreSQL connection
|
||||
|
||||
rustdesk:
|
||||
id-server: "192.168.1.66:21116"
|
||||
relay-server: "192.168.1.66:21117"
|
||||
|
||||
@@ -32,20 +32,21 @@ type Admin struct {
|
||||
RelayServerPort int `mapstructure:"relay-server-port"`
|
||||
}
|
||||
type Config struct {
|
||||
Lang string `mapstructure:"lang"`
|
||||
App App
|
||||
Admin Admin
|
||||
Gorm Gorm
|
||||
Mysql Mysql
|
||||
Gin Gin
|
||||
Logger Logger
|
||||
Redis Redis
|
||||
Cache Cache
|
||||
Oss Oss
|
||||
Jwt Jwt
|
||||
Rustdesk Rustdesk
|
||||
Proxy Proxy
|
||||
Ldap Ldap
|
||||
Lang string `mapstructure:"lang"`
|
||||
App App
|
||||
Admin Admin
|
||||
Gorm Gorm
|
||||
Mysql Mysql
|
||||
Postgresql Postgresql
|
||||
Gin Gin
|
||||
Logger Logger
|
||||
Redis Redis
|
||||
Cache Cache
|
||||
Oss Oss
|
||||
Jwt Jwt
|
||||
Rustdesk Rustdesk
|
||||
Proxy Proxy
|
||||
Ldap Ldap
|
||||
}
|
||||
|
||||
func (a *Admin) Init() {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package config
|
||||
|
||||
const (
|
||||
TypeSqlite = "sqlite"
|
||||
TypeMysql = "mysql"
|
||||
TypeSqlite = "sqlite"
|
||||
TypeMysql = "mysql"
|
||||
TypePostgresql = "postgresql"
|
||||
)
|
||||
|
||||
type Gorm struct {
|
||||
@@ -17,3 +18,13 @@ type Mysql struct {
|
||||
Password string `mapstructure:"password"`
|
||||
Dbname string `mapstructure:"dbname"`
|
||||
}
|
||||
|
||||
type Postgresql struct {
|
||||
Host string `mapstructure:"host"`
|
||||
Port string `mapstructure:"port"`
|
||||
User string `mapstructure:"user"`
|
||||
Password string `mapstructure:"password"`
|
||||
Dbname string `mapstructure:"dbname"`
|
||||
Sslmode string `mapstructure:"sslmode"` // "disable", "require", "verify-ca", "verify-full"
|
||||
TimeZone string `mapstructure:"time-zone"` // e.g., "Asia/Shanghai"
|
||||
}
|
||||
|
||||
@@ -18,3 +18,9 @@ type OidcOauth struct {
|
||||
ClientSecret string `mapstructure:"client-secret"`
|
||||
RedirectUrl string `mapstructure:"redirect-url"`
|
||||
}
|
||||
|
||||
type LinuxdoOauth struct {
|
||||
ClientId string `mapstructure:"client-id"`
|
||||
ClientSecret string `mapstructure:"client-secret"`
|
||||
RedirectUrl string `mapstructure:"redirect-url"`
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package admin Content generated by swaggo/swag. DO NOT EDIT
|
||||
// Package admin Code generated by swaggo/swag. DO NOT EDIT
|
||||
package admin
|
||||
|
||||
import "github.com/swaggo/swag"
|
||||
@@ -5828,6 +5828,9 @@ const docTemplateadmin = `{
|
||||
"captcha": {
|
||||
"type": "string"
|
||||
},
|
||||
"captcha_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -5821,6 +5821,9 @@
|
||||
"captcha": {
|
||||
"type": "string"
|
||||
},
|
||||
"captcha_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -297,6 +297,8 @@ definitions:
|
||||
properties:
|
||||
captcha:
|
||||
type: string
|
||||
captcha_id:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
platform:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package api Content generated by swaggo/swag. DO NOT EDIT
|
||||
// Package api Code generated by swaggo/swag. DO NOT EDIT
|
||||
package api
|
||||
|
||||
import "github.com/swaggo/swag"
|
||||
@@ -1208,7 +1208,7 @@ const docTemplateapi = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址"
|
||||
"System"
|
||||
],
|
||||
"summary": "提交系统信息",
|
||||
"parameters": [
|
||||
@@ -1238,6 +1238,35 @@ const docTemplateapi = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/sysinfo_ver": {
|
||||
"post": {
|
||||
"description": "获取系统版本信息",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"System"
|
||||
],
|
||||
"summary": "获取系统版本信息",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
||||
@@ -1201,7 +1201,7 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址"
|
||||
"System"
|
||||
],
|
||||
"summary": "提交系统信息",
|
||||
"parameters": [
|
||||
@@ -1231,6 +1231,35 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/sysinfo_ver": {
|
||||
"post": {
|
||||
"description": "获取系统版本信息",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"System"
|
||||
],
|
||||
"summary": "获取系统版本信息",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
||||
@@ -973,7 +973,26 @@ paths:
|
||||
$ref: '#/definitions/response.ErrorResponse'
|
||||
summary: 提交系统信息
|
||||
tags:
|
||||
- 地址
|
||||
- System
|
||||
/sysinfo_ver:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 获取系统版本信息
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.ErrorResponse'
|
||||
summary: 获取系统版本信息
|
||||
tags:
|
||||
- System
|
||||
/users:
|
||||
get:
|
||||
consumes:
|
||||
|
||||
23
go.mod
23
go.mod
@@ -1,19 +1,23 @@
|
||||
module github.com/lejianwen/rustdesk-api/v2
|
||||
|
||||
go 1.22
|
||||
go 1.23
|
||||
|
||||
toolchain go1.23.10
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.3.2
|
||||
github.com/antonfisher/nested-logrus-formatter v1.3.1
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
github.com/coreos/go-oidc/v3 v3.12.0
|
||||
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
|
||||
github.com/gin-gonic/gin v1.9.0
|
||||
github.com/go-ldap/ldap/v3 v3.4.10
|
||||
github.com/go-playground/locales v0.14.1
|
||||
github.com/go-playground/universal-translator v0.18.1
|
||||
github.com/go-playground/validator/v10 v10.26.0
|
||||
github.com/go-redis/redis/v8 v8.11.4
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/mojocn/base64Captcha v1.3.6
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/cobra v1.8.1
|
||||
@@ -24,8 +28,9 @@ require (
|
||||
golang.org/x/oauth2 v0.23.0
|
||||
golang.org/x/text v0.22.0
|
||||
gorm.io/driver/mysql v1.5.7
|
||||
gorm.io/driver/postgres v1.6.0
|
||||
gorm.io/driver/sqlite v1.5.6
|
||||
gorm.io/gorm v1.25.7
|
||||
gorm.io/gorm v1.25.10
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -36,13 +41,12 @@ require (
|
||||
github.com/bytedance/sonic v1.8.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/coreos/go-oidc/v3 v3.12.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
|
||||
github.com/go-ldap/ldap/v3 v3.4.10 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/spec v0.20.4 // indirect
|
||||
@@ -52,6 +56,10 @@ require (
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v5 v5.6.0 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
@@ -65,9 +73,9 @@ require (
|
||||
github.com/mitchellh/mapstructure v1.4.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mojocn/base64Captcha v1.3.6 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
@@ -79,8 +87,9 @@ require (
|
||||
golang.org/x/crypto v0.33.0 // indirect
|
||||
golang.org/x/image v0.13.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
golang.org/x/tools v0.26.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/ini.v1 v1.63.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
@@ -78,11 +78,13 @@ func (co *Config) AdminConfig(c *gin.Context) {
|
||||
}
|
||||
|
||||
hello := global.Config.Admin.Hello
|
||||
helloFile := global.Config.Admin.HelloFile
|
||||
if helloFile != "" {
|
||||
b, err := os.ReadFile(helloFile)
|
||||
if err == nil && len(b) > 0 {
|
||||
hello = string(b)
|
||||
if hello == "" {
|
||||
helloFile := global.Config.Admin.HelloFile
|
||||
if helloFile != "" {
|
||||
b, err := os.ReadFile(helloFile)
|
||||
if err == nil && len(b) > 0 {
|
||||
hello = string(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
requstform "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||
@@ -13,7 +14,7 @@ type Peer struct {
|
||||
}
|
||||
|
||||
// SysInfo
|
||||
// @Tags 地址
|
||||
// @Tags System
|
||||
// @Summary 提交系统信息
|
||||
// @Description 提交系统信息
|
||||
// @Accept json
|
||||
@@ -57,8 +58,19 @@ func (p *Peer) SysInfo(c *gin.Context) {
|
||||
c.String(http.StatusOK, "SYSINFO_UPDATED")
|
||||
}
|
||||
|
||||
// SysInfoVer
|
||||
// @Tags System
|
||||
// @Summary 获取系统版本信息
|
||||
// @Description 获取系统版本信息
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {string} string ""
|
||||
// @Failure 500 {object} response.ErrorResponse
|
||||
// @Router /sysinfo_ver [post]
|
||||
func (p *Peer) SysInfoVer(c *gin.Context) {
|
||||
//读取resources/version文件
|
||||
v := service.AllService.AppService.GetAppVersion()
|
||||
// 加上启动时间,方便client上传信息
|
||||
v = fmt.Sprintf("%s\n%s", v, service.AllService.AppService.GetStartTime())
|
||||
c.String(http.StatusOK, v)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package orm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
@@ -10,14 +9,14 @@ import (
|
||||
)
|
||||
|
||||
type MysqlConfig struct {
|
||||
Dns string
|
||||
Dsn string
|
||||
MaxIdleConns int
|
||||
MaxOpenConns int
|
||||
}
|
||||
|
||||
func NewMysql(mysqlConf *MysqlConfig) *gorm.DB {
|
||||
func NewMysql(mysqlConf *MysqlConfig, logwriter logger.Writer) *gorm.DB {
|
||||
db, err := gorm.Open(mysql.New(mysql.Config{
|
||||
DSN: mysqlConf.Dns, // DSN data source name
|
||||
DSN: mysqlConf.Dsn, // DSN data source name
|
||||
DefaultStringSize: 256, // string 类型字段的默认长度
|
||||
//DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
|
||||
//DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
|
||||
@@ -26,7 +25,7 @@ func NewMysql(mysqlConf *MysqlConfig) *gorm.DB {
|
||||
}), &gorm.Config{
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
Logger: logger.New(
|
||||
global.Logger, // io writer
|
||||
logwriter, // io writer
|
||||
logger.Config{
|
||||
SlowThreshold: time.Second, // Slow SQL threshold
|
||||
LogLevel: logger.Warn, // Log level
|
||||
|
||||
45
lib/orm/postgresql.go
Normal file
45
lib/orm/postgresql.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PostgresqlConfig struct {
|
||||
Dsn string
|
||||
MaxIdleConns int
|
||||
MaxOpenConns int
|
||||
}
|
||||
|
||||
func NewPostgresql(conf *PostgresqlConfig, logwriter logger.Writer) *gorm.DB {
|
||||
db, err := gorm.Open(postgres.Open(conf.Dsn), &gorm.Config{
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
Logger: logger.New(
|
||||
logwriter, // io writer
|
||||
logger.Config{
|
||||
SlowThreshold: time.Second, // Slow SQL threshold
|
||||
LogLevel: logger.Warn, // Log level
|
||||
//IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
|
||||
ParameterizedQueries: true, // Don't include params in the SQL log
|
||||
Colorful: true,
|
||||
},
|
||||
),
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
sqlDB, err2 := db.DB()
|
||||
if err2 != nil {
|
||||
fmt.Println(err2)
|
||||
}
|
||||
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
|
||||
sqlDB.SetMaxIdleConns(conf.MaxIdleConns)
|
||||
|
||||
// SetMaxOpenConns 设置打开数据库连接的最大数量。
|
||||
sqlDB.SetMaxOpenConns(conf.MaxOpenConns)
|
||||
|
||||
return db
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package orm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
@@ -14,11 +13,11 @@ type SqliteConfig struct {
|
||||
MaxOpenConns int
|
||||
}
|
||||
|
||||
func NewSqlite(sqliteConf *SqliteConfig) *gorm.DB {
|
||||
func NewSqlite(sqliteConf *SqliteConfig, logwriter logger.Writer) *gorm.DB {
|
||||
db, err := gorm.Open(sqlite.Open("./data/rustdeskapi.db"), &gorm.Config{
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
Logger: logger.New(
|
||||
global.Logger, // io writer
|
||||
logwriter, // io writer
|
||||
logger.Config{
|
||||
SlowThreshold: time.Second, // Slow SQL threshold
|
||||
LogLevel: logger.Warn, // Log level
|
||||
|
||||
@@ -14,6 +14,7 @@ const (
|
||||
OauthTypeGoogle string = "google"
|
||||
OauthTypeOidc string = "oidc"
|
||||
OauthTypeWebauth string = "webauth"
|
||||
OauthTypeLinuxdo string = "linuxdo"
|
||||
PKCEMethodS256 string = "S256"
|
||||
PKCEMethodPlain string = "plain"
|
||||
)
|
||||
@@ -21,7 +22,7 @@ const (
|
||||
// Validate the oauth type
|
||||
func ValidateOauthType(oauthType string) error {
|
||||
switch oauthType {
|
||||
case OauthTypeGithub, OauthTypeGoogle, OauthTypeOidc, OauthTypeWebauth:
|
||||
case OauthTypeGithub, OauthTypeGoogle, OauthTypeOidc, OauthTypeWebauth, OauthTypeLinuxdo:
|
||||
return nil
|
||||
default:
|
||||
return errors.New("invalid Oauth type")
|
||||
@@ -30,6 +31,7 @@ func ValidateOauthType(oauthType string) error {
|
||||
|
||||
const (
|
||||
UserEndpointGithub string = "https://api.github.com/user"
|
||||
UserEndpointLinuxdo string = "https://connect.linux.do/api/user"
|
||||
IssuerGoogle string = "https://accounts.google.com"
|
||||
)
|
||||
|
||||
@@ -60,6 +62,8 @@ func (oa *Oauth) FormatOauthInfo() error {
|
||||
oa.Op = OauthTypeGithub
|
||||
case OauthTypeGoogle:
|
||||
oa.Op = OauthTypeGoogle
|
||||
case OauthTypeLinuxdo:
|
||||
oa.Op = OauthTypeLinuxdo
|
||||
}
|
||||
// check if the op is empty, set the default value
|
||||
op := strings.TrimSpace(oa.Op)
|
||||
@@ -152,6 +156,24 @@ func (gu *GithubUser) ToOauthUser() *OauthUser {
|
||||
}
|
||||
}
|
||||
|
||||
type LinuxdoUser struct {
|
||||
OauthUserBase
|
||||
Id int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Avatar string `json:"avatar_url"`
|
||||
}
|
||||
|
||||
func (lu *LinuxdoUser) ToOauthUser() *OauthUser {
|
||||
return &OauthUser{
|
||||
OpenId: strconv.Itoa(lu.Id),
|
||||
Name: lu.Name,
|
||||
Username: strings.ToLower(lu.Username),
|
||||
Email: lu.Email,
|
||||
VerifiedEmail: true, // linux.do 用户邮箱默认已验证
|
||||
Picture: lu.Avatar,
|
||||
}
|
||||
}
|
||||
|
||||
type OauthList struct {
|
||||
Oauths []*Oauth `json:"list"`
|
||||
Pagination
|
||||
|
||||
@@ -3,13 +3,14 @@ package service
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AppService struct {
|
||||
}
|
||||
|
||||
var version = ""
|
||||
|
||||
var startTime = ""
|
||||
var once = &sync.Once{}
|
||||
|
||||
func (a *AppService) GetAppVersion() string {
|
||||
@@ -26,3 +27,13 @@ func (a *AppService) GetAppVersion() string {
|
||||
})
|
||||
return version
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Initialize the AppService if needed
|
||||
startTime = time.Now().Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
// GetStartTime
|
||||
func (a *AppService) GetStartTime() string {
|
||||
return startTime
|
||||
}
|
||||
|
||||
@@ -154,6 +154,18 @@ func (os *OauthService) GithubProvider() *oidc.Provider {
|
||||
}).NewProvider(context.Background())
|
||||
}
|
||||
|
||||
func (os *OauthService) LinuxdoProvider() *oidc.Provider {
|
||||
return (&oidc.ProviderConfig{
|
||||
IssuerURL: "",
|
||||
AuthURL: "https://connect.linux.do/oauth2/authorize",
|
||||
TokenURL: "https://connect.linux.do/oauth2/token",
|
||||
DeviceAuthURL: "",
|
||||
UserInfoURL: model.UserEndpointLinuxdo,
|
||||
JWKSURL: "",
|
||||
Algorithms: nil,
|
||||
}).NewProvider(context.Background())
|
||||
}
|
||||
|
||||
// GetOauthConfig retrieves the OAuth2 configuration based on the provider name
|
||||
func (os *OauthService) GetOauthConfig(op string) (err error, oauthInfo *model.Oauth, oauthConfig *oauth2.Config, provider *oidc.Provider) {
|
||||
//err, oauthInfo, oauthConfig = os.getOauthConfigGeneral(op)
|
||||
@@ -182,6 +194,10 @@ func (os *OauthService) GetOauthConfig(op string) (err error, oauthInfo *model.O
|
||||
oauthConfig.Endpoint = github.Endpoint
|
||||
oauthConfig.Scopes = []string{"read:user", "user:email"}
|
||||
provider = os.GithubProvider()
|
||||
case model.OauthTypeLinuxdo:
|
||||
provider = os.LinuxdoProvider()
|
||||
oauthConfig.Endpoint = provider.Endpoint()
|
||||
oauthConfig.Scopes = []string{"profile"}
|
||||
//case model.OauthTypeGoogle: //google单独出来,可以少一次FetchOidcEndpoint请求
|
||||
// oauthConfig.Endpoint = google.Endpoint
|
||||
// oauthConfig.Scopes = os.constructScopes(oauthInfo.Scopes)
|
||||
@@ -299,6 +315,16 @@ func (os *OauthService) githubCallback(oauthConfig *oauth2.Config, provider *oid
|
||||
return nil, user.ToOauthUser()
|
||||
}
|
||||
|
||||
// linuxdoCallback linux.do回调
|
||||
func (os *OauthService) linuxdoCallback(oauthConfig *oauth2.Config, provider *oidc.Provider, code, verifier, nonce string) (error, *model.OauthUser) {
|
||||
var user = &model.LinuxdoUser{}
|
||||
err, _ := os.callbackBase(oauthConfig, provider, code, verifier, nonce, user)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
return nil, user.ToOauthUser()
|
||||
}
|
||||
|
||||
// oidcCallback oidc回调, 通过code获取用户信息
|
||||
func (os *OauthService) oidcCallback(oauthConfig *oauth2.Config, provider *oidc.Provider, code, verifier, nonce string) (error, *model.OauthUser) {
|
||||
var user = &model.OidcUser{}
|
||||
@@ -319,6 +345,8 @@ func (os *OauthService) Callback(code, verifier, op, nonce string) (err error, o
|
||||
switch oauthType {
|
||||
case model.OauthTypeGithub:
|
||||
err, oauthUser = os.githubCallback(oauthConfig, provider, code, verifier, nonce)
|
||||
case model.OauthTypeLinuxdo:
|
||||
err, oauthUser = os.linuxdoCallback(oauthConfig, provider, code, verifier, nonce)
|
||||
case model.OauthTypeOidc, model.OauthTypeGoogle:
|
||||
err, oauthUser = os.oidcCallback(oauthConfig, provider, code, verifier, nonce)
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user