This commit is contained in:
Sakurasan
2023-03-28 22:46:22 +08:00
parent 58835ee0d4
commit 2ba63e226d
6 changed files with 492 additions and 5 deletions

View File

@@ -12,6 +12,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt"
"github.com/google/go-github/v50/github"
"github.com/joho/godotenv"
"golang.org/x/oauth2"
ogithub "golang.org/x/oauth2/github"
"gorm.io/driver/mysql"
@@ -19,15 +20,19 @@ import (
)
var db *gorm.DB
var jwtSecret = []byte(os.Getenv("JWT_SECRET"))
var jwtSecret = []byte("JWT_SECRET")
func main() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
initDB()
router := gin.Default()
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:8080"},
AllowOrigins: []string{"http://localhost:8000"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD"},
AllowHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
AllowCredentials: true,
@@ -40,7 +45,8 @@ func main() {
}
func githubLoginHandler(c *gin.Context) {
state := generateState()
state := "1234567890"
// state := generateState()
// code := generateCode()
// err := storeStateToDB(state, code)
@@ -110,7 +116,7 @@ func githubCallbackHandler(c *gin.Context) {
}
c.SetCookie("token", jwtToken, 60*60*24, "/", "localhost", false, true)
c.Redirect(http.StatusFound, "http://localhost:8080/#/")
c.Redirect(http.StatusFound, "http://localhost:8080/")
}
func initDB() {
@@ -202,3 +208,11 @@ func generateJWTToken(userID int64) (string, error) {
return jwtToken, nil
}
type GithubUser struct {
ID int `json:"id"`
Login string `json:"login"`
Name string `json:"name"`
AvatarURL string `json:"avatar_url"`
Email string `json:"email"`
}

6
go.mod
View File

@@ -8,10 +8,13 @@ require (
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-github/v50 v50.2.0
github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.5.0
github.com/joho/godotenv v1.5.1
golang.org/x/oauth2 v0.6.0
gorm.io/driver/mysql v1.4.7
gorm.io/gorm v1.23.8
gorm.io/driver/sqlite v1.4.4
gorm.io/gorm v1.24.0
)
require (
@@ -33,6 +36,7 @@ require (
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-sqlite3 v1.14.15 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect

132
opencatd/db/cat.go Normal file
View File

@@ -0,0 +1,132 @@
package db
import (
"database/sql"
"fmt"
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Token string `json:"token"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
IsDelete bool `json:"isDelete"`
}
func addUser(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
db, err := sql.Open("sqlite3", "test.db")
if err != nil {
log.Fatal(err)
}
stmt, err := db.Prepare("INSERT INTO users(name, token, created_at, updated_at, is_delete) values(?,?,?,?,?)")
if err != nil {
log.Fatal(err)
}
res, err := stmt.Exec(user.Name, user.Token, user.CreatedAt, user.UpdatedAt, user.IsDelete)
if err != nil {
log.Fatal(err)
}
id, err := res.LastInsertId()
if err != nil {
log.Fatal(err)
}
user.ID = int(id)
c.JSON(http.StatusOK, user)
}
func updateUser(c *gin.Context) {
id := c.Param("id")
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
db, err := sql.Open("sqlite3", "test.db")
if err != nil {
log.Fatal(err)
}
stmt, err := db.Prepare("UPDATE users SET name=?, token=?, created_at=?, updated_at=?, is_delete=? WHERE id=?")
if err != nil {
log.Fatal(err)
}
_, err = stmt.Exec(user.Name, user.Token, user.CreatedAt, user.UpdatedAt, user.IsDelete, id)
if err != nil {
log.Fatal(err)
}
c.JSON(http.StatusOK, user)
}
func deleteUser(c *gin.Context) {
id := c.Param("id")
db, err := sql.Open("sqlite3", "test.db")
if err != nil {
log.Fatal(err)
}
stmt, err := db.Prepare("DELETE FROM users WHERE id=?")
if err != nil {
log.Fatal(err)
}
_, err = stmt.Exec(id)
if err != nil {
log.Fatal(err)
}
c.JSON(http.StatusOK, gin.H{"message": "ok"})
}
func initDB() {
db, err := sql.Open("sqlite3", "test.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
_, err = db.Exec("CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, name TEXT, token TEXT, created_at DATETIME, updated_at DATETIME, is_delete BOOLEAN)")
if err != nil {
log.Fatal(err)
}
shouldBeDeleted := false
now := time.Now().Format(time.RFC3339)
stmt, err := db.Prepare("INSERT INTO users(name, token, created_at, updated_at, is_delete) values(?,?,?,?,?)")
if err != nil {
log.Fatal(err)
}
res, err := stmt.Exec("Test User", "123456789", now, now, shouldBeDeleted)
if err != nil {
log.Fatal(err)
}
id, err := res.LastInsertId()
if err != nil {
log.Fatal(err)
}
fmt.Printf("New user ID: %d\n", id)
}

172
opencatd/opencat.go Normal file
View File

@@ -0,0 +1,172 @@
package main
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
type User struct {
IsDelete bool `json:"IsDelete"`
ID int `json:"id"`
UpdatedAt string `json:"updatedAt"`
Name string `json:"name"`
Token string `json:"token"`
CreatedAt string `json:"createdAt"`
}
type Key struct {
ID int `json:"id"`
Key string `json:"key"`
UpdatedAt string `json:"updatedAt"`
Name string `json:"name"`
CreatedAt string `json:"createdAt"`
}
var users = []User{
{false, 1, "2023-03-28T12:36:03.907590825Z", "root", "4930f144-7ffc-469b-8f2d-71a267358d87", "2023-03-28T11:52:45.593940257Z"},
}
var keys = []Key{
{1, "1234567890", "2023-03-28T12:53:41.124319079Z", "key1", "2023-03-28T12:53:41.124318928Z"},
}
func main() {
router := gin.Default()
// 初始化用户
router.POST("/1/users/init", func(c *gin.Context) {
resJSON := User{
false,
1,
"2023-03-28T14:13:54.969089197Z",
"root",
"3260dd53-463f-45d0-afa4-57acd04ee036",
"2023-03-28T14:13:54.969089107Z",
}
c.JSON(http.StatusOK, resJSON)
})
// 获取当前用户信息
router.GET("/1/me", func(c *gin.Context) {
resJSON := users[0]
c.JSON(http.StatusOK, resJSON)
})
// 获取所有Key
router.GET("/1/keys", func(c *gin.Context) {
c.JSON(http.StatusOK, keys)
})
// 获取所有用户信息
router.GET("/1/users", func(c *gin.Context) {
c.JSON(http.StatusOK, users)
})
// 添加Key
router.POST("/1/keys", func(c *gin.Context) {
var body Key
if err := c.BindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
keys = append(keys, body)
c.JSON(http.StatusCreated, body)
})
// 删除Key
router.DELETE("/1/keys/:id", func(c *gin.Context) {
id := c.Param("id")
var keyIdx int = -1
for idx, key := range keys {
if strconv.Itoa(key.ID) == id {
keyIdx = idx
break
}
}
if keyIdx == -1 {
c.JSON(http.StatusNotFound, gin.H{"error": "Key not found"})
return
}
keys = append(keys[:keyIdx], keys[keyIdx+1:]...)
c.JSON(http.StatusOK, gin.H{"message": "ok"})
})
// 添加用户
router.POST("/1/users", func(c *gin.Context) {
var body User
if err := c.BindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
newUser := User{
false,
len(users) + 1,
"2023-03-28T13:05:02.103135082Z",
body.Name,
GenerateToken(),
"2023-03-28T12:38:57.513105431Z",
}
users = append(users, newUser)
c.JSON(http.StatusCreated, newUser)
})
// 删除用户
router.DELETE("/1/users/:id", func(c *gin.Context) {
id := c.Param("id")
var userIdx int = -1
for idx, user := range users {
if strconv.Itoa(user.ID) == id {
userIdx = idx
break
}
}
if userIdx == -1 {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
users = append(users[:userIdx], users[userIdx+1:]...)
c.JSON(http.StatusOK, gin.H{"message": "ok"})
})
// 重置用户Token
router.POST("/1/users/:id/reset", func(c *gin.Context) {
id := c.Param("id")
var userIdx int = -1
for idx, user := range users {
if strconv.Itoa(user.ID) == id {
userIdx = idx
break
}
}
if userIdx == -1 {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
users[userIdx].Token = GenerateToken()
c.JSON(http.StatusOK, users[userIdx])
})
router.Run(":8080")
}
func GenerateToken() string {
token := uuid.New()
return token.String()
}

108
opencatd/opencatd.c Normal file
View File

@@ -0,0 +1,108 @@
docker pull debian:bullseye
opencat://team/join?domain=http://168.138.211.226&token=f1ad7afa-65fe-436f-bbbb-8df8a35c332e
"/1/me"
"/1/keys"
"/1/users"
POST "/1/users/init"
{
"IsDelete" : false,
"id" : 1,
"updatedAt" : "2023-03-28T14:13:54.969089197Z",
"name" : "root",
"token" : "3260dd53-463f-45d0-afa4-57acd04ee036",
"createdAt" : "2023-03-28T14:13:54.969089107Z"
}
GET "1/me"
{
"IsDelete" : false,
"id" : 1,
"updatedAt" : "2023-03-28T12:36:03.907590825Z",
"name" : "root",
"token" : "4930f144-7ffc-469b-8f2d-71a267358d87",
"createdAt" : "2023-03-28T11:52:45.593940257Z"
}
GET "1/keys"
[
{
"id" : 1,
"key" : "1234567890",
"updatedAt" : "2023-03-28T12:53:41.124319079Z",
"name" : "key1",
"createdAt" : "2023-03-28T12:53:41.124318928Z"
}
]
GET "1/users"
[
{
"IsDelete" : false,
"id" : 1,
"updatedAt" : "2023-03-28T12:36:03.907590825Z",
"name" : "root",
"token" : "4930f144-7ffc-469b-8f2d-71a267358d87",
"createdAt" : "2023-03-28T11:52:45.593940257Z"
}
]
//添加key
POST "/1/keys" body {"key":"1234567890","name":"key1"}
{
"id" : 1,
"key" : "1234567890",
"updatedAt" : "2023-03-28T12:53:41.124319079Z",
"name" : "key1",
"createdAt" : "2023-03-28T12:53:41.124318928Z"
}
//删除KEY
DELETE "1/keys/1"
{"message":"ok"}
//添加user
POST "1/users" body{"name":"user1"}
Host: 168.138.211.226
User-Agent: OpenCat/99 CFNetwork/1404.0.5 Darwin/22.3.0
Authorization: Bearer 4930f144-7ffc-469b-8f2d-71a267358d87
{
"IsDelete" : false,
"id" : 2,
"updatedAt" : "2023-03-28T12:38:57.513105571Z",
"name" : "user1",
"token" : "f5bbee90-5f10-4501-bbe4-4989d0c41a82",
"createdAt" : "2023-03-28T12:38:57.513105431Z"
}
//删除user3
DELETE "1/users/3"
{"message":"ok"}
//重置user token
POST "/1/users/2/reset"
{
"IsDelete" : false,
"id" : 2,
"updatedAt" : "2023-03-28T13:05:02.103135082Z",
"name" : "user1",
"token" : "87f0af9c-ae80-4754-8de8-2d9522b24dee",
"createdAt" : "2023-03-28T12:38:57.513105431Z"
}
http://localhost/v1/chat/completions
./opencatd reset_root

57
pkg/opencatd/db/db.go Normal file
View File

@@ -0,0 +1,57 @@
package db
import (
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Name string `gorm:"not null"`
Token string `gorm:"unique;not null"`
}
var db *gorm.DB
func init() {
var err error
db, err = gorm.Open(sqlite.Open("./db/cat.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// 自动迁移 User 结构体
err = db.AutoMigrate(&User{})
if err != nil {
panic(err)
}
}
// 添加用户
func AddUser(name, token string) error {
user := &User{Name: name, Token: token}
result := db.Create(&user)
if result.Error != nil {
return result.Error
}
return nil
}
// 删除用户
func DeleteUser(id uint) error {
result := db.Delete(&User{}, id)
if result.Error != nil {
return result.Error
}
return nil
}
// 修改用户
func UpdateUser(id uint, name, token string) error {
user := &User{Name: name, Token: token}
result := db.Model(&User{}).Where("id = ?", id).Updates(user)
if result.Error != nil {
return result.Error
}
return nil
}