mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-07-11 14:36:38 +02:00
36ee621f1a
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
226 lines
6.6 KiB
Go
226 lines
6.6 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/go-errors/errors"
|
|
"github.com/google/uuid"
|
|
"github.com/phishingclub/phishingclub/data"
|
|
"github.com/phishingclub/phishingclub/errs"
|
|
"github.com/phishingclub/phishingclub/model"
|
|
"github.com/phishingclub/phishingclub/repository"
|
|
"github.com/phishingclub/phishingclub/validate"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// RemoteBrowser manages saved remote browser scripts.
|
|
type RemoteBrowser struct {
|
|
Common
|
|
RemoteBrowserRepository *repository.RemoteBrowser
|
|
}
|
|
|
|
// Create saves a new remote browser script.
|
|
func (s *RemoteBrowser) Create(
|
|
ctx context.Context,
|
|
session *model.Session,
|
|
rb *model.RemoteBrowser,
|
|
) (*uuid.UUID, error) {
|
|
ae := NewAuditEvent("RemoteBrowser.Create", session)
|
|
isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
|
|
if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
|
|
s.LogAuthError(err)
|
|
return nil, errs.Wrap(err)
|
|
}
|
|
if !isAuthorized {
|
|
s.AuditLogNotAuthorized(ae)
|
|
return nil, errs.ErrAuthorizationFailed
|
|
}
|
|
|
|
var companyID *uuid.UUID
|
|
if cid, err := rb.CompanyID.Get(); err == nil {
|
|
companyID = &cid
|
|
}
|
|
|
|
if err := rb.Validate(); err != nil {
|
|
s.Logger.Errorw("failed to validate remote browser", "error", err)
|
|
return nil, errs.Wrap(err)
|
|
}
|
|
|
|
name := rb.Name.MustGet()
|
|
isOK, err := repository.CheckNameIsUnique(ctx, s.RemoteBrowserRepository.DB, "remote_browsers", name.String(), companyID, nil)
|
|
if err != nil {
|
|
s.Logger.Errorw("failed to check remote browser uniqueness", "error", err)
|
|
return nil, errs.Wrap(err)
|
|
}
|
|
if !isOK {
|
|
return nil, validate.WrapErrorWithField(errors.New("is not unique"), "name")
|
|
}
|
|
|
|
id, err := s.RemoteBrowserRepository.Insert(ctx, rb)
|
|
if err != nil {
|
|
s.Logger.Errorw("failed to create remote browser", "error", err)
|
|
return nil, errs.Wrap(err)
|
|
}
|
|
ae.Details["id"] = id.String()
|
|
s.AuditLogAuthorized(ae)
|
|
return id, nil
|
|
}
|
|
|
|
// GetAll returns all remote browsers for the given company.
|
|
func (s *RemoteBrowser) GetAll(
|
|
ctx context.Context,
|
|
session *model.Session,
|
|
companyID *uuid.UUID,
|
|
options *repository.RemoteBrowserOption,
|
|
) (*model.Result[model.RemoteBrowser], error) {
|
|
result := model.NewEmptyResult[model.RemoteBrowser]()
|
|
ae := NewAuditEvent("RemoteBrowser.GetAll", session)
|
|
isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
|
|
if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
|
|
s.LogAuthError(err)
|
|
return result, errs.Wrap(err)
|
|
}
|
|
if !isAuthorized {
|
|
s.AuditLogNotAuthorized(ae)
|
|
return result, errs.ErrAuthorizationFailed
|
|
}
|
|
result, err = s.RemoteBrowserRepository.GetAll(ctx, companyID, options)
|
|
if err != nil {
|
|
s.Logger.Errorw("failed to get remote browsers", "error", err)
|
|
return result, errs.Wrap(err)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// GetAllOverview returns lightweight overview rows.
|
|
func (s *RemoteBrowser) GetAllOverview(
|
|
companyID *uuid.UUID,
|
|
ctx context.Context,
|
|
session *model.Session,
|
|
options *repository.RemoteBrowserOption,
|
|
) (*model.Result[model.RemoteBrowserOverview], error) {
|
|
result := model.NewEmptyResult[model.RemoteBrowserOverview]()
|
|
ae := NewAuditEvent("RemoteBrowser.GetAllOverview", session)
|
|
isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
|
|
if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
|
|
s.LogAuthError(err)
|
|
return result, errs.Wrap(err)
|
|
}
|
|
if !isAuthorized {
|
|
s.AuditLogNotAuthorized(ae)
|
|
return result, errs.ErrAuthorizationFailed
|
|
}
|
|
result, err = s.RemoteBrowserRepository.GetAllSubset(ctx, companyID, options)
|
|
if err != nil {
|
|
s.Logger.Errorw("failed to get remote browser overview", "error", err)
|
|
return result, errs.Wrap(err)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// GetByID returns a single remote browser by ID.
|
|
func (s *RemoteBrowser) GetByID(
|
|
ctx context.Context,
|
|
session *model.Session,
|
|
id *uuid.UUID,
|
|
options *repository.RemoteBrowserOption,
|
|
) (*model.RemoteBrowser, error) {
|
|
ae := NewAuditEvent("RemoteBrowser.GetByID", session)
|
|
ae.Details["id"] = id.String()
|
|
isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
|
|
if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
|
|
s.LogAuthError(err)
|
|
return nil, errs.Wrap(err)
|
|
}
|
|
if !isAuthorized {
|
|
s.AuditLogNotAuthorized(ae)
|
|
return nil, errs.ErrAuthorizationFailed
|
|
}
|
|
rb, err := s.RemoteBrowserRepository.GetByID(ctx, id, options)
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errs.Wrap(err)
|
|
}
|
|
if err != nil {
|
|
s.Logger.Errorw("failed to get remote browser by ID", "error", err)
|
|
return nil, errs.Wrap(err)
|
|
}
|
|
return rb, nil
|
|
}
|
|
|
|
// UpdateByID updates mutable fields on a remote browser.
|
|
func (s *RemoteBrowser) UpdateByID(
|
|
ctx context.Context,
|
|
session *model.Session,
|
|
id *uuid.UUID,
|
|
rb *model.RemoteBrowser,
|
|
) error {
|
|
ae := NewAuditEvent("RemoteBrowser.UpdateByID", session)
|
|
ae.Details["id"] = id.String()
|
|
isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
|
|
if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
|
|
s.LogAuthError(err)
|
|
return err
|
|
}
|
|
if !isAuthorized {
|
|
s.AuditLogNotAuthorized(ae)
|
|
return errs.ErrAuthorizationFailed
|
|
}
|
|
|
|
current, err := s.RemoteBrowserRepository.GetByID(ctx, id, &repository.RemoteBrowserOption{})
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return err
|
|
}
|
|
if err != nil {
|
|
s.Logger.Errorw("failed to get remote browser for update", "error", err)
|
|
return err
|
|
}
|
|
|
|
if _, err := rb.Name.Get(); err == nil {
|
|
var companyID *uuid.UUID
|
|
if cid, err := current.CompanyID.Get(); err == nil {
|
|
companyID = &cid
|
|
}
|
|
name := rb.Name.MustGet()
|
|
isOK, err := repository.CheckNameIsUnique(ctx, s.RemoteBrowserRepository.DB, "remote_browsers", name.String(), companyID, id)
|
|
if err != nil {
|
|
s.Logger.Errorw("failed to check remote browser name uniqueness on update", "error", err)
|
|
return errs.Wrap(err)
|
|
}
|
|
if !isOK {
|
|
return validate.WrapErrorWithField(errors.New("is not unique"), "name")
|
|
}
|
|
}
|
|
|
|
if err := s.RemoteBrowserRepository.UpdateByID(ctx, id, rb); err != nil {
|
|
s.Logger.Errorw("failed to update remote browser", "error", err)
|
|
return errs.Wrap(err)
|
|
}
|
|
s.AuditLogAuthorized(ae)
|
|
return nil
|
|
}
|
|
|
|
// DeleteByID removes a remote browser.
|
|
func (s *RemoteBrowser) DeleteByID(
|
|
ctx context.Context,
|
|
session *model.Session,
|
|
id *uuid.UUID,
|
|
) error {
|
|
ae := NewAuditEvent("RemoteBrowser.DeleteByID", session)
|
|
ae.Details["id"] = id.String()
|
|
isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
|
|
if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
|
|
s.LogAuthError(err)
|
|
return err
|
|
}
|
|
if !isAuthorized {
|
|
s.AuditLogNotAuthorized(ae)
|
|
return errs.ErrAuthorizationFailed
|
|
}
|
|
if err := s.RemoteBrowserRepository.DeleteByID(ctx, id); err != nil {
|
|
s.Logger.Errorw("failed to delete remote browser", "error", err)
|
|
return errs.Wrap(err)
|
|
}
|
|
s.AuditLogAuthorized(ae)
|
|
return nil
|
|
}
|