feat: Added basic user authorization

This commit is contained in:
2025-08-20 01:24:49 +03:00
parent b72066f19e
commit fb4902dea6
15 changed files with 396 additions and 2 deletions

3
modules/auth/auth.go Normal file
View File

@@ -0,0 +1,3 @@
package auth
const BCRYPT_COST = 13

36
modules/auth/plain.go Normal file
View File

@@ -0,0 +1,36 @@
package auth
import (
"git.ostiwe.com/ostiwe-com/status/modules/jwt"
"git.ostiwe.com/ostiwe-com/status/repository"
"golang.org/x/crypto/bcrypt"
)
type Module struct {
userRepository repository.User
}
func New() Module {
return Module{
userRepository: repository.NewUserRepository(),
}
}
func (m *Module) Proceed(login, password string) (*string, error) {
lightweightUser, err := m.userRepository.FindByLogin(login)
if err != nil {
return nil, err
}
err = bcrypt.CompareHashAndPassword([]byte(lightweightUser.Password), []byte(password))
if err != nil {
return nil, err
}
jwtString, err := jwt.CreateByUser(lightweightUser)
if err != nil {
return nil, err
}
return &jwtString, nil
}

38
modules/jwt/claims.go Normal file
View File

@@ -0,0 +1,38 @@
package jwt
import (
"os"
"slices"
"strings"
"github.com/golang-jwt/jwt/v5"
)
type Claims struct {
*jwt.RegisteredClaims
UserID uint64 `json:"userId"`
}
func NewClaims() *Claims {
c := &Claims{
RegisteredClaims: &jwt.RegisteredClaims{},
}
var (
trustedHosts = os.Getenv("JWT_TRUSTED_HOSTS")
audienceList []string
)
c.Issuer = os.Getenv("APP_HOST")
audienceList = append(audienceList, strings.Split(trustedHosts, ",")...)
audienceList = append(audienceList, c.Issuer)
audienceList = slices.DeleteFunc(audienceList, func(s string) bool {
return s == ""
})
c.Audience = audienceList
return c
}

83
modules/jwt/jwt.go Normal file
View File

@@ -0,0 +1,83 @@
package jwt
import (
"crypto/ed25519"
"os"
"strings"
"time"
"git.ostiwe.com/ostiwe-com/status/model"
"git.ostiwe.com/ostiwe-com/status/settings"
"github.com/go-chi/jwtauth/v5"
"github.com/golang-jwt/jwt/v5"
"github.com/lestrrat-go/jwx/v2/jwa"
)
var (
signKey *ed25519.PrivateKey
publicSignKey *ed25519.PublicKey
signMethod jwt.SigningMethod
TokenAuth *jwtauth.JWTAuth
)
func init() {
jwtPublicKeyPath := os.Getenv("JWT_SIGN_PUBLIC_KEY_PATH")
if !strings.HasPrefix(jwtPublicKeyPath, "/") {
jwtPublicKeyPath = settings.WorkingDir + "/" + jwtPublicKeyPath
}
jwtPrivateKeyPath := os.Getenv("JWT_SIGN_PRIVATE_KEY_PATH")
if !strings.HasPrefix(jwtPrivateKeyPath, "/") {
jwtPrivateKeyPath = settings.WorkingDir + "/" + jwtPrivateKeyPath
}
publicFile, err := os.ReadFile(jwtPublicKeyPath)
if err != nil {
panic(err)
}
privateFile, err := os.ReadFile(jwtPrivateKeyPath)
if err != nil {
panic(err)
}
privateKey, err := jwt.ParseEdPrivateKeyFromPEM(privateFile)
if err != nil {
panic(err)
}
publicKey, err := jwt.ParseEdPublicKeyFromPEM(publicFile)
if err != nil {
panic(err)
}
pk, ok := privateKey.(ed25519.PrivateKey)
if !ok {
panic("invalid ed25519 private key")
}
k, ok := publicKey.(ed25519.PublicKey)
if !ok {
panic("invalid ed25519 public key")
}
signKey = &pk
publicSignKey = &k
signMethod = jwt.SigningMethodEdDSA
TokenAuth = jwtauth.New(string(jwa.EdDSA), signKey, publicSignKey)
}
func CreateByUser(user *model.User) (string, error) {
claims := NewClaims()
claims.Subject = user.Login
claims.UserID = user.ID
claims.IssuedAt = jwt.NewNumericDate(time.Now())
claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(time.Hour * 24 * 2))
token := jwt.NewWithClaims(signMethod, claims)
return token.SignedString(signKey)
}