From 69bae574738ce2ea6a1cdc0a7e9f3fcf2e1c6cca Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 7 Jan 2024 15:52:23 +0800 Subject: [PATCH] :sparkles: Auth impl --- pkg/models/accounts.go | 21 +++++++++++++-------- pkg/security/challanges.go | 3 +-- pkg/server/auth.go | 32 ++++++++++++++++++++++++++++++++ pkg/server/index.go | 21 +++++++++++++++++++++ pkg/services/accounts.go | 11 +++++++++++ pkg/services/sessions.go | 18 ++++++++++++++++++ 6 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 pkg/server/auth.go create mode 100644 pkg/services/sessions.go diff --git a/pkg/models/accounts.go b/pkg/models/accounts.go index 986ba6e..fc883f1 100644 --- a/pkg/models/accounts.go +++ b/pkg/models/accounts.go @@ -1,6 +1,10 @@ package models -import "time" +import ( + "time" + + "gorm.io/datatypes" +) type AccountState = int8 @@ -12,13 +16,14 @@ const ( type Account struct { BaseModel - Name string `json:"name" gorm:"uniqueIndex"` - Nick string `json:"nick"` - State AccountState `json:"state"` - Session []AuthSession `json:"sessions"` - Challenges []AuthChallenge `json:"challenges"` - Factors []AuthFactor `json:"factors"` - Contacts []AccountContact `json:"contacts"` + Name string `json:"name" gorm:"uniqueIndex"` + Nick string `json:"nick"` + State AccountState `json:"state"` + Session []AuthSession `json:"sessions"` + Challenges []AuthChallenge `json:"challenges"` + Factors []AuthFactor `json:"factors"` + Contacts []AccountContact `json:"contacts"` + Permissions datatypes.JSONType[[]string] `json:"permissions"` } type AccountContactType = int8 diff --git a/pkg/security/challanges.go b/pkg/security/challanges.go index 48ff263..d7e2b16 100644 --- a/pkg/security/challanges.go +++ b/pkg/security/challanges.go @@ -17,8 +17,7 @@ func NewChallenge(account models.Account, factors []models.AuthFactor, ip, ua st // Pickup any challenge if possible if err := database.C.Where(models.AuthChallenge{ AccountID: account.ID, - State: models.ActiveChallengeState, - }).First(&challenge).Error; err == nil { + }).Where("state = ?", models.ActiveChallengeState).First(&challenge).Error; err == nil { return challenge, nil } diff --git a/pkg/server/auth.go b/pkg/server/auth.go new file mode 100644 index 0000000..a96add6 --- /dev/null +++ b/pkg/server/auth.go @@ -0,0 +1,32 @@ +package server + +import ( + "code.smartsheep.studio/hydrogen/bus/pkg/kit/adaptor" + "code.smartsheep.studio/hydrogen/bus/pkg/kit/publisher" + "code.smartsheep.studio/hydrogen/bus/pkg/wire" + "code.smartsheep.studio/hydrogen/passport/pkg/security" + "code.smartsheep.studio/hydrogen/passport/pkg/services" +) + +func doAuth(c *publisher.RequestCtx) error { + token := adaptor.ParseAnyToStruct[string](c.Parameters) + + claims, err := security.DecodeJwt(token) + if err != nil { + return c.SendError(wire.Unauthorized, err) + } + + session, err := services.LookupSessionWithToken(claims.ID) + if err != nil { + return c.SendError(wire.Unauthorized, err) + } else if err := session.IsAvailable(); err != nil { + return c.SendError(wire.Unauthorized, err) + } + + user, err := services.GetAccount(session.AccountID) + if err != nil { + return c.SendError(wire.Unauthorized, err) + } + + return c.SendResponse(user.Permissions.Data()) +} diff --git a/pkg/server/index.go b/pkg/server/index.go index 1c2fefd..12eb221 100644 --- a/pkg/server/index.go +++ b/pkg/server/index.go @@ -42,4 +42,25 @@ var Commands = map[string]publisher.CommandManifest{ Requirements: wire.CommandRequirements{}, Handle: refreshToken, }, + "passport.auth": { + Name: "Auth with access token.", + Description: "Auth gateway request with access token.", + Requirements: wire.CommandRequirements{}, + Providers: []wire.CommandProvider{ + { + ID: "passport.auth", + Implementation: "gateway.auth", + Weight: 1000, + }, + }, + Handle: doAuth, + }, + "passport.test": { + Name: "Test secured resource.", + Description: "Test secured resource connectivity.", + Requirements: wire.CommandRequirements{Authorized: true}, + Handle: func(c *publisher.RequestCtx) error { + return c.SendResponse("You got me!") + }, + }, } diff --git a/pkg/services/accounts.go b/pkg/services/accounts.go index 9b2f72d..b4b6ed4 100644 --- a/pkg/services/accounts.go +++ b/pkg/services/accounts.go @@ -7,6 +7,17 @@ import ( "code.smartsheep.studio/hydrogen/passport/pkg/models" ) +func GetAccount(id uint) (models.Account, error) { + var account models.Account + if err := database.C.Where(models.Account{ + BaseModel: models.BaseModel{ID: id}, + }).First(&account).Error; err != nil { + return account, err + } + + return account, nil +} + func LookupAccount(id string) (models.Account, error) { var account models.Account if err := database.C.Where(models.Account{Name: id}).First(&account).Error; err == nil { diff --git a/pkg/services/sessions.go b/pkg/services/sessions.go new file mode 100644 index 0000000..190431c --- /dev/null +++ b/pkg/services/sessions.go @@ -0,0 +1,18 @@ +package services + +import ( + "code.smartsheep.studio/hydrogen/passport/pkg/database" + "code.smartsheep.studio/hydrogen/passport/pkg/models" +) + +func LookupSessionWithToken(tokenId string) (models.AuthSession, error) { + var session models.AuthSession + if err := database.C. + Where(models.AuthSession{AccessToken: tokenId}). + Or(models.AuthSession{RefreshToken: tokenId}). + First(&session).Error; err != nil { + return session, err + } + + return session, nil +}