diff --git a/auth/auth.go b/auth/auth.go index 6040c89..489c0d1 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -19,22 +19,15 @@ import ( "golang.org/x/crypto/bcrypt" ) -type AuthMode string - var secret []byte var method string var DOMAIN string -const ( - Oidc AuthMode = "OIDC" - UserPass AuthMode = "UserPass" -) - type Connection struct { usersDbHandler dbhandler.UsersDBHandler authorizationDbHandler dbhandler.AuthorizationDbHandler - authMode AuthMode + authMode models.AuthMode userAuthDbHandler *dbhandler.UserPassAuthanticationDbHandler OidcAuthDbHandler *dbhandler.OidcAuthenticationDbHandler } @@ -69,11 +62,6 @@ func signToken(token Claims) (string, error) { 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 { return func(ctx *gin.Context) { authCookie, err := ctx.Request.Cookie("auth") diff --git a/db_handler/authorization_db_handler.go b/db_handler/authorization.go similarity index 100% rename from db_handler/authorization_db_handler.go rename to db_handler/authorization.go diff --git a/db_handler/mongo/mongo_authorization_db_handler.go b/db_handler/mongo/authorization_db_handler.go similarity index 99% rename from db_handler/mongo/mongo_authorization_db_handler.go rename to db_handler/mongo/authorization_db_handler.go index 8498573..7b93af3 100644 --- a/db_handler/mongo/mongo_authorization_db_handler.go +++ b/db_handler/mongo/authorization_db_handler.go @@ -1,4 +1,4 @@ -package mongo +package mongo_db_handlers import ( "context" diff --git a/db_handler/mongo/go.mod b/db_handler/mongo/go.mod index dfbcea5..d1df786 100644 --- a/db_handler/mongo/go.mod +++ b/db_handler/mongo/go.mod @@ -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 diff --git a/db_handler/mongo/user_pass_authentication_db_handler.go b/db_handler/mongo/user_pass_authentication_db_handler.go new file mode 100644 index 0000000..e933e34 --- /dev/null +++ b/db_handler/mongo/user_pass_authentication_db_handler.go @@ -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 +} diff --git a/db_handler/mongo/mongo_users_db_handler.go b/db_handler/mongo/users_db_handler.go similarity index 70% rename from db_handler/mongo/mongo_users_db_handler.go rename to db_handler/mongo/users_db_handler.go index 777d64e..8946f5c 100644 --- a/db_handler/mongo/mongo_users_db_handler.go +++ b/db_handler/mongo/users_db_handler.go @@ -1,4 +1,4 @@ -package mongo +package mongo_db_handlers import ( "context" @@ -11,13 +11,11 @@ import ( ) type MongoDbUserHandler struct { - con *mongo.Client - collectionName string - databaseName string + collection *mongo.Collection } 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 { return nil, err @@ -34,7 +32,7 @@ func (self *MongoDbUserHandler) GetUser(username string) (*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 { return nil, err @@ -48,7 +46,7 @@ func (self *MongoDbUserHandler) ListUsers() ([]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, Email: user.Email, Nickname: user.Nickname, @@ -74,8 +72,6 @@ func NewMMongoDbUsersHandler(config models.MongoDBConfig) (*MongoDbUserHandler, } return &MongoDbUserHandler{ - con: client, - databaseName: config.Database, - collectionName: config.Collection, + collection: client.Database(config.Database).Collection(config.Collection), }, nil } diff --git a/db_handler/mongo/utils.go b/db_handler/mongo/utils.go deleted file mode 100644 index 3ce5f36..0000000 --- a/db_handler/mongo/utils.go +++ /dev/null @@ -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 -} diff --git a/db_handler/authentication_db_handler.go b/db_handler/oidc_auth.go similarity index 66% rename from db_handler/authentication_db_handler.go rename to db_handler/oidc_auth.go index bcfb509..3638cdd 100644 --- a/db_handler/authentication_db_handler.go +++ b/db_handler/oidc_auth.go @@ -12,37 +12,6 @@ import ( "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 { Code string `json:"code"` } diff --git a/db_handler/user_pass_auth.go b/db_handler/user_pass_auth.go new file mode 100644 index 0000000..1e4c7f0 --- /dev/null +++ b/db_handler/user_pass_auth.go @@ -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) +} diff --git a/db_handler/users_db_handler.go b/db_handler/users.go similarity index 90% rename from db_handler/users_db_handler.go rename to db_handler/users.go index 39e289f..eba3f92 100644 --- a/db_handler/users_db_handler.go +++ b/db_handler/users.go @@ -9,6 +9,6 @@ type User struct { type UsersDBHandler interface { GetUser(username string) (User, error) ListUsers() ([]User, error) - CreateUser(User) error + CreateUser(user User) error DeleteUser(username string) error } diff --git a/mail/mail.go b/mail/mail.go index 5f1721d..8e9821c 100644 --- a/mail/mail.go +++ b/mail/mail.go @@ -9,31 +9,25 @@ import ( "git.acooldomain.co/server-manager/backend-kubernetes-go/models" ) -const EMAIL_SERVER_ENV_VAR = "EMAIL_SERVER" -const FROM_EMAIL_ENV_VAR = "FROM_EMAIL" - -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 +type MailClient struct { + auth *smtp.Auth + mailConfig *models.EmailConfig } -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, subject string, content string, ) error { - if auth == nil { - return fmt.Errorf("mail not initialized") - } - if mailConfig == nil { - return fmt.Errorf("mail not initialized") - } - from := mail.Address{Name: "", Address: mailConfig.FromEmail} + from := mail.Address{Name: "", Address: self.mailConfig.FromEmail} to := mail.Address{Name: "", Address: recipient} headers := make(map[string]string) @@ -47,21 +41,21 @@ func SendMail( } 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 { return err } - client, err := smtp.NewClient(conn, mailConfig.Server) + client, err := smtp.NewClient(conn, self.mailConfig.Server) if err != nil { return err } - if err = client.Auth(*auth); err != nil { + if err = client.Auth(*self.auth); err != nil { return err } - if err = client.Mail(mailConfig.FromEmail); err != nil { + if err = client.Mail(self.mailConfig.FromEmail); err != nil { return err } diff --git a/models/auth.go b/models/auth.go new file mode 100644 index 0000000..47661d4 --- /dev/null +++ b/models/auth.go @@ -0,0 +1,8 @@ +package models + +type AuthMode string + +const ( + Oidc AuthMode = "OIDC" + UserPass AuthMode = "UserPass" +)