From e1b5691facb660fefd2204a85744f6d9cbef307c Mon Sep 17 00:00:00 2001 From: Thomas Peetz Date: Sun, 4 Oct 2026 20:43:08 +0200 Subject: [PATCH] add models for MailAccount and Mail --- kontor-gin/internal/cmd/export.go | 10 ++++ kontor-gin/internal/cmd/root.go | 2 +- kontor-gin/internal/handlers/admin.go | 28 +++++---- kontor-gin/internal/handlers/mail.go | 30 ++++++++++ kontor-gin/internal/handlers/mailaccount.go | 30 ++++++++++ kontor-gin/internal/models/mail.go | 55 ++++++++++++++++++ kontor-gin/internal/models/mailaccount.go | 58 +++++++++++++++++++ kontor-gin/internal/repository/mail.go | 37 ++++++++++++ kontor-gin/internal/repository/mailaccount.go | 37 ++++++++++++ kontor-gin/internal/router/router.go | 2 + kontor-gin/internal/service/mail.go | 27 +++++++++ kontor-gin/internal/service/mailaccount.go | 28 +++++++++ kontor-gin/templates/layouts/navbar.html | 5 +- 13 files changed, 334 insertions(+), 15 deletions(-) create mode 100644 kontor-gin/internal/handlers/mail.go create mode 100644 kontor-gin/internal/handlers/mailaccount.go create mode 100644 kontor-gin/internal/models/mail.go create mode 100644 kontor-gin/internal/models/mailaccount.go create mode 100644 kontor-gin/internal/repository/mail.go create mode 100644 kontor-gin/internal/repository/mailaccount.go create mode 100644 kontor-gin/internal/service/mail.go create mode 100644 kontor-gin/internal/service/mailaccount.go diff --git a/kontor-gin/internal/cmd/export.go b/kontor-gin/internal/cmd/export.go index e56d0f0..95800fa 100644 --- a/kontor-gin/internal/cmd/export.go +++ b/kontor-gin/internal/cmd/export.go @@ -67,6 +67,8 @@ var exportCmd = &cobra.Command{ Permission []models.PermissionDTO `json:"permission"` Assignment []models.AssignmentDTO `json:"assignment"` Token []models.TokenDTO `json:"token"` + MailAccount []map[string]interface{} `json:"mail_account"` + Mail []map[string]interface{} `json:"mail"` } var ( @@ -97,12 +99,15 @@ var exportCmd = &cobra.Command{ mediaarticles []models.MediaArticleDTO mediavideos []models.MediaVideoDTO mediaactors []models.MediaActorDTO + mediaactorfiles []models.MediaActorFileDTO mediafiles []models.MediaFileDTO medialofis []models.MediaLoFiDTO profiles []models.ProfileDTO permissions []models.PermissionDTO assignments []models.AssignmentDTO tokens []models.TokenDTO + mailaccounts []map[string]interface{} + mail []map[string]interface{} ) registry := map[string]any{ @@ -134,11 +139,14 @@ var exportCmd = &cobra.Command{ "media/videos": &mediavideos, "media/actors": &mediaactors, "media/files": &mediafiles, + "media/actorfiles": &mediaactorfiles, "media/lofis": &medialofis, "user/profiles": &profiles, "user/permissions": &permissions, "user/assignments": &assignments, "user/tokens": &tokens, + "admin/mailaccounts": &mailaccounts, + "user/mail": &mail, } for path, value := range registry { GetJSON(client, login.Token, fmt.Sprintf("%s/%s/%s", server, "api/v1", path), value) @@ -177,6 +185,8 @@ var exportCmd = &cobra.Command{ Permission: permissions, Assignment: assignments, Token: tokens, + MailAccount: mailaccounts, + Mail: mail, } defer client.Close() jsonData, err := json.MarshalIndent(export, "", " ") diff --git a/kontor-gin/internal/cmd/root.go b/kontor-gin/internal/cmd/root.go index 24220de..d285702 100644 --- a/kontor-gin/internal/cmd/root.go +++ b/kontor-gin/internal/cmd/root.go @@ -37,6 +37,6 @@ func Execute() { } func init() { - rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.myapp.yaml)") + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.config/kli.yaml)") rootCmd.PersistentFlags().CountVarP(&verbose, "verbose", "v", "increase verbosity (-v, -vv, -vvv)") } diff --git a/kontor-gin/internal/handlers/admin.go b/kontor-gin/internal/handlers/admin.go index 9a03f4c..a3a3873 100644 --- a/kontor-gin/internal/handlers/admin.go +++ b/kontor-gin/internal/handlers/admin.go @@ -8,22 +8,26 @@ import ( ) type AdminHandler struct { - AuthHandler *AuthHandler - ProfileHandler *ProfileHandler - PermissionHandler *PermissionHandler - AssignmentHandler *AssignmentHandler - TokenHandler *TokenHandler - Secret []byte + AuthHandler *AuthHandler + ProfileHandler *ProfileHandler + PermissionHandler *PermissionHandler + AssignmentHandler *AssignmentHandler + TokenHandler *TokenHandler + MailAccountHandler *MailAccountHandler + MailHandler *MailHandler + Secret []byte } func NewAdminHandler(db *gorm.DB, secret []byte) *AdminHandler { adminHandler := &AdminHandler{ - AuthHandler: &AuthHandler{Service: service.NewAuthService(repository.NewProfileRepository(db), secret)}, - ProfileHandler: NewProfileHandler(db), - PermissionHandler: &PermissionHandler{Service: service.NewPermissionService(repository.NewPermissionRepository(db))}, - AssignmentHandler: NewAssignmentHandler(db), - TokenHandler: NewTokenHandler(db), - Secret: secret, + AuthHandler: &AuthHandler{Service: service.NewAuthService(repository.NewProfileRepository(db), secret)}, + ProfileHandler: NewProfileHandler(db), + PermissionHandler: &PermissionHandler{Service: service.NewPermissionService(repository.NewPermissionRepository(db))}, + AssignmentHandler: NewAssignmentHandler(db), + TokenHandler: NewTokenHandler(db), + MailAccountHandler: NewMailAccountHandler(db), + MailHandler: NewMailHandler(db), + Secret: secret, } return adminHandler } diff --git a/kontor-gin/internal/handlers/mail.go b/kontor-gin/internal/handlers/mail.go new file mode 100644 index 0000000..277b732 --- /dev/null +++ b/kontor-gin/internal/handlers/mail.go @@ -0,0 +1,30 @@ +package handlers + +import ( + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "kontor-api-gin/internal/service" + "net/http" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type MailHandler struct { + Service *service.MailService +} + +func NewMailHandler(db *gorm.DB) *MailHandler { + handler := &MailHandler{Service: service.NewMailService(repository.NewMailRepository(db))} + return handler +} + +func (handler *MailHandler) List(c *gin.Context) { + mails, err := handler.Service.List(c.Request.Context()) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + dtos := models.ConvertMailsToDtos(mails) + c.JSON(http.StatusOK, dtos) +} diff --git a/kontor-gin/internal/handlers/mailaccount.go b/kontor-gin/internal/handlers/mailaccount.go new file mode 100644 index 0000000..b653244 --- /dev/null +++ b/kontor-gin/internal/handlers/mailaccount.go @@ -0,0 +1,30 @@ +package handlers + +import ( + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "kontor-api-gin/internal/service" + "net/http" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type MailAccountHandler struct { + Service *service.MailAccountService +} + +func NewMailAccountHandler(db *gorm.DB) *MailAccountHandler { + handler := &MailAccountHandler{Service: service.NewMailAccountService(repository.NewMailAccountRepository(db))} + return handler +} + +func (handler *MailAccountHandler) List(c *gin.Context) { + mailaccounts, err := handler.Service.List(c.Request.Context()) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + dtos := models.ConvertMailAccountsToDtos(mailaccounts) + c.JSON(http.StatusOK, dtos) +} diff --git a/kontor-gin/internal/models/mail.go b/kontor-gin/internal/models/mail.go new file mode 100644 index 0000000..2283f61 --- /dev/null +++ b/kontor-gin/internal/models/mail.go @@ -0,0 +1,55 @@ +package models + +import ( + "kontor-api-gin/internal/helpers" + "time" +) + +type Mail struct { + ID string `gorm:"type:string;primary_key;" json:"id"` + CreatedAt time.Time `gorm:"column:created_date" json:"created_date"` + UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"` + DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"` + Version int `gorm:"default:0" json:"version"` + Folder string `gorm:"column:folder" json:"folder"` + Subject string `gorm:"column:subject" json:"subject"` + Body string `gorm:"column:body" json:"body"` + SendAt time.Time `gorm:"column:sent_date" json:"sent_date"` + ReceivedAt time.Time `gorm:"column:received_date" json:"received_date"` +} + +func (mail *Mail) TableName() string { + return "mail" +} + +type MailDTO struct { + ID string `json:"id" binding:"required"` + CreatedAt helpers.KontorTime `json:"created_date"` + UpdatedAt helpers.KontorTime `json:"last_modified_date"` + DeletedAt *time.Time `json:"deleted_date.omitempty"` + Version int `json:"version"` + Folder string `json:"folder"` + Subject string `json:"subject"` + Body string `json:"body"` + SendAt time.Time `json:"sent_date"` + ReceivedAt time.Time `json:"received_date"` +} + +func ConvertMailsToDtos(mails []Mail) []MailDTO { + dtos := make([]MailDTO, len(mails)) + for i, mail := range mails { + dtos[i] = MailDTO{ + ID: mail.ID, + CreatedAt: helpers.KontorTime{Time: mail.CreatedAt}, + UpdatedAt: helpers.KontorTime{Time: mail.UpdatedAt}, + DeletedAt: mail.DeletedAt, + Version: mail.Version, + Folder: mail.Folder, + Subject: mail.Subject, + Body: mail.Body, + SendAt: mail.SendAt, + ReceivedAt: mail.ReceivedAt, + } + } + return dtos +} diff --git a/kontor-gin/internal/models/mailaccount.go b/kontor-gin/internal/models/mailaccount.go new file mode 100644 index 0000000..d00381a --- /dev/null +++ b/kontor-gin/internal/models/mailaccount.go @@ -0,0 +1,58 @@ +package models + +import ( + "kontor-api-gin/internal/helpers" + "time" +) + +type MailAccount struct { + ID string `gorm:"type:string;primary_key;" json:"id"` + CreatedAt time.Time `gorm:"column:created_date" json:"created_date"` + UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"` + DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"` + Version int `gorm:"default:0" json:"version"` + Host string `gorm:"column:host" json:"host"` + Port int `gorm:"column:port" json:"port"` + Protocol string `gorm:"column:protocol" json:"protocol"` + UserName string `gorm:"column:user_name" json:"user_name"` + Password string `gorm:"column:password" json:"password"` + StartTLS bool `gorm:"column:start_tls" json:"start_tls"` +} + +func (mail_account *MailAccount) TableName() string { + return "mail_account" +} + +type MailAccountDTO struct { + ID string `json:"id" binding:"required"` + CreatedAt helpers.KontorTime `json:"created_date"` + UpdatedAt helpers.KontorTime `json:"last_modified_date"` + DeletedAt *time.Time `json:"deleted_date.omitempty"` + Version int `json:"version"` + Host string `json:"host"` + Port int `json:"port"` + Protocol string `json:"protocol"` + UserName string `json:"user_name"` + Password string `json:"password"` + StartTLS bool `json:"start_tls"` +} + +func ConvertMailAccountsToDtos(mailaccounts []MailAccount) []MailAccountDTO { + dtos := make([]MailAccountDTO, len(mailaccounts)) + for i, mailaccount := range mailaccounts { + dtos[i] = MailAccountDTO{ + ID: mailaccount.ID, + CreatedAt: helpers.KontorTime{Time: mailaccount.CreatedAt}, + UpdatedAt: helpers.KontorTime{Time: mailaccount.UpdatedAt}, + DeletedAt: mailaccount.DeletedAt, + Version: mailaccount.Version, + Host: mailaccount.Host, + Port: mailaccount.Port, + Protocol: mailaccount.Protocol, + UserName: mailaccount.UserName, + Password: mailaccount.Password, + StartTLS: mailaccount.StartTLS, + } + } + return dtos +} diff --git a/kontor-gin/internal/repository/mail.go b/kontor-gin/internal/repository/mail.go new file mode 100644 index 0000000..7704b52 --- /dev/null +++ b/kontor-gin/internal/repository/mail.go @@ -0,0 +1,37 @@ +package repository + +import ( + "context" + "kontor-api-gin/internal/models" + "log/slog" + + "gorm.io/gorm" +) + +type MailRepository struct { + db *gorm.DB +} + +func NewMailRepository(db *gorm.DB) *MailRepository { + repository := &MailRepository{db: db} + return repository +} + +func (repository *MailRepository) FindAll(context context.Context) ([]models.Mail, error) { + var mails []models.Mail + + result := repository.db.Find(&mails) + slog.Info("MailRepository#FindAll", "count", result.RowsAffected) + + return mails, nil +} + +func (repository *MailRepository) GetById(context context.Context, id string) (models.Mail, error) { + var mail = models.Mail{ID: id} + slog.Info("MailRepository#GetById", "id", id) + result := repository.db.First(&mail) + if result.Error != nil { + slog.Info("MailRepository#GetById", "error", result.Error.Error()) + } + return mail, result.Error +} diff --git a/kontor-gin/internal/repository/mailaccount.go b/kontor-gin/internal/repository/mailaccount.go new file mode 100644 index 0000000..f87c39e --- /dev/null +++ b/kontor-gin/internal/repository/mailaccount.go @@ -0,0 +1,37 @@ +package repository + +import ( + "context" + "kontor-api-gin/internal/models" + "log/slog" + + "gorm.io/gorm" +) + +type MailAccountRepository struct { + db *gorm.DB +} + +func NewMailAccountRepository(db *gorm.DB) *MailAccountRepository { + repository := &MailAccountRepository{db: db} + return repository +} + +func (repository *MailAccountRepository) FindAll(context context.Context) ([]models.MailAccount, error) { + var mailaccounts []models.MailAccount + + result := repository.db.Find(&mailaccounts) + slog.Info("MailAccountRepository#FindAll", "count", result.RowsAffected) + + return mailaccounts, nil +} + +func (repository *MailAccountRepository) GetById(context context.Context, id string) (models.MailAccount, error) { + var mailaccount = models.MailAccount{ID: id} + slog.Info("MailAccountRepository#GetById", "id", id) + result := repository.db.First(&mailaccount) + if result.Error != nil { + slog.Info("MailAccountRepository#GetById", "error", result.Error.Error()) + } + return mailaccount, result.Error +} diff --git a/kontor-gin/internal/router/router.go b/kontor-gin/internal/router/router.go index 99bccac..876c801 100644 --- a/kontor-gin/internal/router/router.go +++ b/kontor-gin/internal/router/router.go @@ -70,9 +70,11 @@ func New(admin *handlers.AdminHandler, bookshelf *handlers.BookshelfHandler, com { secured := v1.Group("") secured.Use(middleware.JWT(admin.Secret)) + secured.GET("admin/mailaccounts", admin.MailAccountHandler.List) secured.GET("user/profiles", admin.ProfileHandler.List) secured.GET("user/permissions", admin.PermissionHandler.List) secured.GET("user/assignments", admin.AssignmentHandler.List) + secured.GET("user/mails", admin.MailHandler.List) secured.GET("user/tokens", admin.TokenHandler.List) secured.GET("tysc/sports", tysc.SportHandler.List) secured.GET("tysc/sports/:id", tysc.SportHandler.Get) diff --git a/kontor-gin/internal/service/mail.go b/kontor-gin/internal/service/mail.go new file mode 100644 index 0000000..ebd2ada --- /dev/null +++ b/kontor-gin/internal/service/mail.go @@ -0,0 +1,27 @@ +package service + +import ( + "context" + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "log/slog" +) + +type MailService struct { + repository *repository.MailRepository +} + +func NewMailService(repo *repository.MailRepository) *MailService { + service := &MailService{repository: repo} + return service +} + +func (service *MailService) List(context context.Context) ([]models.Mail, error) { + slog.Info("MailService#List") + return service.repository.FindAll(context) +} + +func (service *MailService) Get(context context.Context, id string) (models.Mail, error) { + slog.Info("MailService#Get") + return service.repository.GetById(context, id) +} diff --git a/kontor-gin/internal/service/mailaccount.go b/kontor-gin/internal/service/mailaccount.go new file mode 100644 index 0000000..ea34869 --- /dev/null +++ b/kontor-gin/internal/service/mailaccount.go @@ -0,0 +1,28 @@ +package service + +import ( + "context" + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "log/slog" +) + +type MailAccountService struct { + repository *repository.MailAccountRepository +} + +func NewMailAccountService(repo *repository.MailAccountRepository) *MailAccountService { + service := &MailAccountService{repository: repo} + return service +} + +func (service *MailAccountService) List(context context.Context) ([]models.MailAccount, error) { + slog.Info("MailAccountService#List") + return service.repository.FindAll(context) +} + +func (service *MailAccountService) Get(context context.Context, id string) (models.MailAccount, error) { + slog.Info("MailAccountService#Get") + return service.repository.GetById(context, id) +} + diff --git a/kontor-gin/templates/layouts/navbar.html b/kontor-gin/templates/layouts/navbar.html index e38ef48..1c81f99 100644 --- a/kontor-gin/templates/layouts/navbar.html +++ b/kontor-gin/templates/layouts/navbar.html @@ -17,9 +17,10 @@ {{ if .user }}