mirror of
https://github.com/twofas/2fas-server.git
synced 2024-12-12 20:20:19 +01:00
460 lines
10 KiB
Go
460 lines
10 KiB
Go
package command
|
|
|
|
import (
|
|
"encoding/json"
|
|
"github.com/doug-martin/goqu/v9"
|
|
"github.com/google/uuid"
|
|
"github.com/twofas/2fas-server/internal/api/icons/domain"
|
|
"github.com/twofas/2fas-server/internal/common/logging"
|
|
"github.com/twofas/2fas-server/internal/common/storage"
|
|
"gorm.io/datatypes"
|
|
"gorm.io/gorm"
|
|
"image/png"
|
|
"path/filepath"
|
|
)
|
|
|
|
type CreateIconRequest struct {
|
|
Id uuid.UUID
|
|
CallerId string `json:"caller_id" validate:"required,max=128"`
|
|
ServiceName string `json:"service_name" validate:"required,max=128"`
|
|
Issuers []string `json:"issuers" validate:"required,max=128"`
|
|
Description string `json:"description" validate:"omitempty,max=512"`
|
|
LightIcon string `json:"light_icon" validate:"required,base64"`
|
|
DarkIcon string `json:"dark_icon" validate:"omitempty,base64"`
|
|
}
|
|
|
|
type CreateIconRequestHandler struct {
|
|
Storage storage.FileSystemStorage
|
|
Repository domain.IconsRequestsRepository
|
|
}
|
|
|
|
func (h *CreateIconRequestHandler) Handle(cmd *CreateIconRequest) error {
|
|
_, rawImg, err := processB64PngImage(cmd.LightIcon)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
lightIconPath := filepath.Join(iconsStoragePath, "ir_"+uuid.New().String()+".light.png")
|
|
|
|
lightIconLocation, err := h.Storage.Save(lightIconPath, rawImg)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
issuers, err := json.Marshal(cmd.Issuers)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iconRequest := &domain.IconRequest{
|
|
Id: cmd.Id,
|
|
CallerId: cmd.CallerId,
|
|
Issuers: issuers,
|
|
ServiceName: cmd.ServiceName,
|
|
Description: cmd.Description,
|
|
LightIconUrl: lightIconLocation,
|
|
}
|
|
|
|
if cmd.DarkIcon != "" {
|
|
_, darkIconRaw, err := processB64PngImage(cmd.DarkIcon)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
darkIconPath := filepath.Join(iconsStoragePath, "ir_"+uuid.New().String()+".dark.png")
|
|
|
|
darkIconLocation, err := h.Storage.Save(darkIconPath, darkIconRaw)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iconRequest.DarkIconUrl = darkIconLocation
|
|
}
|
|
|
|
return h.Repository.Save(iconRequest)
|
|
}
|
|
|
|
type DeleteIconRequest struct {
|
|
Id string `uri:"icon_request_id" validate:"required,uuid4"`
|
|
}
|
|
|
|
type DeleteIconRequestHandler struct {
|
|
Repository domain.IconsRequestsRepository
|
|
}
|
|
|
|
func (h *DeleteIconRequestHandler) Handle(cmd *DeleteIconRequest) error {
|
|
id, _ := uuid.Parse(cmd.Id)
|
|
|
|
icon, err := h.Repository.FindById(id)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return h.Repository.Delete(icon)
|
|
}
|
|
|
|
type DeleteAllIconsRequestsHandler struct {
|
|
Database *gorm.DB
|
|
Qb *goqu.Database
|
|
}
|
|
|
|
func (h *DeleteAllIconsRequestsHandler) Handle() {
|
|
sql, _, _ := h.Qb.Truncate("icons_requests").ToSQL()
|
|
|
|
h.Database.Exec(sql)
|
|
}
|
|
|
|
type UpdateWebServiceFromIconRequest struct {
|
|
IconRequestId string `uri:"icon_request_id" validate:"required,uuid4"`
|
|
WebServiceId string `json:"web_service_id" validate:"required,uuid4"`
|
|
}
|
|
|
|
type UpdateWebServiceFromIconRequestHandler struct {
|
|
IconsStorage storage.FileSystemStorage
|
|
WebServiceRepository domain.WebServicesRepository
|
|
IconsCollectionsRepository domain.IconsCollectionRepository
|
|
IconsRepository domain.IconsRepository
|
|
IconsRequestsRepository domain.IconsRequestsRepository
|
|
}
|
|
|
|
func (h *UpdateWebServiceFromIconRequestHandler) Handle(cmd *UpdateWebServiceFromIconRequest) error {
|
|
webServiceId, err := uuid.Parse(cmd.WebServiceId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iconRequestId, err := uuid.Parse(cmd.IconRequestId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iconRequest, err := h.IconsRequestsRepository.FindById(iconRequestId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
webService, err := h.WebServiceRepository.FindById(webServiceId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iconsCollectionId := uuid.New()
|
|
|
|
lightIconStoragePath := filepath.Join(iconsStoragePath, filepath.Base(iconRequest.LightIconUrl))
|
|
|
|
lightIconImg, err := h.IconsStorage.Get(lightIconStoragePath)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
lightIconPng, err := png.Decode(lightIconImg)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
lightIconId := uuid.New()
|
|
lightIconNewPath := filepath.Join(iconsStoragePath, lightIconId.String()+".png")
|
|
newLightIconLocation, err := h.IconsStorage.Move(lightIconStoragePath, lightIconNewPath)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
lightIcon := &domain.Icon{
|
|
Id: lightIconId,
|
|
Name: iconRequest.ServiceName,
|
|
Url: newLightIconLocation,
|
|
Width: lightIconPng.Bounds().Dx(),
|
|
Height: lightIconPng.Bounds().Dy(),
|
|
Type: domain.Light,
|
|
}
|
|
|
|
err = h.IconsRepository.Save(lightIcon)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iconsIds := []string{
|
|
lightIcon.Id.String(),
|
|
}
|
|
|
|
if iconRequest.DarkIconUrl != "" {
|
|
darkIconStoragePath := filepath.Join(iconsStoragePath, filepath.Base(iconRequest.DarkIconUrl))
|
|
|
|
darkIconImg, err := h.IconsStorage.Get(darkIconStoragePath)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
darkIconPng, err := png.Decode(darkIconImg)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
darkIconId := uuid.New()
|
|
darkIconNewPath := filepath.Join(iconsStoragePath, darkIconId.String()+".png")
|
|
newDarkIconLocation, err := h.IconsStorage.Move(darkIconStoragePath, darkIconNewPath)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
darkIcon := &domain.Icon{
|
|
Id: darkIconId,
|
|
Name: iconRequest.ServiceName,
|
|
Url: newDarkIconLocation,
|
|
Width: darkIconPng.Bounds().Dx(),
|
|
Height: darkIconPng.Bounds().Dy(),
|
|
Type: domain.Dark,
|
|
}
|
|
|
|
err = h.IconsRepository.Save(darkIcon)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iconsIds = append(iconsIds, darkIconId.String())
|
|
}
|
|
|
|
iconsJson, err := json.Marshal(iconsIds)
|
|
|
|
iconsCollection := &domain.IconsCollection{
|
|
Id: iconsCollectionId,
|
|
Name: iconRequest.ServiceName,
|
|
Icons: iconsJson,
|
|
}
|
|
|
|
err = h.IconsCollectionsRepository.Save(iconsCollection)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var webServiceIconsCollectionsIds []string
|
|
|
|
err = json.Unmarshal(webService.IconsCollections, &webServiceIconsCollectionsIds)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, outdatedIconsCollectionId := range webServiceIconsCollectionsIds {
|
|
id, _ := uuid.Parse(outdatedIconsCollectionId)
|
|
|
|
outDatedIconsCollection, err := h.IconsCollectionsRepository.FindById(id)
|
|
|
|
if err != nil {
|
|
logging.
|
|
WithField("icon_collection_id", outdatedIconsCollectionId).
|
|
Error("Out of date icons collection cannot be found")
|
|
}
|
|
|
|
err = h.IconsCollectionsRepository.Delete(outDatedIconsCollection)
|
|
|
|
if err != nil {
|
|
logging.
|
|
WithField("icon_collection_id", outdatedIconsCollectionId).
|
|
Error("Cannot delete out of date icons collection")
|
|
}
|
|
|
|
var outdatedCollectionIcons []string
|
|
|
|
err = json.Unmarshal(outDatedIconsCollection.Icons, &outdatedCollectionIcons)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, outdatedIconId := range webServiceIconsCollectionsIds {
|
|
iconId, _ := uuid.Parse(outdatedIconId)
|
|
iconToDelete, err := h.IconsRepository.FindById(iconId)
|
|
|
|
if err == nil {
|
|
h.IconsRepository.Delete(iconToDelete)
|
|
}
|
|
}
|
|
}
|
|
|
|
webService.IconsCollections = datatypes.JSON(`["` + iconsCollection.Id.String() + `"]`)
|
|
|
|
h.WebServiceRepository.Update(webService)
|
|
|
|
err = h.IconsRequestsRepository.Delete(iconRequest)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type TransformIconRequestToWebService struct {
|
|
WebServiceId uuid.UUID
|
|
IconRequestId string `uri:"icon_request_id" validate:"required,uuid4"`
|
|
}
|
|
|
|
type TransformIconRequestToWebServiceHandler struct {
|
|
IconsStorage storage.FileSystemStorage
|
|
WebServiceRepository domain.WebServicesRepository
|
|
IconsRepository domain.IconsRepository
|
|
IconsCollectionsRepository domain.IconsCollectionRepository
|
|
IconsRequestsRepository domain.IconsRequestsRepository
|
|
}
|
|
|
|
func (h *TransformIconRequestToWebServiceHandler) Handle(cmd *TransformIconRequestToWebService) error {
|
|
iconRequestId, err := uuid.Parse(cmd.IconRequestId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iconRequest, err := h.IconsRequestsRepository.FindById(iconRequestId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
conflict, err := h.WebServiceRepository.FindByName(iconRequest.ServiceName)
|
|
|
|
if conflict != nil {
|
|
return domain.WebServiceAlreadyExistsError{Name: iconRequest.ServiceName}
|
|
}
|
|
|
|
iconsCollectionId := uuid.New()
|
|
|
|
lightIconStoragePath := filepath.Join(iconsStoragePath, filepath.Base(iconRequest.LightIconUrl))
|
|
|
|
lightIconImg, err := h.IconsStorage.Get(lightIconStoragePath)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
lightIconPng, err := png.Decode(lightIconImg)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
lightIconId := uuid.New()
|
|
lightIconNewPath := filepath.Join(iconsStoragePath, lightIconId.String()+".png")
|
|
newLightIconLocation, err := h.IconsStorage.Move(lightIconStoragePath, lightIconNewPath)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
lightIcon := &domain.Icon{
|
|
Id: lightIconId,
|
|
Name: iconRequest.ServiceName,
|
|
Url: newLightIconLocation,
|
|
Width: lightIconPng.Bounds().Dx(),
|
|
Height: lightIconPng.Bounds().Dy(),
|
|
Type: domain.Light,
|
|
}
|
|
|
|
err = h.IconsRepository.Save(lightIcon)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iconsIds := []string{
|
|
lightIcon.Id.String(),
|
|
}
|
|
|
|
if iconRequest.DarkIconUrl != "" {
|
|
darkIconStoragePath := filepath.Join(iconsStoragePath, filepath.Base(iconRequest.DarkIconUrl))
|
|
|
|
darkIconImg, err := h.IconsStorage.Get(darkIconStoragePath)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
darkIconPng, err := png.Decode(darkIconImg)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
darkIconId := uuid.New()
|
|
darkIconNewPath := filepath.Join(iconsStoragePath, darkIconId.String()+".png")
|
|
newDarkIconLocation, err := h.IconsStorage.Move(darkIconStoragePath, darkIconNewPath)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
darkIcon := &domain.Icon{
|
|
Id: darkIconId,
|
|
Name: iconRequest.ServiceName,
|
|
Url: newDarkIconLocation,
|
|
Width: darkIconPng.Bounds().Dx(),
|
|
Height: darkIconPng.Bounds().Dy(),
|
|
Type: domain.Dark,
|
|
}
|
|
|
|
err = h.IconsRepository.Save(darkIcon)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iconsIds = append(iconsIds, darkIconId.String())
|
|
}
|
|
|
|
iconsJson, err := json.Marshal(iconsIds)
|
|
|
|
iconsCollection := &domain.IconsCollection{
|
|
Id: iconsCollectionId,
|
|
Name: iconRequest.ServiceName,
|
|
Icons: iconsJson,
|
|
}
|
|
|
|
err = h.IconsCollectionsRepository.Save(iconsCollection)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
webService := &domain.WebService{
|
|
Id: cmd.WebServiceId,
|
|
Name: iconRequest.ServiceName,
|
|
Issuers: iconRequest.Issuers,
|
|
Tags: datatypes.JSON(`[]`),
|
|
IconsCollections: datatypes.JSON(`["` + iconsCollectionId.String() + `"]`),
|
|
MatchRules: nil,
|
|
}
|
|
|
|
err = h.WebServiceRepository.Save(webService)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = h.IconsRequestsRepository.Delete(iconRequest)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|