fix: go mod oauth test
This commit is contained in:
parent
548266fe9d
commit
92704e80f1
8 changed files with 175 additions and 2 deletions
|
|
@ -14,4 +14,9 @@
|
|||
| SMTP_PASSWORD | SMTP Password | `none` |
|
||||
| SMTP_FROM | Mail address used as from for all mails | `none` |
|
||||
| WEB_PUBLIC_REGISTRATION | Enabled the registration for anyone on the webgui | False |
|
||||
| WEB_JWT_SECRET_KEY | Set secret key for the jwt used | `abc` |
|
||||
| MINIAUTH_LOGIN_WITH_NOT_APPROVED_MAIL | Allow user to login even if there mail address is not validated | False |
|
||||
|
||||
|
||||
## Development
|
||||
create locale db by run `sh db.sh` than set the env varieables you need and run everything.
|
||||
|
|
|
|||
5
main.go
5
main.go
|
|
@ -7,6 +7,7 @@ import (
|
|||
"html/template"
|
||||
|
||||
"git.keks.cloud/kekskurse/miniauth/pkg/miniauth"
|
||||
"git.keks.cloud/kekskurse/miniauth/pkg/oauthapi"
|
||||
"git.keks.cloud/kekskurse/miniauth/pkg/smtpclient"
|
||||
"git.keks.cloud/kekskurse/miniauth/pkg/userstore"
|
||||
"git.keks.cloud/kekskurse/miniauth/pkg/web"
|
||||
|
|
@ -31,6 +32,7 @@ type gloableConfig struct {
|
|||
WebConfig web.WebConfig `env:", prefix=WEB_"`
|
||||
MiniauthConfig miniauth.MiniauthConfig `env:", prefix=MINIAUTH_"`
|
||||
DummyDatabase bool `env:"DUMMY_DATABASE"`
|
||||
OauthConfig oauthapi.OauthAPIConf `env:", prefix=OAUTH_"`
|
||||
}
|
||||
|
||||
func config() gloableConfig {
|
||||
|
|
@ -79,6 +81,9 @@ func setupRouter(cfg gloableConfig) *gin.Engine {
|
|||
webServer := web.NewWeb(cfg.WebConfig, ma)
|
||||
webServer.RegisterRoutes(routesWeb)
|
||||
|
||||
oauthapi := oauthapi.NewOauthAPI(cfg.OauthConfig, ma)
|
||||
oauthapi.RegisterRoutes(router.Group("/oauth/"))
|
||||
|
||||
router.GET("/", func(c *gin.Context) {})
|
||||
router.GET("/ping", func(c *gin.Context) { c.String(200, "pong") })
|
||||
|
||||
|
|
|
|||
1
pkg/oauthapi/migrations/1742764325_init.down.sql
Normal file
1
pkg/oauthapi/migrations/1742764325_init.down.sql
Normal file
|
|
@ -0,0 +1 @@
|
|||
-- Write your down sql migration here
|
||||
12
pkg/oauthapi/migrations/1742764325_init.up.sql
Normal file
12
pkg/oauthapi/migrations/1742764325_init.up.sql
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
-- Write your up sql migration here
|
||||
CREATE TABLE clients (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
client_id TEXT NOT NULL UNIQUE,
|
||||
client_secret TEXT NOT NULL UNIQUE,
|
||||
redirect_uris TEXT NOT NULL,
|
||||
response_types TEXT NOT NULL,
|
||||
grant_types TEXT NOT NULL,
|
||||
scopes TEXT NOT NULL
|
||||
)
|
||||
109
pkg/oauthapi/oauthapi.go
Normal file
109
pkg/oauthapi/oauthapi.go
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
package oauthapi
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.keks.cloud/kekskurse/miniauth/pkg/miniauth"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/compose"
|
||||
"github.com/ory/fosite/storage"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type OauthAPIConf struct{}
|
||||
|
||||
type OAuthAPI struct {
|
||||
config OauthAPIConf
|
||||
ma miniauth.Miniauth
|
||||
log zerolog.Logger
|
||||
oauth fosite.OAuth2Provider
|
||||
}
|
||||
|
||||
func NewOauthAPI(config OauthAPIConf, ma miniauth.Miniauth) OAuthAPI {
|
||||
w := OAuthAPI{}
|
||||
w.config = config
|
||||
w.ma = ma
|
||||
l := log.With().Str("pkg", "oauthapi").Logger()
|
||||
w.log = l
|
||||
|
||||
storage := storage.NewExampleStore()
|
||||
secret := []byte("my super secret signing password")
|
||||
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
w.log.Fatal().Err(err).Msg("cant create privatekey")
|
||||
}
|
||||
|
||||
oconfig := &fosite.Config{
|
||||
AccessTokenLifespan: time.Minute * 30,
|
||||
GlobalSecret: secret,
|
||||
}
|
||||
|
||||
oauth2Provider := compose.ComposeAllEnabled(oconfig, storage, privateKey)
|
||||
|
||||
w.oauth = oauth2Provider
|
||||
return w
|
||||
}
|
||||
|
||||
func (w OAuthAPI) RegisterRoutes(routing *gin.RouterGroup) error {
|
||||
routing.GET("/auth", w.authGet)
|
||||
routing.POST("/auth", w.authPost)
|
||||
routing.POST("/token", w.token)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w OAuthAPI) authGet(ctx *gin.Context) {
|
||||
ar, err := w.oauth.NewAuthorizeRequest(ctx, ctx.Request)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("cant create authorize request")
|
||||
w.oauth.WriteAuthorizeError(ctx, ctx.Writer, ar, err)
|
||||
return
|
||||
}
|
||||
w.log.Debug().Interface("ar", err).Msg("AuthorizeRequest")
|
||||
|
||||
ctx.HTML(http.StatusOK, "login.html", nil)
|
||||
}
|
||||
|
||||
func (w OAuthAPI) authPost(ctx *gin.Context) {
|
||||
ar, err := w.oauth.NewAuthorizeRequest(ctx, ctx.Request)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("cant create authorize request")
|
||||
w.oauth.WriteAuthorizeError(ctx, ctx.Writer, ar, err)
|
||||
return
|
||||
}
|
||||
|
||||
mySessionData := &fosite.DefaultSession{
|
||||
Username: ctx.PostForm("username"),
|
||||
}
|
||||
|
||||
response, err := w.oauth.NewAuthorizeResponse(ctx.Request.Context(), ar, mySessionData)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("cant create response")
|
||||
w.oauth.WriteAuthorizeError(ctx, ctx.Writer, ar, err)
|
||||
return
|
||||
}
|
||||
|
||||
w.oauth.WriteAuthorizeResponse(ctx, ctx.Writer, ar, response)
|
||||
}
|
||||
|
||||
func (w OAuthAPI) token(ctx *gin.Context) {
|
||||
mySessionData := new(fosite.DefaultSession)
|
||||
|
||||
accessRequest, err := w.oauth.NewAccessRequest(ctx, ctx.Request, mySessionData)
|
||||
if err != nil {
|
||||
w.oauth.WriteAccessError(ctx.Request.Context(), ctx.Writer, accessRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
response, err := w.oauth.NewAccessResponse(ctx, accessRequest)
|
||||
if err != nil {
|
||||
w.oauth.WriteAccessError(ctx, ctx.Writer, accessRequest, err)
|
||||
return
|
||||
}
|
||||
w.oauth.WriteAccessResponse(ctx, ctx.Writer, accessRequest, response)
|
||||
}
|
||||
10
pkg/oauthapi/store.go
Normal file
10
pkg/oauthapi/store.go
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package oauthapi
|
||||
|
||||
import "github.com/rs/zerolog"
|
||||
|
||||
type Config struct {
|
||||
SQLite struct {
|
||||
Path string `env:"SQLITE_PATH"`
|
||||
}
|
||||
Logger zerolog.Logger
|
||||
}
|
||||
|
|
@ -3,13 +3,17 @@ package web
|
|||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.keks.cloud/kekskurse/miniauth/pkg/miniauth"
|
||||
"git.keks.cloud/kekskurse/miniauth/pkg/userstore"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
type WebConfig struct {
|
||||
PublicRegistration bool `env:"PUBLIC_REGISTRATION, default=0"`
|
||||
JWT_SECRET_KEY string `env:"JWT_SECRET_KEY, default=abc"`
|
||||
}
|
||||
|
||||
type Web struct {
|
||||
|
|
@ -68,11 +72,37 @@ func (w Web) PostLoginPage(c *gin.Context) {
|
|||
username := c.PostForm("username")
|
||||
password := c.PostForm("password")
|
||||
|
||||
err := w.ma.UserLogin(username, password)
|
||||
_, err := w.ma.UserLogin(username, password)
|
||||
if err != nil {
|
||||
c.HTML(http.StatusOK, "login.html", gin.H{"msg": errors.Unwrap(err).Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.SetSameSite(http.SameSiteStrictMode)
|
||||
|
||||
c.HTML(http.StatusOK, "msg.html", gin.H{"msg": "Login ok!"})
|
||||
}
|
||||
|
||||
func (w Web) DashboardPage(c *gin.Context) {
|
||||
}
|
||||
|
||||
type UserClaim struct {
|
||||
User userstore.User
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func (w Web) createToken(user userstore.User) (string, error) {
|
||||
tokenLifespan := 15 * time.Minute
|
||||
|
||||
claims := UserClaim{
|
||||
User: user,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
Subject: "user-" + user.Username,
|
||||
Issuer: "gin-jwt",
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(tokenLifespan)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
},
|
||||
}
|
||||
t := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
return t.SignedString(w.config.JWT_SECRET_KEY)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ export default defineConfig({
|
|||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on-first-retry',
|
||||
video: 'on',
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
|
|
|
|||
Reference in a new issue