mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-02-13 00:22:49 +00:00
131 lines
3.7 KiB
Go
131 lines
3.7 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/go-errors/errors"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/oapi-codegen/nullable"
|
|
"github.com/phishingclub/phishingclub/data"
|
|
"github.com/phishingclub/phishingclub/errs"
|
|
"github.com/phishingclub/phishingclub/model"
|
|
"github.com/phishingclub/phishingclub/password"
|
|
"github.com/phishingclub/phishingclub/repository"
|
|
"github.com/phishingclub/phishingclub/vo"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// InstallSetup sets up the intial administrator account
|
|
// this is called by the installation process and is not part of the normal application flow
|
|
// it must not use services that require authentication or be used by any other part of the application
|
|
type InstallSetup struct {
|
|
Common
|
|
UserRepository *repository.User
|
|
RoleRepository *repository.Role
|
|
CompanyRepository *repository.Company
|
|
PasswordHasher *password.Argon2Hasher
|
|
}
|
|
|
|
// SetupAccounts sets up the accounts needed for the system to function
|
|
func (s *InstallSetup) SetupAccounts(
|
|
ctx context.Context,
|
|
) (*model.User, *vo.ReasonableLengthPassword, error) {
|
|
user, password, err := s.setupInitialAdministratorAccount(ctx)
|
|
if err != nil {
|
|
s.Logger.Errorw("failed to setup the initial administrator account", "error", err)
|
|
return nil, nil, errs.Wrap(err)
|
|
}
|
|
return user, password, nil
|
|
}
|
|
|
|
// setupInitialAdministratorAccount sets up the initial administrator account
|
|
func (s *InstallSetup) setupInitialAdministratorAccount(
|
|
ctx context.Context,
|
|
) (*model.User, *vo.ReasonableLengthPassword, error) {
|
|
username := vo.NewUsernameMust(data.DefaultSacrificalAccountUsername)
|
|
nullableUsername := nullable.NewNullableWithValue(*username)
|
|
// get the admin user if it already exists
|
|
// this could happend if the installation was started, but not completed
|
|
adminUser, err := s.UserRepository.GetByUsername(
|
|
ctx,
|
|
username,
|
|
&repository.UserOption{
|
|
WithRole: true,
|
|
WithCompany: true,
|
|
},
|
|
)
|
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, nil, errs.Wrap(err)
|
|
}
|
|
password, err := vo.NewReasonableLengthPasswordGenerated()
|
|
if err != nil {
|
|
return nil, nil, errs.Wrap(err)
|
|
}
|
|
// if the admin account does not exist, create it
|
|
if adminUser == nil {
|
|
adminRole, err := s.RoleRepository.GetByName(
|
|
ctx,
|
|
data.RoleSuperAdministrator,
|
|
)
|
|
if err != nil {
|
|
return nil, nil, errs.Wrap(err)
|
|
}
|
|
email := nullable.NewNullableWithValue(*vo.NewEmailMust(data.DefaultSacrificalAccountEmail))
|
|
fullname := nullable.NewNullableWithValue(*vo.NewUserFullnameMust(data.DefaultSacrificalAccountName))
|
|
tmpAdminID := nullable.NewNullableWithValue(uuid.New())
|
|
tmpAdmin := &model.User{
|
|
ID: tmpAdminID,
|
|
Name: fullname,
|
|
Username: nullableUsername,
|
|
Email: email,
|
|
RoleID: nullable.NewNullableWithValue(adminRole.ID),
|
|
}
|
|
hash, err := s.PasswordHasher.Hash(password.String())
|
|
if err != nil {
|
|
return nil, nil, errs.Wrap(err)
|
|
}
|
|
|
|
newUserID, err := s.UserRepository.Insert(
|
|
ctx,
|
|
tmpAdmin,
|
|
hash,
|
|
"",
|
|
)
|
|
if err != nil {
|
|
return nil, nil, errs.Wrap(err)
|
|
}
|
|
adminUser, err = s.UserRepository.GetByID(
|
|
ctx,
|
|
newUserID,
|
|
&repository.UserOption{
|
|
WithRole: true,
|
|
WithCompany: false,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, nil, errs.Wrap(err)
|
|
}
|
|
} else {
|
|
username, err := vo.NewUsername(data.DefaultSacrificalAccountUsername)
|
|
if err != nil {
|
|
return nil, nil, errs.Wrap(err)
|
|
}
|
|
// if the admin account exists, update the password
|
|
hash, err := s.PasswordHasher.Hash(password.String())
|
|
if err != nil {
|
|
return nil, nil, errs.Wrap(err)
|
|
}
|
|
err = s.UserRepository.UpdatePasswordHashByUsername(
|
|
ctx,
|
|
username,
|
|
hash,
|
|
)
|
|
if err != nil {
|
|
return nil, nil, errs.Wrap(err)
|
|
}
|
|
return adminUser, password, nil
|
|
}
|
|
return adminUser, password, nil
|
|
}
|