forked from mirrors/homebox
align types with new db schema
This commit is contained in:
parent
63cfeffc4d
commit
b83505104a
30 changed files with 1491 additions and 263 deletions
|
@ -10,4 +10,5 @@ type SeedUser struct {
|
|||
type Seed struct {
|
||||
Enabled bool `yaml:"enabled" conf:"default:false"`
|
||||
Users []SeedUser `yaml:"users"`
|
||||
Group string `yaml:"group"`
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
// Code generated by "/pkgs/automapper"; DO NOT EDIT.
|
||||
package mapper
|
||||
|
||||
import (
|
||||
"github.com/hay-kot/content/backend/ent"
|
||||
"github.com/hay-kot/content/backend/internal/types"
|
||||
)
|
||||
|
||||
func UserOutFromModel(from ent.User) types.UserOut {
|
||||
return types.UserOut{
|
||||
ID: from.ID,
|
||||
Name: from.Name,
|
||||
Email: from.Email,
|
||||
Password: from.Password,
|
||||
IsSuperuser: from.IsSuperuser,
|
||||
}
|
||||
}
|
||||
|
||||
func UserOutToModel(from types.UserOut) ent.User {
|
||||
return ent.User{
|
||||
ID: from.ID,
|
||||
Name: from.Name,
|
||||
Email: from.Email,
|
||||
Password: from.Password,
|
||||
IsSuperuser: from.IsSuperuser,
|
||||
}
|
||||
}
|
29
backend/internal/repo/repo_group.go
Normal file
29
backend/internal/repo/repo_group.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/content/backend/ent"
|
||||
)
|
||||
|
||||
type EntGroupRepository struct {
|
||||
db *ent.Client
|
||||
}
|
||||
|
||||
func (r *EntGroupRepository) Create(ctx context.Context, name string) (*ent.Group, error) {
|
||||
dbGroup, err := r.db.Group.Create().SetName(name).Save(ctx)
|
||||
|
||||
if err != nil {
|
||||
return dbGroup, err
|
||||
}
|
||||
return dbGroup, nil
|
||||
}
|
||||
|
||||
func (r *EntGroupRepository) GetOneId(ctx context.Context, id uuid.UUID) (*ent.Group, error) {
|
||||
dbGroup, err := r.db.Group.Get(ctx, id)
|
||||
if err != nil {
|
||||
return dbGroup, err
|
||||
}
|
||||
return dbGroup, nil
|
||||
}
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/hay-kot/content/backend/ent"
|
||||
"github.com/hay-kot/content/backend/ent/authtokens"
|
||||
"github.com/hay-kot/content/backend/internal/mapper"
|
||||
"github.com/hay-kot/content/backend/internal/types"
|
||||
)
|
||||
|
||||
|
@ -15,7 +14,7 @@ type EntTokenRepository struct {
|
|||
}
|
||||
|
||||
// GetUserFromToken get's a user from a token
|
||||
func (r *EntTokenRepository) GetUserFromToken(ctx context.Context, token []byte) (types.UserOut, error) {
|
||||
func (r *EntTokenRepository) GetUserFromToken(ctx context.Context, token []byte) (*ent.User, error) {
|
||||
dbToken, err := r.db.AuthTokens.Query().
|
||||
Where(authtokens.Token(token)).
|
||||
Where(authtokens.ExpiresAtGTE(time.Now())).
|
||||
|
@ -23,10 +22,10 @@ func (r *EntTokenRepository) GetUserFromToken(ctx context.Context, token []byte)
|
|||
Only(ctx)
|
||||
|
||||
if err != nil {
|
||||
return types.UserOut{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mapper.UserOutFromModel(*dbToken.Edges.User), nil
|
||||
return dbToken.Edges.User, nil
|
||||
}
|
||||
|
||||
// Creates a token for a user
|
|
@ -13,66 +13,41 @@ type EntUserRepository struct {
|
|||
db *ent.Client
|
||||
}
|
||||
|
||||
func (e *EntUserRepository) toUserOut(usr *types.UserOut, entUsr *ent.User) {
|
||||
usr.ID = entUsr.ID
|
||||
usr.Password = entUsr.Password
|
||||
usr.Name = entUsr.Name
|
||||
usr.Email = entUsr.Email
|
||||
usr.IsSuperuser = entUsr.IsSuperuser
|
||||
}
|
||||
|
||||
func (e *EntUserRepository) GetOneId(ctx context.Context, id uuid.UUID) (types.UserOut, error) {
|
||||
func (e *EntUserRepository) GetOneId(ctx context.Context, id uuid.UUID) (*ent.User, error) {
|
||||
usr, err := e.db.User.Query().Where(user.ID(id)).Only(ctx)
|
||||
|
||||
usrOut := types.UserOut{}
|
||||
|
||||
if err != nil {
|
||||
return usrOut, err
|
||||
return usr, err
|
||||
}
|
||||
|
||||
e.toUserOut(&usrOut, usr)
|
||||
|
||||
return usrOut, nil
|
||||
return usr, nil
|
||||
}
|
||||
|
||||
func (e *EntUserRepository) GetOneEmail(ctx context.Context, email string) (types.UserOut, error) {
|
||||
func (e *EntUserRepository) GetOneEmail(ctx context.Context, email string) (*ent.User, error) {
|
||||
usr, err := e.db.User.Query().Where(user.Email(email)).Only(ctx)
|
||||
|
||||
usrOut := types.UserOut{}
|
||||
|
||||
if err != nil {
|
||||
return usrOut, err
|
||||
return usr, err
|
||||
}
|
||||
|
||||
e.toUserOut(&usrOut, usr)
|
||||
|
||||
return usrOut, nil
|
||||
return usr, nil
|
||||
}
|
||||
|
||||
func (e *EntUserRepository) GetAll(ctx context.Context) ([]types.UserOut, error) {
|
||||
func (e *EntUserRepository) GetAll(ctx context.Context) ([]*ent.User, error) {
|
||||
users, err := e.db.User.Query().All(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var usrs []types.UserOut
|
||||
|
||||
for _, usr := range users {
|
||||
usrOut := types.UserOut{}
|
||||
e.toUserOut(&usrOut, usr)
|
||||
usrs = append(usrs, usrOut)
|
||||
}
|
||||
|
||||
return usrs, nil
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (e *EntUserRepository) Create(ctx context.Context, usr types.UserCreate) (types.UserOut, error) {
|
||||
func (e *EntUserRepository) Create(ctx context.Context, usr types.UserCreate) (*ent.User, error) {
|
||||
err := usr.Validate()
|
||||
usrOut := types.UserOut{}
|
||||
|
||||
if err != nil {
|
||||
return usrOut, err
|
||||
return &ent.User{}, err
|
||||
}
|
||||
|
||||
entUser, err := e.db.User.
|
||||
|
@ -81,11 +56,10 @@ func (e *EntUserRepository) Create(ctx context.Context, usr types.UserCreate) (t
|
|||
SetEmail(usr.Email).
|
||||
SetPassword(usr.Password).
|
||||
SetIsSuperuser(usr.IsSuperuser).
|
||||
SetGroupID(usr.GroupID).
|
||||
Save(ctx)
|
||||
|
||||
e.toUserOut(&usrOut, entUser)
|
||||
|
||||
return usrOut, err
|
||||
return entUser, err
|
||||
}
|
||||
|
||||
func (e *EntUserRepository) Update(ctx context.Context, ID uuid.UUID, data types.UserUpdate) error {
|
||||
|
@ -122,20 +96,12 @@ func (e *EntUserRepository) DeleteAll(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (e *EntUserRepository) GetSuperusers(ctx context.Context) ([]types.UserOut, error) {
|
||||
func (e *EntUserRepository) GetSuperusers(ctx context.Context) ([]*ent.User, error) {
|
||||
users, err := e.db.User.Query().Where(user.IsSuperuser(true)).All(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var usrs []types.UserOut
|
||||
|
||||
for _, usr := range users {
|
||||
usrOut := types.UserOut{}
|
||||
e.toUserOut(&usrOut, usr)
|
||||
usrs = append(usrs, usrOut)
|
||||
}
|
||||
|
||||
return usrs, nil
|
||||
return users, nil
|
||||
}
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hay-kot/content/backend/ent"
|
||||
"github.com/hay-kot/content/backend/internal/types"
|
||||
"github.com/hay-kot/content/backend/pkgs/faker"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -66,7 +67,7 @@ func Test_EntUserRepo_GetAll(t *testing.T) {
|
|||
|
||||
ctx := context.Background()
|
||||
|
||||
created := []types.UserOut{}
|
||||
created := []*ent.User{}
|
||||
|
||||
for _, usr := range toCreate {
|
||||
usrOut, _ := testRepos.Users.Create(ctx, usr)
|
|
@ -4,13 +4,15 @@ import "github.com/hay-kot/content/backend/ent"
|
|||
|
||||
// AllRepos is a container for all the repository interfaces
|
||||
type AllRepos struct {
|
||||
Users UserRepository
|
||||
AuthTokens TokenRepository
|
||||
Users *EntUserRepository
|
||||
AuthTokens *EntTokenRepository
|
||||
Groups *EntGroupRepository
|
||||
}
|
||||
|
||||
func EntAllRepos(db *ent.Client) *AllRepos {
|
||||
return &AllRepos{
|
||||
Users: &EntUserRepository{db},
|
||||
AuthTokens: &EntTokenRepository{db},
|
||||
Groups: &EntGroupRepository{db},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hay-kot/content/backend/internal/types"
|
||||
)
|
||||
|
||||
type TokenRepository interface {
|
||||
// GetUserFromToken get's a user from a token
|
||||
GetUserFromToken(ctx context.Context, token []byte) (types.UserOut, error)
|
||||
// Creates a token for a user
|
||||
CreateToken(ctx context.Context, createToken types.UserAuthTokenCreate) (types.UserAuthToken, error)
|
||||
// DeleteToken remove a single token from the database - equivalent to revoke or logout
|
||||
DeleteToken(ctx context.Context, token []byte) error
|
||||
// PurgeExpiredTokens removes all expired tokens from the database
|
||||
PurgeExpiredTokens(ctx context.Context) (int, error)
|
||||
// DeleteAll removes all tokens from the database
|
||||
DeleteAll(ctx context.Context) (int, error)
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/content/backend/internal/types"
|
||||
)
|
||||
|
||||
type UserRepository interface {
|
||||
// GetOneId returns a user by id
|
||||
GetOneId(ctx context.Context, ID uuid.UUID) (types.UserOut, error)
|
||||
// GetOneEmail returns a user by email
|
||||
GetOneEmail(ctx context.Context, email string) (types.UserOut, error)
|
||||
// GetAll returns all users
|
||||
GetAll(ctx context.Context) ([]types.UserOut, error)
|
||||
// Get Super Users
|
||||
GetSuperusers(ctx context.Context) ([]types.UserOut, error)
|
||||
// Create creates a new user
|
||||
Create(ctx context.Context, user types.UserCreate) (types.UserOut, error)
|
||||
// Update updates a user
|
||||
Update(ctx context.Context, ID uuid.UUID, user types.UserUpdate) error
|
||||
// Delete deletes a user
|
||||
Delete(ctx context.Context, ID uuid.UUID) error
|
||||
|
||||
DeleteAll(ctx context.Context) error
|
||||
}
|
|
@ -3,7 +3,7 @@ package services
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hay-kot/content/backend/internal/types"
|
||||
"github.com/hay-kot/content/backend/ent"
|
||||
)
|
||||
|
||||
type contextKeys struct {
|
||||
|
@ -17,16 +17,16 @@ var (
|
|||
|
||||
// SetUserCtx is a helper function that sets the ContextUser and ContextUserToken
|
||||
// values within the context of a web request (or any context).
|
||||
func SetUserCtx(ctx context.Context, user *types.UserOut, token string) context.Context {
|
||||
func SetUserCtx(ctx context.Context, user *ent.User, token string) context.Context {
|
||||
ctx = context.WithValue(ctx, ContextUser, user)
|
||||
ctx = context.WithValue(ctx, ContextUserToken, token)
|
||||
return ctx
|
||||
}
|
||||
|
||||
// UseUserCtx is a helper function that returns the user from the context.
|
||||
func UseUserCtx(ctx context.Context) *types.UserOut {
|
||||
func UseUserCtx(ctx context.Context) *ent.User {
|
||||
if val := ctx.Value(ContextUser); val != nil {
|
||||
return val.(*types.UserOut)
|
||||
return val.(*ent.User)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/content/backend/internal/types"
|
||||
"github.com/hay-kot/content/backend/ent"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_SetAuthContext(t *testing.T) {
|
||||
user := &types.UserOut{
|
||||
user := &ent.User{
|
||||
ID: uuid.New(),
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/content/backend/ent"
|
||||
"github.com/hay-kot/content/backend/internal/repo"
|
||||
"github.com/hay-kot/content/backend/internal/types"
|
||||
)
|
||||
|
@ -12,27 +13,27 @@ type AdminService struct {
|
|||
repos *repo.AllRepos
|
||||
}
|
||||
|
||||
func (svc *AdminService) Create(ctx context.Context, usr types.UserCreate) (types.UserOut, error) {
|
||||
func (svc *AdminService) Create(ctx context.Context, usr types.UserCreate) (*ent.User, error) {
|
||||
return svc.repos.Users.Create(ctx, usr)
|
||||
}
|
||||
|
||||
func (svc *AdminService) GetAll(ctx context.Context) ([]types.UserOut, error) {
|
||||
func (svc *AdminService) GetAll(ctx context.Context) ([]*ent.User, error) {
|
||||
return svc.repos.Users.GetAll(ctx)
|
||||
}
|
||||
|
||||
func (svc *AdminService) GetByID(ctx context.Context, id uuid.UUID) (types.UserOut, error) {
|
||||
func (svc *AdminService) GetByID(ctx context.Context, id uuid.UUID) (*ent.User, error) {
|
||||
return svc.repos.Users.GetOneId(ctx, id)
|
||||
}
|
||||
|
||||
func (svc *AdminService) GetByEmail(ctx context.Context, email string) (types.UserOut, error) {
|
||||
func (svc *AdminService) GetByEmail(ctx context.Context, email string) (*ent.User, error) {
|
||||
return svc.repos.Users.GetOneEmail(ctx, email)
|
||||
}
|
||||
|
||||
func (svc *AdminService) UpdateProperties(ctx context.Context, ID uuid.UUID, data types.UserUpdate) (types.UserOut, error) {
|
||||
func (svc *AdminService) UpdateProperties(ctx context.Context, ID uuid.UUID, data types.UserUpdate) (*ent.User, error) {
|
||||
err := svc.repos.Users.Update(ctx, ID, data)
|
||||
|
||||
if err != nil {
|
||||
return types.UserOut{}, err
|
||||
return &ent.User{}, err
|
||||
}
|
||||
|
||||
return svc.repos.Users.GetOneId(ctx, ID)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/content/backend/ent"
|
||||
"github.com/hay-kot/content/backend/internal/repo"
|
||||
"github.com/hay-kot/content/backend/internal/types"
|
||||
"github.com/hay-kot/content/backend/pkgs/hasher"
|
||||
|
@ -22,17 +23,41 @@ type UserService struct {
|
|||
repos *repo.AllRepos
|
||||
}
|
||||
|
||||
func (svc *UserService) RegisterUser(ctx context.Context, data types.UserRegistration) (*ent.User, error) {
|
||||
group, err := svc.repos.Groups.Create(ctx, data.GroupName)
|
||||
if err != nil {
|
||||
return &ent.User{}, err
|
||||
}
|
||||
|
||||
hashed, _ := hasher.HashPassword(data.User.Password)
|
||||
|
||||
usrCreate := types.UserCreate{
|
||||
Name: data.User.Name,
|
||||
Email: data.User.Email,
|
||||
Password: hashed,
|
||||
IsSuperuser: false,
|
||||
GroupID: group.ID,
|
||||
}
|
||||
|
||||
usr, err := svc.repos.Users.Create(ctx, usrCreate)
|
||||
if err != nil {
|
||||
return &ent.User{}, err
|
||||
}
|
||||
|
||||
return usr, nil
|
||||
}
|
||||
|
||||
// GetSelf returns the user that is currently logged in based of the token provided within
|
||||
func (svc *UserService) GetSelf(ctx context.Context, requestToken string) (types.UserOut, error) {
|
||||
func (svc *UserService) GetSelf(ctx context.Context, requestToken string) (*ent.User, error) {
|
||||
hash := hasher.HashToken(requestToken)
|
||||
return svc.repos.AuthTokens.GetUserFromToken(ctx, hash)
|
||||
}
|
||||
|
||||
func (svc *UserService) UpdateSelf(ctx context.Context, ID uuid.UUID, data types.UserUpdate) (types.UserOut, error) {
|
||||
func (svc *UserService) UpdateSelf(ctx context.Context, ID uuid.UUID, data types.UserUpdate) (*ent.User, error) {
|
||||
err := svc.repos.Users.Update(ctx, ID, data)
|
||||
|
||||
if err != nil {
|
||||
return types.UserOut{}, err
|
||||
return &ent.User{}, err
|
||||
}
|
||||
|
||||
return svc.repos.Users.GetOneId(ctx, ID)
|
||||
|
|
|
@ -23,10 +23,11 @@ type UserIn struct {
|
|||
// in the database. It should to create users from an API unless the user has
|
||||
// rights to create SuperUsers. For regular user in data use the UserIn struct.
|
||||
type UserCreate struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
IsSuperuser bool `json:"isSuperuser"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
IsSuperuser bool `json:"isSuperuser"`
|
||||
GroupID uuid.UUID `json:"groupID"`
|
||||
}
|
||||
|
||||
func (u *UserCreate) Validate() error {
|
||||
|
@ -39,20 +40,12 @@ func (u *UserCreate) Validate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type UserOut struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"-"`
|
||||
IsSuperuser bool `json:"isSuperuser"`
|
||||
}
|
||||
|
||||
// IsNull is a proxy call for `usr.Id == uuid.Nil`
|
||||
func (usr *UserOut) IsNull() bool {
|
||||
return usr.ID == uuid.Nil
|
||||
}
|
||||
|
||||
type UserUpdate struct {
|
||||
Name *string `json:"name"`
|
||||
Email *string `json:"email"`
|
||||
}
|
||||
|
||||
type UserRegistration struct {
|
||||
User UserIn `json:"user"`
|
||||
GroupName string `json:"groupName"`
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@ package types
|
|||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUserCreate_Validate(t *testing.T) {
|
||||
|
@ -64,13 +61,3 @@ func TestUserCreate_Validate(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserOut_IsNull(t *testing.T) {
|
||||
nullUser := UserOut{}
|
||||
|
||||
assert.True(t, nullUser.IsNull())
|
||||
|
||||
nullUser.ID = uuid.New()
|
||||
|
||||
assert.False(t, nullUser.IsNull())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue