refactored
This commit is contained in:
1
dbhandler/db_handler.go
Normal file
1
dbhandler/db_handler.go
Normal file
@@ -0,0 +1 @@
|
||||
package dbhandler
|
3
dbhandler/go.mod
Normal file
3
dbhandler/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module git.acooldomain.co/server-manager/backend/dbhandler
|
||||
|
||||
go 1.22.0
|
19
dbhandler/mongo/go.mod
Normal file
19
dbhandler/mongo/go.mod
Normal file
@@ -0,0 +1,19 @@
|
||||
module git.acooldomain.co/server-manager/backend/dbhandler/mongo
|
||||
|
||||
go 1.24.1
|
||||
|
||||
require go.mongodb.org/mongo-driver v1.14.0
|
||||
|
||||
require (
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
)
|
13
dbhandler/mongo/go.sum
Normal file
13
dbhandler/mongo/go.sum
Normal file
@@ -0,0 +1,13 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
|
||||
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
192
dbhandler/mongo/servers.go
Normal file
192
dbhandler/mongo/servers.go
Normal file
@@ -0,0 +1,192 @@
|
||||
package mongo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend/dbhandler"
|
||||
"git.acooldomain.co/server-manager/backend/models"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type Image struct {
|
||||
Registry string `bson:"registry"`
|
||||
Tag string `bson:"tag"`
|
||||
}
|
||||
|
||||
type Port struct {
|
||||
PublicPort uint16 `bson:"public_port"`
|
||||
ContainerPort uint16 `bson:"container_port"`
|
||||
Protocol models.PortProtocol `bson:"protocol"`
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Id string `bson:"id"`
|
||||
Owner string `bson:"owner"`
|
||||
Image Image `bson:"image"`
|
||||
Nickname string `bson:"nickname"`
|
||||
Command string `bson:"command"`
|
||||
Ports []Port `bson:"ports"`
|
||||
}
|
||||
|
||||
func convertToDbServer(server dbhandler.Server) Server {
|
||||
ports := make([]Port, len(server.Ports))
|
||||
|
||||
for i, port := range server.Ports {
|
||||
ports[i] = Port{
|
||||
PublicPort: port.PublicPort,
|
||||
ContainerPort: port.ContainerPort,
|
||||
Protocol: port.Protocol,
|
||||
}
|
||||
}
|
||||
|
||||
return Server{
|
||||
Id: server.Id,
|
||||
Owner: server.Owner,
|
||||
Image: Image{
|
||||
Registry: server.Image.Registry,
|
||||
Tag: server.Image.Tag,
|
||||
},
|
||||
Nickname: server.Nickname,
|
||||
Command: server.Command,
|
||||
Ports: ports,
|
||||
}
|
||||
}
|
||||
|
||||
func convertToResponseServer(server Server) dbhandler.Server {
|
||||
ports := make([]models.Port, len(server.Ports))
|
||||
|
||||
for i, port := range server.Ports {
|
||||
ports[i] = models.Port{
|
||||
PublicPort: port.PublicPort,
|
||||
ContainerPort: port.ContainerPort,
|
||||
Protocol: port.Protocol,
|
||||
}
|
||||
}
|
||||
|
||||
return dbhandler.Server{
|
||||
Id: server.Id,
|
||||
Owner: server.Owner,
|
||||
Image: &models.Image{
|
||||
Registry: server.Image.Registry,
|
||||
Tag: server.Image.Tag,
|
||||
},
|
||||
Nickname: server.Nickname,
|
||||
Command: server.Command,
|
||||
Ports: ports,
|
||||
}
|
||||
}
|
||||
|
||||
type ServersDbHandler struct {
|
||||
dbhandler.ServersDbHandler
|
||||
collection *mongo.Collection
|
||||
}
|
||||
|
||||
func (self *ServersDbHandler) ListServers(ctx context.Context) ([]dbhandler.Server, error) {
|
||||
var servers []Server
|
||||
cursor, err := self.collection.Find(ctx, bson.M{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
|
||||
err = cursor.All(ctx, &servers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dbServers := make([]dbhandler.Server, len(servers))
|
||||
|
||||
for i, server := range servers {
|
||||
dbServers[i] = convertToResponseServer(server)
|
||||
}
|
||||
|
||||
return dbServers, nil
|
||||
}
|
||||
|
||||
func (self *ServersDbHandler) GetServer(ctx context.Context, serverId string) (*dbhandler.Server, error) {
|
||||
var server Server
|
||||
err := self.collection.FindOne(ctx, bson.M{"server_id": serverId}).Decode(&server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
responseServer := convertToResponseServer(server)
|
||||
|
||||
return &responseServer, nil
|
||||
}
|
||||
|
||||
func (self *ServersDbHandler) CreateServer(ctx context.Context, server dbhandler.Server) error {
|
||||
dbServer := convertToDbServer(server)
|
||||
_, err := self.collection.InsertOne(ctx, &dbServer)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *ServersDbHandler) DeleteServer(ctx context.Context, serverId string) error {
|
||||
_, err := self.collection.DeleteOne(ctx, bson.M{
|
||||
"server_id": serverId,
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *ServersDbHandler) UpdateServer(ctx context.Context, serverId string, updateParams dbhandler.ServerUpdateRequest) error {
|
||||
updateServerRequest := bson.M{}
|
||||
|
||||
if updateParams.Owner != "" {
|
||||
updateServerRequest["owner"] = updateParams.Owner
|
||||
}
|
||||
|
||||
if updateParams.Image != nil {
|
||||
updateServerRequest["image"] = bson.M{
|
||||
"registry": updateParams.Image.Registry,
|
||||
"tag": updateParams.Image.Tag,
|
||||
}
|
||||
}
|
||||
|
||||
if updateParams.Ports != nil {
|
||||
ports := make([]bson.M, len(updateParams.Ports))
|
||||
for i, port := range updateParams.Ports {
|
||||
ports[i] = bson.M{
|
||||
"number": port.PublicPort,
|
||||
"protocol": port.Protocol,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if updateParams.Nickname != "" {
|
||||
updateServerRequest["nickname"] = updateParams.Nickname
|
||||
}
|
||||
|
||||
if updateParams.Command != "" {
|
||||
updateServerRequest["command"] = updateParams.Command
|
||||
}
|
||||
|
||||
_, err := self.collection.UpdateOne(ctx, bson.M{"server_id": serverId}, bson.M{"$set": updateServerRequest})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func NewServersDbHandler(config models.MongoDBConfig) (*ServersDbHandler, error) {
|
||||
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
})
|
||||
|
||||
ctx, cancel := context.WithTimeoutCause(context.Background(), 30*time.Second, fmt.Errorf("Timeout"))
|
||||
defer cancel()
|
||||
|
||||
client, err := mongo.Connect(ctx, clientOptions)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ServersDbHandler{
|
||||
collection: client.Database(config.Database).Collection(config.Collection),
|
||||
}, nil
|
||||
}
|
161
dbhandler/mongo/servers_authorization.go
Normal file
161
dbhandler/mongo/servers_authorization.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package mongo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend/dbhandler"
|
||||
"git.acooldomain.co/server-manager/backend/models"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type ServerPermissions struct {
|
||||
Username string `bson:"username"`
|
||||
ServerId string `bson:"server_id"`
|
||||
Permissions models.Permission `bson:"permissions"`
|
||||
}
|
||||
|
||||
type ServersAuthorizationDbHandler struct {
|
||||
dbhandler.ServersAuthorizationDbHandler
|
||||
collection *mongo.Collection
|
||||
}
|
||||
|
||||
func (self *ServersAuthorizationDbHandler) RemoveUser(ctx context.Context, username string) error {
|
||||
_, err := self.collection.DeleteMany(
|
||||
ctx,
|
||||
bson.M{
|
||||
"username": username,
|
||||
},
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *ServersAuthorizationDbHandler) RemoveServer(ctx context.Context, serverId string) error {
|
||||
_, err := self.collection.DeleteMany(
|
||||
ctx,
|
||||
bson.M{
|
||||
"server_id": serverId,
|
||||
},
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *ServersAuthorizationDbHandler) AddPermissions(ctx context.Context, username string, serverId string, permissions models.Permission) error {
|
||||
var serverPermissions ServerPermissions
|
||||
err := self.collection.FindOne(
|
||||
ctx,
|
||||
bson.M{
|
||||
"username": username,
|
||||
"server_id": serverId,
|
||||
},
|
||||
).Decode(&serverPermissions)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newPermissions := serverPermissions.Permissions | permissions
|
||||
|
||||
_, err = self.collection.UpdateOne(
|
||||
ctx,
|
||||
bson.M{
|
||||
"username": username,
|
||||
"server_id": serverId,
|
||||
},
|
||||
bson.M{"$set": bson.M{
|
||||
"permissions": newPermissions,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *ServersAuthorizationDbHandler) RemovePermissions(ctx context.Context, username string, serverId string, permissions models.Permission) error {
|
||||
var serverPermissions ServerPermissions
|
||||
err := self.collection.FindOne(
|
||||
ctx,
|
||||
bson.M{
|
||||
"username": username,
|
||||
"server_id": serverId,
|
||||
},
|
||||
).Decode(&serverPermissions)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newPermissions := serverPermissions.Permissions | permissions ^ permissions
|
||||
|
||||
_, err = self.collection.UpdateOne(
|
||||
ctx,
|
||||
bson.M{
|
||||
"username": username,
|
||||
"server_id": serverId,
|
||||
},
|
||||
bson.M{"$set": bson.M{
|
||||
"permissions": newPermissions,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *ServersAuthorizationDbHandler) SetPermissions(ctx context.Context, username string, serverId string, permissions models.Permission) error {
|
||||
_, err := self.collection.UpdateOne(
|
||||
ctx,
|
||||
bson.M{
|
||||
"username": username,
|
||||
"server_id": serverId,
|
||||
},
|
||||
bson.M{"$set": bson.M{
|
||||
"permissions": permissions,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *ServersAuthorizationDbHandler) GetPermissions(ctx context.Context, username string, serverId string) (models.Permission, error) {
|
||||
var serverPermissions ServerPermissions
|
||||
err := self.collection.FindOne(
|
||||
ctx,
|
||||
bson.M{
|
||||
"username": username,
|
||||
"server_id": serverId,
|
||||
},
|
||||
).Decode(&serverPermissions)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return serverPermissions.Permissions, nil
|
||||
}
|
||||
|
||||
func NewServersAuthorizationHandler(config models.MongoDBConfig) (*ServersAuthorizationDbHandler, error) {
|
||||
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
})
|
||||
|
||||
ctx, cancel := context.WithTimeoutCause(context.Background(), 30*time.Second, fmt.Errorf("Timeout"))
|
||||
defer cancel()
|
||||
|
||||
client, err := mongo.Connect(ctx, clientOptions)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ServersAuthorizationDbHandler{
|
||||
collection: client.Database(config.Database).Collection(config.Collection),
|
||||
}, nil
|
||||
}
|
216
dbhandler/mongo/user_pass_authentication.go
Normal file
216
dbhandler/mongo/user_pass_authentication.go
Normal file
@@ -0,0 +1,216 @@
|
||||
package mongo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend/dbhandler"
|
||||
"git.acooldomain.co/server-manager/backend/models"
|
||||
"github.com/google/uuid"
|
||||
"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"`
|
||||
Nickname string `json:"nickname"`
|
||||
HashedPassword string `json:"hashed_password"`
|
||||
Permissions models.Permission `json:"permissions"`
|
||||
MaxOwnedSevers uint `json:"max_owned_severs"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
type UserPassAuthenticationDbHandler struct {
|
||||
dbhandler.UserPassAuthanticationDbHandler
|
||||
collection *mongo.Collection
|
||||
}
|
||||
|
||||
func (self *UserPassAuthenticationDbHandler) ListUsers(ctx context.Context) ([]models.User, error) {
|
||||
cursor, err := self.collection.Find(ctx, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var authUsers []AuthUser
|
||||
|
||||
cursor.All(ctx, &authUsers)
|
||||
|
||||
modelUsers := make([]models.User, len(authUsers))
|
||||
for i, authUser := range authUsers {
|
||||
modelUsers[i] = models.User{
|
||||
Username: authUser.Username,
|
||||
Nickname: authUser.Nickname,
|
||||
Email: authUser.Email,
|
||||
MaxOwnedServers: authUser.MaxOwnedSevers,
|
||||
Permissions: authUser.Permissions,
|
||||
}
|
||||
}
|
||||
|
||||
return modelUsers, nil
|
||||
}
|
||||
|
||||
func (self *UserPassAuthenticationDbHandler) AuthenticateUser(ctx context.Context, username string, password string) (*models.User, error) {
|
||||
var user AuthUser
|
||||
err := self.collection.FindOne(ctx, bson.M{"username": username}).Decode(&user)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hashedPassword, err := dbhandler.HashPassword(password)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if user.HashedPassword != hashedPassword {
|
||||
return nil, fmt.Errorf("Incorrect Password")
|
||||
}
|
||||
|
||||
return &models.User{
|
||||
Username: user.Username,
|
||||
Nickname: user.Nickname,
|
||||
Email: user.Email,
|
||||
MaxOwnedServers: user.MaxOwnedSevers,
|
||||
Permissions: user.Permissions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (self *UserPassAuthenticationDbHandler) CreateUser(
|
||||
ctx context.Context,
|
||||
username string,
|
||||
password string,
|
||||
permissions models.Permission,
|
||||
email string,
|
||||
maxOwnedServers uint,
|
||||
) error {
|
||||
hashedPassword, err := dbhandler.HashPassword(password)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = self.collection.InsertOne(ctx, &AuthUser{
|
||||
Username: username,
|
||||
HashedPassword: hashedPassword,
|
||||
Permissions: permissions,
|
||||
Email: email,
|
||||
MaxOwnedSevers: maxOwnedServers,
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *UserPassAuthenticationDbHandler) RemoveUser(ctx context.Context, username string) error {
|
||||
_, err := self.collection.DeleteOne(
|
||||
ctx,
|
||||
bson.M{
|
||||
"username": username,
|
||||
},
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *UserPassAuthenticationDbHandler) SetPermissions(
|
||||
ctx context.Context,
|
||||
username string,
|
||||
permissions models.Permission,
|
||||
) error {
|
||||
_, err := self.collection.UpdateOne(
|
||||
ctx,
|
||||
bson.M{
|
||||
"username": username,
|
||||
},
|
||||
bson.M{
|
||||
"$set": bson.M{
|
||||
"permissions": permissions,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func NewUserPassAuthHandler(config models.MongoDBConfig) (*UserPassAuthenticationDbHandler, error) {
|
||||
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
})
|
||||
|
||||
ctx, cancel := context.WithTimeoutCause(context.Background(), 30*time.Second, fmt.Errorf("Timeout"))
|
||||
defer cancel()
|
||||
|
||||
client, err := mongo.Connect(ctx, clientOptions)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &UserPassAuthenticationDbHandler{
|
||||
collection: client.Database(config.Database).Collection(config.Collection),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type InviteToken struct {
|
||||
Email string `json:"email"`
|
||||
Token string `json:"token"`
|
||||
Permissions models.Permission `json:"permissions"`
|
||||
}
|
||||
|
||||
type InviteTokenDbHandler struct {
|
||||
dbhandler.InviteTokenDbHandler
|
||||
collection *mongo.Collection
|
||||
}
|
||||
|
||||
func (self *ServersDbHandler) SaveInviteToken(ctx context.Context, email string, permissions models.Permission) (string, error) {
|
||||
token := uuid.NewString()
|
||||
|
||||
_, err := self.collection.InsertOne(ctx, &InviteToken{
|
||||
Permissions: permissions,
|
||||
Email: email,
|
||||
Token: token,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (self *ServersDbHandler) GetInviteToken(ctx context.Context, token string) (*dbhandler.InviteToken, error) {
|
||||
var inviteToken InviteToken
|
||||
err := self.collection.FindOne(ctx, bson.M{"token": token}).Decode(&inviteToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dbhandler.InviteToken{
|
||||
Email: inviteToken.Email,
|
||||
Permissions: inviteToken.Permissions,
|
||||
Token: inviteToken.Token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewInviteTokenDbHandler(config models.MongoDBConfig) (*InviteTokenDbHandler, error) {
|
||||
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
})
|
||||
|
||||
ctx, cancel := context.WithTimeoutCause(context.Background(), 30*time.Second, fmt.Errorf("Timeout"))
|
||||
defer cancel()
|
||||
|
||||
client, err := mongo.Connect(ctx, clientOptions)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &InviteTokenDbHandler{
|
||||
collection: client.Database(config.Database).Collection(config.Collection),
|
||||
}, nil
|
||||
}
|
78
dbhandler/oidc_auth.go
Normal file
78
dbhandler/oidc_auth.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package dbhandler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend/models"
|
||||
"github.com/coreos/go-oidc"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
type CallbackRequest struct {
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
type OidcClaims struct {
|
||||
Email string
|
||||
Profile string
|
||||
Permissions models.Permission
|
||||
}
|
||||
|
||||
type OidcAuthenticationDbHandler struct {
|
||||
provider *oidc.Provider
|
||||
oauth2Config *oauth2.Config
|
||||
}
|
||||
|
||||
func GenerateOidcState() string {
|
||||
b := make([]byte, 16)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return base64.URLEncoding.EncodeToString(b)
|
||||
}
|
||||
|
||||
func (self *OidcAuthenticationDbHandler) AuthenticateUser(ctx context.Context, request CallbackRequest) (models.Permission, error) {
|
||||
token, err := self.oauth2Config.Exchange(ctx, request.Code)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
verifier := self.provider.Verifier(&oidc.Config{ClientID: self.oauth2Config.ClientID})
|
||||
idToken, ok := token.Extra("id_token").(string)
|
||||
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("Failed to convert id_token to string")
|
||||
}
|
||||
|
||||
tokenObj, err := verifier.Verify(ctx, idToken)
|
||||
var claims OidcClaims
|
||||
|
||||
if err := tokenObj.Claims(&claims); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return claims.Permissions, nil
|
||||
}
|
||||
|
||||
func NewOidcAuthenticationDbHamdler(config models.OidcAuthConfig) (*OidcAuthenticationDbHandler, error) {
|
||||
provider, err := oidc.NewProvider(context.Background(), config.IssuerUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &OidcAuthenticationDbHandler{
|
||||
provider: provider,
|
||||
oauth2Config: &oauth2.Config{
|
||||
ClientID: config.ClientId,
|
||||
ClientSecret: config.ClientSecret,
|
||||
Endpoint: provider.Endpoint(),
|
||||
Scopes: []string{oidc.ScopeOpenID, "email", "name", "profile"},
|
||||
},
|
||||
}, nil
|
||||
}
|
32
dbhandler/servers.go
Normal file
32
dbhandler/servers.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package dbhandler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend/models"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
Id string
|
||||
Owner string
|
||||
Image *models.Image
|
||||
Nickname string
|
||||
Command string
|
||||
Ports []models.Port
|
||||
}
|
||||
|
||||
type ServerUpdateRequest struct {
|
||||
Owner string
|
||||
Image *models.Image
|
||||
Nickname string
|
||||
Command string
|
||||
Ports []models.Port
|
||||
}
|
||||
|
||||
type ServersDbHandler interface {
|
||||
ListServers(ctx context.Context) ([]Server, error)
|
||||
GetServer(ctx context.Context, serverId string) (*Server, error)
|
||||
CreateServer(ctx context.Context, server Server) error
|
||||
DeleteServer(ctx context.Context, serverId string) error
|
||||
UpdateServer(ctx context.Context, serverId string, updateParams ServerUpdateRequest) error
|
||||
}
|
16
dbhandler/servers_authorization.go
Normal file
16
dbhandler/servers_authorization.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package dbhandler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend/models"
|
||||
)
|
||||
|
||||
type ServersAuthorizationDbHandler interface {
|
||||
AddPermissions(ctx context.Context, username string, server_id string, permissions models.Permission) error
|
||||
RemovePermissions(ctx context.Context, string, server_id string, permissions models.Permission) error
|
||||
SetPermissions(ctx context.Context, username string, server_id string, permissions models.Permission) error
|
||||
GetPermissions(ctx context.Context, username string, server_id string) (models.Permission, error)
|
||||
RemoveUser(ctx context.Context, username string) error
|
||||
RemoveServer(ctx context.Context, server_id string) error
|
||||
}
|
42
dbhandler/user_pass_auth.go
Normal file
42
dbhandler/user_pass_auth.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package dbhandler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend/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 InviteToken struct {
|
||||
Email string
|
||||
Permissions models.Permission
|
||||
Token string
|
||||
}
|
||||
|
||||
type UserSignupRequest struct {
|
||||
Token InviteToken
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
type UserPassAuthanticationDbHandler interface {
|
||||
// Read Only
|
||||
AuthenticateUser(ctx context.Context, username string, password string) (*models.User, error)
|
||||
ListUsers(ctx context.Context) ([]models.User, error)
|
||||
|
||||
// Write
|
||||
CreateUser(ctx context.Context, username string, password string, permissions models.Permission, email string, maxOwnedServers uint) error
|
||||
RemoveUser(ctx context.Context, username string) error
|
||||
SetPermissions(ctx context.Context, username string, permissions models.Permission) error
|
||||
SetPassword(ctx context.Context, username string, password string) error
|
||||
}
|
||||
|
||||
type InviteTokenDbHandler interface {
|
||||
SaveInviteToken(ctx context.Context, email string, permissions models.Permission) (string, error)
|
||||
GetInviteToken(ctx context.Context, token string) (*InviteToken, error)
|
||||
}
|
Reference in New Issue
Block a user