wip: 刚刚开始, 探索阶段

This commit is contained in:
loveuer 2024-10-23 17:46:15 +08:00
commit eb1744bd0d
10 changed files with 249 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.idea
.vscode
.DS_Store

19
go.mod Normal file
View File

@ -0,0 +1,19 @@
module uauth
go 1.20
require (
github.com/google/uuid v1.6.0
github.com/gorilla/mux v1.8.1
github.com/loveuer/nf v0.2.11
github.com/spf13/cobra v1.8.1
)
require (
github.com/fatih/color v1.17.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.20.0 // indirect
)

27
go.sum Normal file
View File

@ -0,0 +1,27 @@
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/loveuer/nf v0.2.11 h1:W775exDO8eNAHT45WDhXekMYCuWahOW9t1aVmGh3u1o=
github.com/loveuer/nf v0.2.11/go.mod h1:M6reF17/kJBis30H4DxR5hrtgo/oJL4AV4cBe4HzJLw=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -0,0 +1,18 @@
meta {
name: auth req
type: http
seq: 2
}
get {
url: http://127.0.0.1:8080/authorize?client_id=12345&response_type=code&redirect_uri=http://localhost:8080/callback&scopde=balaba
body: none
auth: none
}
params:query {
client_id: 12345
response_type: code
redirect_uri: http://localhost:8080/callback
scopde: balaba
}

View File

@ -0,0 +1,9 @@
{
"version": "1",
"name": "uauth",
"type": "collection",
"ignore": [
"node_modules",
".git"
]
}

30
internal/cmd/cmd.go Normal file
View File

@ -0,0 +1,30 @@
package cmd
import (
"github.com/loveuer/nf/nft/log"
"github.com/spf13/cobra"
"uauth/internal/opt"
)
var (
Command = &cobra.Command{
Use: "uauth",
Short: "uauth: oauth v2 server",
Example: "",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
if opt.Cfg.Debug {
log.SetLogLevel(log.LogLevelDebug)
}
},
}
)
func init() {
Command.PersistentFlags().BoolVar(&opt.Cfg.Debug, "debug", false, "debug mode")
initServe()
Command.AddCommand(
initServe(),
)
}

11
internal/cmd/serve.go Normal file
View File

@ -0,0 +1,11 @@
package cmd
import "github.com/spf13/cobra"
func initServe() *cobra.Command {
serve := &cobra.Command{
Use: "serve",
}
return serve
}

9
internal/opt/config.go Normal file
View File

@ -0,0 +1,9 @@
package opt
type config struct {
Debug bool `json:"debug"`
}
var (
Cfg = config{}
)

100
main.go Normal file
View File

@ -0,0 +1,100 @@
package main
import (
"fmt"
"github.com/google/uuid"
"github.com/loveuer/nf"
"log"
"net/http"
)
// 假设这是你的用户认证函数
func authenticateUser(username, password string) (bool, error) {
// 这里你应该实现真实的用户认证逻辑
// 为了简化,我们这里直接硬编码一个用户名和密码
if username == "user" && password == "pass" {
return true, nil
}
return false, fmt.Errorf("invalid username or password")
}
// 处理登录请求
func handleLogin(c *nf.Ctx) error {
username := c.FormValue("username")
password := c.FormValue("password")
// 认证用户
ok, err := authenticateUser(username, password)
if err != nil || !ok {
return c.Status(http.StatusUnauthorized).SendString("Unauthorized")
}
// 用户认证成功,重定向到授权页面
http.Redirect(c.Writer, c.Request, "/authorize?client_id=12345&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fcallback&scope=read%20write", http.StatusFound)
return nil
}
// 处理授权请求
func handleAuthorize(c *nf.Ctx) error {
// 解析查询参数
clientID := c.Query("client_id")
responseType := c.Query("response_type")
redirectURI := c.Query("redirect_uri")
scope := c.Query("scope")
// 检查客户端 ID 和其他参数
// 在实际应用中,你需要检查这些参数是否合法
if clientID != "12345" || responseType != "code" || redirectURI != "http://localhost:8080/callback" {
return c.Status(http.StatusBadRequest).SendString("Invalid request")
}
// 显示授权页面给用户
_, err := c.Write([]byte(`
<html>
<head><title>Authorization</title></head>
<body>
<h1>Do you want to authorize this application?</h1>
<form action="/approve" method="post">
<input type="hidden" name="client_id" value="` + clientID + `"/>
<input type="hidden" name="redirect_uri" value="` + redirectURI + `"/>
<input type="hidden" name="scope" value="` + scope + `"/>
<button type="submit">Yes, I authorize</button>
</form>
</body>
</html>
`))
return err
}
// 处理用户的授权批准
func handleApprove(c *nf.Ctx) error {
// 获取表单数据
clientID := c.FormValue("client_id")
redirectURI := c.FormValue("redirect_uri")
scope := c.FormValue("scope")
// 生成授权码
authorizationCode := uuid.New().String()[:8]
log.Printf("[D] client_id = %s, scope = %s, auth_code = %s", clientID, scope, authorizationCode)
// 重定向到回调 URL 并附带授权码
http.Redirect(c.Writer, c.Request, redirectURI+"?code="+authorizationCode, http.StatusFound)
return nil
}
func main() {
app := nf.New()
// 设置路由
app.Get("/login", handleLogin)
app.Get("/authorize", handleAuthorize)
app.Post("/approve", handleApprove)
// 启动 HTTP 服务器
log.Println("Starting server on :8080")
log.Fatal(app.Run(":8080"))
}

23
model/user.go Normal file
View File

@ -0,0 +1,23 @@
package model
type Status int64
type User struct {
Id uint64 `json:"id" gorm:"primaryKey;column:id"`
CreatedAt int64 `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt int64 `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"`
DeletedAt int64 `json:"deleted_at" gorm:"index;column:deleted_at;default:0"`
Username string `json:"username" gorm:"column:username;type:varchar(64);unique"`
Password string `json:"-" gorm:"column:password;type:varchar(256)"`
Status Status `json:"status" gorm:"column:status;default:0"`
Nickname string `json:"nickname" gorm:"column:nickname;type:varchar(64)"`
Comment string `json:"comment" gorm:"column:comment"`
CreatedById uint64 `json:"created_by_id" gorm:"column:created_by_id"`
CreatedByName string `json:"created_by_name" gorm:"column:created_by_name;type:varchar(64)"`
LoginAt int64 `json:"login_at" gorm:"-"`
}