[WIP] added mongo handlers for more dbhandler interfaces

This commit is contained in:
ACoolName 2025-03-14 19:31:05 +02:00
parent fd957e32b9
commit 3e880725df
12 changed files with 183 additions and 108 deletions

View File

@ -19,22 +19,15 @@ import (
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
type AuthMode string
var secret []byte var secret []byte
var method string var method string
var DOMAIN string var DOMAIN string
const (
Oidc AuthMode = "OIDC"
UserPass AuthMode = "UserPass"
)
type Connection struct { type Connection struct {
usersDbHandler dbhandler.UsersDBHandler usersDbHandler dbhandler.UsersDBHandler
authorizationDbHandler dbhandler.AuthorizationDbHandler authorizationDbHandler dbhandler.AuthorizationDbHandler
authMode AuthMode authMode models.AuthMode
userAuthDbHandler *dbhandler.UserPassAuthanticationDbHandler userAuthDbHandler *dbhandler.UserPassAuthanticationDbHandler
OidcAuthDbHandler *dbhandler.OidcAuthenticationDbHandler OidcAuthDbHandler *dbhandler.OidcAuthenticationDbHandler
} }
@ -69,11 +62,6 @@ func signToken(token Claims) (string, error) {
return t.SignedString(secret) return t.SignedString(secret)
} }
func hashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes), err
}
func AuthorizedTo(requiredPermissions models.Permission, overwriters ...func(*gin.Context) bool) gin.HandlerFunc { func AuthorizedTo(requiredPermissions models.Permission, overwriters ...func(*gin.Context) bool) gin.HandlerFunc {
return func(ctx *gin.Context) { return func(ctx *gin.Context) {
authCookie, err := ctx.Request.Cookie("auth") authCookie, err := ctx.Request.Cookie("auth")

View File

@ -1,4 +1,4 @@
package mongo package mongo_db_handlers
import ( import (
"context" "context"

View File

@ -1,4 +1,4 @@
module git.acooldomain.co/server-manager/backend-kubernetes-go/db_handler/mongo module git.acooldomain.co/server-manager/backend-kubernetes-go/db_handler/mongo_db_handlers
go 1.24.1 go 1.24.1

View File

@ -0,0 +1,106 @@
package mongo_db_handlers
import (
"context"
"fmt"
"git.acooldomain.co/server-manager/backend-kubernetes-go/dbhandler"
"git.acooldomain.co/server-manager/backend-kubernetes-go/mail"
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type AuthUser struct {
Username string `json:"username"`
HashedPassword string `json:"hashed_password"`
Permissions models.Permission `json:"permissions"`
}
type Invite struct {
Email string `json:"email"`
InvitingUser string `json:"inviting_user"`
Token string `json:"token"`
}
type MongoDbUserPassHandler struct {
collection *mongo.Collection
}
func (self *MongoDbUserPassHandler) AuthenticateUser(username string, password string) (models.Permission, error) {
var user AuthUser
err := self.collection.FindOne(context.Background(), bson.D{bson.E{Key: "username", Value: username}}).Decode(&user)
if err != nil {
return 0, err
}
hashedPassword, err := dbhandler.HashPassword(password)
if err != nil {
return 0, err
}
if user.HashedPassword != hashedPassword {
return 0, fmt.Errorf("Incorrect Password")
}
return user.Permissions, nil
}
func (self *MongoDbUserPassHandler) CreateUser(
username string,
password string,
permissions models.Permission,
) error {
hashedPassword, err := dbhandler.HashPassword(password)
if err != nil {
return err
}
_, err = self.collection.InsertOne(context.Background(), &AuthUser{
Username: username,
HashedPassword: hashedPassword,
Permissions: permissions,
})
return err
}
func (self *MongoDbUserPassHandler) RemoveUser(username string) error {
_, err := self.collection.DeleteOne(
context.Background(),
bson.D{
{Key: "username", Value: username},
},
)
return err
}
func (self *MongoDbUserPassHandler) SetPermissions(
username string,
permissions models.Permission,
) error {
return nil
}
func NewMMongoDbUserPassAuthHandler(config models.MongoDBConfig) (*MongoDbUserPassHandler, error) {
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
Username: config.Username,
Password: config.Password,
})
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
return nil, err
}
return &MongoDbUserPassHandler{
collection: client.Database(config.Database).Collection(config.Collection),
}, nil
}

View File

@ -1,4 +1,4 @@
package mongo package mongo_db_handlers
import ( import (
"context" "context"
@ -11,13 +11,11 @@ import (
) )
type MongoDbUserHandler struct { type MongoDbUserHandler struct {
con *mongo.Client collection *mongo.Collection
collectionName string
databaseName string
} }
func (self *MongoDbUserHandler) GetUser(username string) (*dbhandler.User, error) { func (self *MongoDbUserHandler) GetUser(username string) (*dbhandler.User, error) {
users, err := self.con.Database(self.databaseName).Collection(self.collectionName).Find(context.TODO(), bson.D{bson.E{Key: "username", Value: username}}) users, err := self.collection.Find(context.TODO(), bson.D{bson.E{Key: "username", Value: username}})
if err != nil { if err != nil {
return nil, err return nil, err
@ -34,7 +32,7 @@ func (self *MongoDbUserHandler) GetUser(username string) (*dbhandler.User, error
} }
func (self *MongoDbUserHandler) ListUsers() ([]dbhandler.User, error) { func (self *MongoDbUserHandler) ListUsers() ([]dbhandler.User, error) {
users, err := self.con.Database(self.databaseName).Collection(self.collectionName).Find(context.TODO(), bson.D{}) users, err := self.collection.Find(context.TODO(), bson.D{})
if err != nil { if err != nil {
return nil, err return nil, err
@ -48,7 +46,7 @@ func (self *MongoDbUserHandler) ListUsers() ([]dbhandler.User, error) {
func (self *MongoDbUserHandler) CreateUser(user dbhandler.User) error { func (self *MongoDbUserHandler) CreateUser(user dbhandler.User) error {
_, err := self.con.Database(self.databaseName).Collection(self.collectionName).InsertOne(context.TODO(), &dbhandler.User{ _, err := self.collection.InsertOne(context.TODO(), &dbhandler.User{
Username: user.Username, Username: user.Username,
Email: user.Email, Email: user.Email,
Nickname: user.Nickname, Nickname: user.Nickname,
@ -74,8 +72,6 @@ func NewMMongoDbUsersHandler(config models.MongoDBConfig) (*MongoDbUserHandler,
} }
return &MongoDbUserHandler{ return &MongoDbUserHandler{
con: client, collection: client.Database(config.Database).Collection(config.Collection),
databaseName: config.Database,
collectionName: config.Collection,
}, nil }, nil
} }

View File

@ -1,28 +0,0 @@
package mongo
import (
"context"
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func Connect(config *models.MongoDBConfig) (*mongo.Client, error) {
serverAPI := options.ServerAPI(options.ServerAPIVersion1)
opts := options.Client().ApplyURI(config.Url).SetServerAPIOptions(serverAPI)
opts.SetAuth(
options.Credential{
Username: config.Username,
Password: config.Password,
},
)
client, err := mongo.Connect(context.TODO(), opts)
if err != nil {
return nil, err
}
return client, nil
}

View File

@ -12,37 +12,6 @@ import (
"golang.org/x/oauth2" "golang.org/x/oauth2"
) )
type LoginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
type InviteUserRequest struct {
Email string `json:"email"`
InvitingUser string `json:"inviting_user"`
Permissions models.Permission `json:"permissions"`
}
type InviteToken struct {
Email string `json:"email"`
Permissions models.Permission `json:"permissions"`
Token string `json:"token"`
}
type UserSignupRequest struct {
Token InviteToken `json:"token"`
Username string `json:"username"`
Password string `json:"password"`
}
type UserPassAuthanticationDbHandler interface {
AuthenticateUser(LoginRequest) (models.Permission, error)
InviteUser(InviteUserRequest) (InviteToken, error)
UserSignup(UserSignupRequest) error
RemoveUser(string) error
SetPermissions(string, models.Permission) error
}
type CallbackRequest struct { type CallbackRequest struct {
Code string `json:"code"` Code string `json:"code"`
} }

View File

@ -0,0 +1,42 @@
package dbhandler
import (
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
"golang.org/x/crypto/bcrypt"
)
func HashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes), err
}
type InviteUserRequest struct {
Email string `json:"email"`
InvitingUser string `json:"inviting_user"`
Permissions models.Permission `json:"permissions"`
}
type InviteToken struct {
Email string `json:"email"`
Permissions models.Permission `json:"permissions"`
Token string `json:"token"`
}
type UserSignupRequest struct {
Token InviteToken `json:"token"`
Username string `json:"username"`
Password string `json:"password"`
}
type UserPassAuthanticationDbHandler interface {
AuthenticateUser(username string, password string) (models.Permission, error)
CreateUser(username string, password string, permissions models.Permission) error
RemoveUser(username string) error
SetPermissions(username string, permissions models.Permission) error
SetPassword(username string, password string) error
}
type InviteTokenDbHandler interface {
SaveInviteToken(token string, email string, permissions models.Permission) error
GetInviteToken(token string) (*InviteToken, error)
}

View File

@ -9,6 +9,6 @@ type User struct {
type UsersDBHandler interface { type UsersDBHandler interface {
GetUser(username string) (User, error) GetUser(username string) (User, error)
ListUsers() ([]User, error) ListUsers() ([]User, error)
CreateUser(User) error CreateUser(user User) error
DeleteUser(username string) error DeleteUser(username string) error
} }

View File

@ -9,31 +9,25 @@ import (
"git.acooldomain.co/server-manager/backend-kubernetes-go/models" "git.acooldomain.co/server-manager/backend-kubernetes-go/models"
) )
const EMAIL_SERVER_ENV_VAR = "EMAIL_SERVER" type MailClient struct {
const FROM_EMAIL_ENV_VAR = "FROM_EMAIL" auth *smtp.Auth
mailConfig *models.EmailConfig
var auth *smtp.Auth
var mailConfig *models.EmailConfig
func InitializeClient(config models.EmailConfig) error {
simpleAuth := smtp.PlainAuth("", config.Username, config.Password, config.Server)
auth = &simpleAuth
mailConfig = &config
return nil
} }
func SendMail( func NewMailClient(config models.EmailConfig) *MailClient {
simpleAuth := smtp.PlainAuth("", config.Username, config.Password, config.Server)
return &MailClient{
auth: &simpleAuth,
mailConfig: &config,
}
}
func (self *MailClient) SendMail(
recipient string, recipient string,
subject string, subject string,
content string, content string,
) error { ) error {
if auth == nil { from := mail.Address{Name: "", Address: self.mailConfig.FromEmail}
return fmt.Errorf("mail not initialized")
}
if mailConfig == nil {
return fmt.Errorf("mail not initialized")
}
from := mail.Address{Name: "", Address: mailConfig.FromEmail}
to := mail.Address{Name: "", Address: recipient} to := mail.Address{Name: "", Address: recipient}
headers := make(map[string]string) headers := make(map[string]string)
@ -47,21 +41,21 @@ func SendMail(
} }
message += "\r\n" + content message += "\r\n" + content
conn, err := tls.Dial("tcp", mailConfig.Server+":465", &tls.Config{ServerName: mailConfig.Server}) conn, err := tls.Dial("tcp", self.mailConfig.Server+":465", &tls.Config{ServerName: self.mailConfig.Server})
if err != nil { if err != nil {
return err return err
} }
client, err := smtp.NewClient(conn, mailConfig.Server) client, err := smtp.NewClient(conn, self.mailConfig.Server)
if err != nil { if err != nil {
return err return err
} }
if err = client.Auth(*auth); err != nil { if err = client.Auth(*self.auth); err != nil {
return err return err
} }
if err = client.Mail(mailConfig.FromEmail); err != nil { if err = client.Mail(self.mailConfig.FromEmail); err != nil {
return err return err
} }

8
models/auth.go Normal file
View File

@ -0,0 +1,8 @@
package models
type AuthMode string
const (
Oidc AuthMode = "OIDC"
UserPass AuthMode = "UserPass"
)