From fa7e33c4aaac6f4d65e05122495d6e3182649f02 Mon Sep 17 00:00:00 2001 From: hanif salafi Date: Fri, 17 Jan 2025 14:27:10 +0700 Subject: [PATCH] feat: update article files async, magazine, and magazine files --- app/database/entity/magazine_files.entity.go | 31 +- app/database/entity/magazines.entity.go | 26 +- .../service/article_files.service.go | 5 +- .../controller/magazine_files.controller.go | 63 ++- .../magazine_files/magazine_files.module.go | 3 +- .../repository/magazine_files.repository.go | 21 +- .../request/magazine_files.request.go | 66 ++- .../service/magazine_files.service.go | 168 ++++++- .../controller/magazines.controller.go | 43 +- .../magazines/service/magazines.service.go | 24 +- .../users/controller/users.controller.go | 34 ++ app/module/users/response/users.response.go | 4 + app/module/users/service/users.service.go | 104 ++++ app/module/users/users.module.go | 1 + docs/swagger/docs.go | 472 ++++++++++++------ docs/swagger/swagger.json | 472 ++++++++++++------ docs/swagger/swagger.yaml | 365 +++++++++----- go.mod | 12 +- go.sum | 30 +- 19 files changed, 1410 insertions(+), 534 deletions(-) diff --git a/app/database/entity/magazine_files.entity.go b/app/database/entity/magazine_files.entity.go index e694a32..c16ad49 100644 --- a/app/database/entity/magazine_files.entity.go +++ b/app/database/entity/magazine_files.entity.go @@ -3,15 +3,22 @@ package entity import "time" type MagazineFiles struct { - ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` - Title string `json:"title" gorm:"type:varchar"` - Description string `json:"description" gorm:"type:varchar"` - MagazineId int `json:"magazine_id" gorm:"type:int4"` - DownloadCount int `json:"download_count" gorm:"type:int4"` - StatusId int `json:"status_id" gorm:"type:int4"` - IsPublish bool `json:"is_publish" gorm:"type:bool"` - PublishedAt time.Time `json:"published_at" gorm:"type:timestamp"` - IsActive bool `json:"is_active" gorm:"type:bool"` - CreatedAt time.Time `json:"created_at" gorm:"default:now()"` - UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` -} \ No newline at end of file + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + Title string `json:"title" gorm:"type:varchar"` + Description string `json:"description" gorm:"type:varchar"` + MagazineId uint `json:"magazine_id" gorm:"type:int4"` + DownloadCount *int `json:"download_count" gorm:"type:int4"` + StatusId int `json:"status_id" gorm:"type:int4"` + IsPublish *bool `json:"is_publish" gorm:"type:bool"` + FilePath *string `json:"file_path" gorm:"type:varchar"` + FileUrl *string `json:"file_url" gorm:"type:varchar"` + FileName *string `json:"file_name" gorm:"type:varchar"` + FileAlt *string `json:"file_alt" gorm:"type:varchar"` + WidthPixel *string `json:"width_pixel" gorm:"type:varchar"` + HeightPixel *string `json:"height_pixel" gorm:"type:varchar"` + Size *string `json:"size" gorm:"type:varchar"` + PublishedAt *time.Time `json:"published_at" gorm:"type:timestamp"` + IsActive bool `json:"is_active" gorm:"type:bool"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` +} diff --git a/app/database/entity/magazines.entity.go b/app/database/entity/magazines.entity.go index fabd435..074767e 100644 --- a/app/database/entity/magazines.entity.go +++ b/app/database/entity/magazines.entity.go @@ -3,17 +3,17 @@ package entity import "time" type Magazines struct { - ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` - Title string `json:"title" gorm:"type:varchar"` - Description string `json:"description" gorm:"type:varchar"` - ThumbnailPath string `json:"thumbnail_path" gorm:"type:varchar"` + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + Title string `json:"title" gorm:"type:varchar"` + Description string `json:"description" gorm:"type:varchar"` + ThumbnailPath string `json:"thumbnail_path" gorm:"type:varchar"` ThumbnailUrl string `json:"thumbnail_url" gorm:"type:varchar"` - PageUrl string `json:"page_url" gorm:"type:varchar"` - CreatedById int `json:"created_by_id" gorm:"type:int4"` - StatusId int `json:"status_id" gorm:"type:int4"` - IsPublish bool `json:"is_publish" gorm:"type:bool"` - PublishedAt time.Time `json:"published_at" gorm:"type:timestamp"` - IsActive bool `json:"is_active" gorm:"type:bool"` - CreatedAt time.Time `json:"created_at" gorm:"default:now()"` - UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` -} \ No newline at end of file + PageUrl string `json:"page_url" gorm:"type:varchar"` + CreatedById *uint `json:"created_by_id" gorm:"type:int4"` + StatusId int `json:"status_id" gorm:"type:int4"` + IsPublish bool `json:"is_publish" gorm:"type:bool"` + PublishedAt time.Time `json:"published_at" gorm:"type:timestamp"` + IsActive bool `json:"is_active" gorm:"type:bool"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` +} diff --git a/app/module/article_files/service/article_files.service.go b/app/module/article_files/service/article_files.service.go index 497ba9a..a9146c7 100644 --- a/app/module/article_files/service/article_files.service.go +++ b/app/module/article_files/service/article_files.service.go @@ -37,6 +37,7 @@ type ArticleFilesService interface { All(req request.ArticleFilesQueryRequest) (articleFiles []*response.ArticleFilesResponse, paging paginator.Pagination, err error) Show(id uint) (articleFiles *response.ArticleFilesResponse, err error) Save(c *fiber.Ctx, id uint) error + SaveAsync(c *fiber.Ctx, id uint) error Update(id uint, req request.ArticleFilesUpdateRequest) (err error) GetUploadStatus(c *fiber.Ctx) (progress int, err error) Delete(id uint) error @@ -87,7 +88,7 @@ func (_i *articleFilesService) Show(id uint) (articleFiles *response.ArticleFile return mapper.ArticleFilesResponseMapper(result), nil } -func (_i *articleFilesService) Save(c *fiber.Ctx, id uint) (err error) { +func (_i *articleFilesService) SaveAsync(c *fiber.Ctx, id uint) (err error) { bucketName := _i.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName ctx := context.Background() @@ -185,7 +186,7 @@ func (_i *articleFilesService) Save(c *fiber.Ctx, id uint) (err error) { return } -func (_i *articleFilesService) SaveSync(c *fiber.Ctx, id uint) (err error) { +func (_i *articleFilesService) Save(c *fiber.Ctx, id uint) (err error) { bucketName := _i.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName form, err := c.MultipartForm() diff --git a/app/module/magazine_files/controller/magazine_files.controller.go b/app/module/magazine_files/controller/magazine_files.controller.go index cdfe51c..4f2625c 100644 --- a/app/module/magazine_files/controller/magazine_files.controller.go +++ b/app/module/magazine_files/controller/magazine_files.controller.go @@ -21,6 +21,7 @@ type MagazineFilesController interface { Save(c *fiber.Ctx) error Update(c *fiber.Ctx) error Delete(c *fiber.Ctx) error + Viewer(c *fiber.Ctx) error } func NewMagazineFilesController(magazineFilesService service.MagazineFilesService) MagazineFilesController { @@ -35,10 +36,9 @@ func NewMagazineFilesController(magazineFilesService service.MagazineFilesServic // @Tags Magazine Files // @Security Bearer // @Success 200 {object} response.Response -// @Failure 401 {object} response.Response -// @Failure 404 {object} response.Response -// @Failure 422 {object} response.Response -// @Failure 500 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError // @Router /magazine-files [get] func (_i *magazineFilesController) All(c *fiber.Ctx) error { paginate, err := paginator.Paginate(c) @@ -68,10 +68,9 @@ func (_i *magazineFilesController) All(c *fiber.Ctx) error { // @Security Bearer // @Param id path int true "MagazineFiles ID" // @Success 200 {object} response.Response -// @Failure 401 {object} response.Response -// @Failure 404 {object} response.Response -// @Failure 422 {object} response.Response -// @Failure 500 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError // @Router /magazine-files/{id} [get] func (_i *magazineFilesController) Show(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) @@ -95,25 +94,26 @@ func (_i *magazineFilesController) Show(c *fiber.Ctx) error { // @Description API for create MagazineFiles // @Tags Magazine Files // @Security Bearer -// @Body request.MagazineFilesCreateRequest +// @Param files formData file true "Upload file" multiple true +// @Param magazineId path int true "Magazine ID" // @Success 200 {object} response.Response -// @Failure 401 {object} response.Response -// @Failure 404 {object} response.Response -// @Failure 422 {object} response.Response -// @Failure 500 {object} response.Response -// @Router /magazine-files [post] +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /magazine-files/{magazineId} [post] func (_i *magazineFilesController) Save(c *fiber.Ctx) error { - req := new(request.MagazineFilesCreateRequest) - if err := utilVal.ParseAndValidate(c, req); err != nil { + id, err := strconv.ParseUint(c.Params("articleId"), 10, 0) + if err != nil { return err } - err := _i.magazineFilesService.Save(*req) + err = _i.magazineFilesService.Save(c, uint(id)) if err != nil { return err } return utilRes.Resp(c, utilRes.Response{ + Success: true, Messages: utilRes.Messages{"MagazineFiles successfully created"}, }) } @@ -126,10 +126,9 @@ func (_i *magazineFilesController) Save(c *fiber.Ctx) error { // @Body request.MagazineFilesUpdateRequest // @Param id path int true "MagazineFiles ID" // @Success 200 {object} response.Response -// @Failure 401 {object} response.Response -// @Failure 404 {object} response.Response -// @Failure 422 {object} response.Response -// @Failure 500 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError // @Router /magazine-files/{id} [put] func (_i *magazineFilesController) Update(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) @@ -159,10 +158,9 @@ func (_i *magazineFilesController) Update(c *fiber.Ctx) error { // @Security Bearer // @Param id path int true "MagazineFiles ID" // @Success 200 {object} response.Response -// @Failure 401 {object} response.Response -// @Failure 404 {object} response.Response -// @Failure 422 {object} response.Response -// @Failure 500 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError // @Router /magazine-files/{id} [delete] func (_i *magazineFilesController) Delete(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) @@ -179,3 +177,18 @@ func (_i *magazineFilesController) Delete(c *fiber.Ctx) error { Messages: utilRes.Messages{"MagazineFiles successfully deleted"}, }) } + +// Viewer MagazineFiles +// @Summary Create MagazineFiles +// @Description API for create MagazineFiles +// @Tags Magazine Files +// @Security Bearer +// @Param filename path string true "Magazine File Name" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /magazine-files/viewer/{filename} [get] +func (_i *magazineFilesController) Viewer(c *fiber.Ctx) error { + return _i.magazineFilesService.Viewer(c) +} diff --git a/app/module/magazine_files/magazine_files.module.go b/app/module/magazine_files/magazine_files.module.go index b709284..8397c4e 100644 --- a/app/module/magazine_files/magazine_files.module.go +++ b/app/module/magazine_files/magazine_files.module.go @@ -46,8 +46,9 @@ func (_i *MagazineFilesRouter) RegisterMagazineFilesRoutes() { _i.App.Route("/magazine-files", func(router fiber.Router) { router.Get("/", magazineFilesController.All) router.Get("/:id", magazineFilesController.Show) - router.Post("/", magazineFilesController.Save) + router.Post("/:magazineId", magazineFilesController.Save) router.Put("/:id", magazineFilesController.Update) router.Delete("/:id", magazineFilesController.Delete) + router.Get("/viewer/:filename", magazineFilesController.Viewer) }) } diff --git a/app/module/magazine_files/repository/magazine_files.repository.go b/app/module/magazine_files/repository/magazine_files.repository.go index c323076..e389c88 100644 --- a/app/module/magazine_files/repository/magazine_files.repository.go +++ b/app/module/magazine_files/repository/magazine_files.repository.go @@ -15,6 +15,8 @@ type magazineFilesRepository struct { type MagazineFilesRepository interface { GetAll(req request.MagazineFilesQueryRequest) (magazineFiless []*entity.MagazineFiles, paging paginator.Pagination, err error) FindOne(id uint) (magazineFiles *entity.MagazineFiles, err error) + FindByArticle(magazineId uint) (magazineFiles []*entity.MagazineFiles, err error) + FindByFilename(filename string) (magazineFiles *entity.MagazineFiles, err error) Create(magazineFiles *entity.MagazineFiles) (err error) Update(id uint, magazineFiles *entity.MagazineFiles) (err error) Delete(id uint) (err error) @@ -46,6 +48,23 @@ func (_i *magazineFilesRepository) GetAll(req request.MagazineFilesQueryRequest) return } +func (_i *magazineFilesRepository) FindByArticle(magazineId uint) (magazineFiles []*entity.MagazineFiles, err error) { + if err := _i.DB.DB.Where("magazine_id = ?", magazineId).Find(&magazineFiles).Error; err != nil { + return nil, err + } + + return magazineFiles, nil +} + +func (_i *magazineFilesRepository) FindByFilename(magazineFilename string) (magazineFiles *entity.MagazineFiles, err error) { + + if err := _i.DB.DB.Where("file_name = ?", magazineFilename).First(&magazineFiles).Error; err != nil { + return nil, err + } + + return magazineFiles, nil +} + func (_i *magazineFilesRepository) FindOne(id uint) (magazineFiles *entity.MagazineFiles, err error) { if err := _i.DB.DB.First(&magazineFiles, id).Error; err != nil { return nil, err @@ -66,4 +85,4 @@ func (_i *magazineFilesRepository) Update(id uint, magazineFiles *entity.Magazin func (_i *magazineFilesRepository) Delete(id uint) error { return _i.DB.DB.Delete(&entity.MagazineFiles{}, id).Error -} \ No newline at end of file +} diff --git a/app/module/magazine_files/request/magazine_files.request.go b/app/module/magazine_files/request/magazine_files.request.go index 6eaed1e..3b2ad34 100644 --- a/app/module/magazine_files/request/magazine_files.request.go +++ b/app/module/magazine_files/request/magazine_files.request.go @@ -23,14 +23,20 @@ type MagazineFilesQueryRequest struct { } type MagazineFilesCreateRequest struct { - Title string `json:"title" validate:"required"` - Description string `json:"description" validate:"required"` - MagazineId int `json:"magazine_id" validate:"required"` - DownloadCount int `json:"download_count" validate:"required"` - StatusId int `json:"status_id" validate:"required"` - IsPublish bool `json:"is_publish" validate:"required"` - PublishedAt time.Time `json:"published_at" validate:"required"` - IsActive bool `json:"is_active" validate:"required"` + Title string `json:"title" validate:"required"` + Description string `json:"description" validate:"required"` + MagazineId uint `json:"magazine_id" validate:"required"` + StatusId int `json:"status_id" validate:"required"` + DownloadCount *int `json:"download_count"` + FilePath *string `json:"filePath"` + FileUrl *string `json:"fileUrl"` + FileName *string `json:"fileName"` + FileAlt *string `json:"fileAlt"` + WidthPixel *string `json:"widthPixel"` + HeightPixel *string `json:"heightPixel"` + Size *string `json:"size"` + IsPublish *bool `json:"is_publish"` + PublishedAt *time.Time `json:"published_at"` } func (req MagazineFilesCreateRequest) ToEntity() *entity.MagazineFiles { @@ -39,25 +45,35 @@ func (req MagazineFilesCreateRequest) ToEntity() *entity.MagazineFiles { Description: req.Description, MagazineId: req.MagazineId, DownloadCount: req.DownloadCount, + FilePath: req.FilePath, + FileUrl: req.FileUrl, + FileName: req.FileName, + FileAlt: req.FileAlt, + WidthPixel: req.WidthPixel, + HeightPixel: req.HeightPixel, + Size: req.Size, StatusId: req.StatusId, IsPublish: req.IsPublish, PublishedAt: req.PublishedAt, - IsActive: req.IsActive, } } type MagazineFilesUpdateRequest struct { - ID uint `json:"id" validate:"required"` - Title string `json:"title" validate:"required"` - Description string `json:"description" validate:"required"` - MagazineId int `json:"magazine_id" validate:"required"` - DownloadCount int `json:"download_count" validate:"required"` - StatusId int `json:"status_id" validate:"required"` - IsPublish bool `json:"is_publish" validate:"required"` - PublishedAt time.Time `json:"published_at" validate:"required"` - IsActive bool `json:"is_active" validate:"required"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID uint `json:"id" validate:"required"` + Title string `json:"title" validate:"required"` + Description string `json:"description" validate:"required"` + MagazineId uint `json:"magazine_id" validate:"required"` + DownloadCount *int `json:"download_count" validate:"required"` + StatusId int `json:"status_id" validate:"required"` + FilePath *string `json:"filePath"` + FileUrl *string `json:"fileUrl"` + FileName *string `json:"fileName"` + FileAlt *string `json:"fileAlt"` + WidthPixel *string `json:"widthPixel"` + HeightPixel *string `json:"heightPixel"` + Size *string `json:"size"` + IsPublish *bool `json:"is_publish"` + PublishedAt *time.Time `json:"published_at"` } func (req MagazineFilesUpdateRequest) ToEntity() *entity.MagazineFiles { @@ -67,11 +83,15 @@ func (req MagazineFilesUpdateRequest) ToEntity() *entity.MagazineFiles { Description: req.Description, MagazineId: req.MagazineId, DownloadCount: req.DownloadCount, + FilePath: req.FilePath, + FileUrl: req.FileUrl, + FileName: req.FileName, + FileAlt: req.FileAlt, + WidthPixel: req.WidthPixel, + HeightPixel: req.HeightPixel, + Size: req.Size, StatusId: req.StatusId, IsPublish: req.IsPublish, PublishedAt: req.PublishedAt, - IsActive: req.IsActive, - CreatedAt: req.CreatedAt, - UpdatedAt: req.UpdatedAt, } } diff --git a/app/module/magazine_files/service/magazine_files.service.go b/app/module/magazine_files/service/magazine_files.service.go index 4a34b61..5f48d8f 100644 --- a/app/module/magazine_files/service/magazine_files.service.go +++ b/app/module/magazine_files/service/magazine_files.service.go @@ -1,35 +1,50 @@ package service import ( + "context" + "github.com/gofiber/fiber/v2" + "github.com/minio/minio-go/v7" "github.com/rs/zerolog" "go-humas-be/app/module/magazine_files/mapper" "go-humas-be/app/module/magazine_files/repository" "go-humas-be/app/module/magazine_files/request" "go-humas-be/app/module/magazine_files/response" + minioStorage "go-humas-be/config/config" "go-humas-be/utils/paginator" + "io" + "log" + "math/rand" + "mime" + "path/filepath" + "strconv" + "strings" + "time" ) // MagazineFilesService type magazineFilesService struct { - Repo repository.MagazineFilesRepository - Log zerolog.Logger + Repo repository.MagazineFilesRepository + Log zerolog.Logger + MinioStorage *minioStorage.MinioStorage } // MagazineFilesService define interface of IMagazineFilesService type MagazineFilesService interface { All(req request.MagazineFilesQueryRequest) (magazineFiles []*response.MagazineFilesResponse, paging paginator.Pagination, err error) Show(id uint) (magazineFiles *response.MagazineFilesResponse, err error) - Save(req request.MagazineFilesCreateRequest) (err error) + Save(c *fiber.Ctx, id uint) (err error) Update(id uint, req request.MagazineFilesUpdateRequest) (err error) Delete(id uint) error + Viewer(c *fiber.Ctx) error } // NewMagazineFilesService init MagazineFilesService -func NewMagazineFilesService(repo repository.MagazineFilesRepository, log zerolog.Logger) MagazineFilesService { +func NewMagazineFilesService(repo repository.MagazineFilesRepository, log zerolog.Logger, minioStorage *minioStorage.MinioStorage) MagazineFilesService { return &magazineFilesService{ - Repo: repo, - Log: log, + Repo: repo, + Log: log, + MinioStorage: minioStorage, } } @@ -56,10 +71,145 @@ func (_i *magazineFilesService) Show(id uint) (magazineFiles *response.MagazineF return mapper.MagazineFilesResponseMapper(result), nil } -func (_i *magazineFilesService) Save(req request.MagazineFilesCreateRequest) (err error) { - _i.Log.Info().Interface("data", req).Msg("") +func (_i *magazineFilesService) Save(c *fiber.Ctx, id uint) (err error) { + bucketName := _i.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName - return _i.Repo.Create(req.ToEntity()) + form, err := c.MultipartForm() + + if err != nil { + return err + } + //filess := form.File["files"] + + // Create minio connection. + minioClient, err := _i.MinioStorage.ConnectMinio() + + if err != nil { + // Return status 500 and minio connection error. + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": true, + "msg": err.Error(), + }) + } + + for _, files := range form.File { + + _i.Log.Info().Str("timestamp", time.Now(). + Format(time.RFC3339)).Str("Service:Resource", "Uploader:: top"). + Interface("files", files).Msg("") + + for _, fileHeader := range files { + _i.Log.Info().Str("timestamp", time.Now(). + Format(time.RFC3339)).Str("Service:Resource", "Uploader:: loop"). + Interface("data", fileHeader).Msg("") + + src, err := fileHeader.Open() + if err != nil { + return err + } + defer src.Close() + + filename := filepath.Base(fileHeader.Filename) + filenameAlt := filepath.Clean(filename[:len(filename)-len(filepath.Ext(filename))]) + filename = strings.ReplaceAll(filename, " ", "") + filenameWithoutExt := filepath.Clean(filename[:len(filename)-len(filepath.Ext(filename))]) + extension := filepath.Ext(fileHeader.Filename)[1:] + + rand.New(rand.NewSource(time.Now().UnixNano())) + randUniqueId := rand.Intn(1000000) + + newFilenameWithoutExt := filenameWithoutExt + "_" + strconv.Itoa(randUniqueId) + newFilename := newFilenameWithoutExt + "." + extension + + objectName := "magazines/upload/" + newFilename + fileSize := strconv.FormatInt(fileHeader.Size, 10) + + req := request.MagazineFilesCreateRequest{ + MagazineId: id, + Title: newFilename, + FilePath: &objectName, + FileName: &newFilename, + FileAlt: &filenameAlt, + Size: &fileSize, + } + + err = _i.Repo.Create(req.ToEntity()) + if err != nil { + return err + } + + // Upload file ke MinIO + _, err = minioClient.PutObject(context.Background(), bucketName, objectName, src, fileHeader.Size, minio.PutObjectOptions{}) + if err != nil { + return err + } + } + } + + _i.Log.Info().Str("timestamp", time.Now(). + Format(time.RFC3339)).Str("Service:Resource", "User:All"). + Interface("data", "Successfully uploaded").Msg("") + + return +} + +func (_i *magazineFilesService) Viewer(c *fiber.Ctx) (err error) { + filename := c.Params("filename") + result, err := _i.Repo.FindByFilename(filename) + if err != nil { + return err + } + + ctx := context.Background() + bucketName := _i.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName + objectName := *result.FilePath + + _i.Log.Info().Str("timestamp", time.Now(). + Format(time.RFC3339)).Str("Service:Resource", "Article:Uploads"). + Interface("data", objectName).Msg("") + + // Create minio connection. + minioClient, err := _i.MinioStorage.ConnectMinio() + if err != nil { + // Return status 500 and minio connection error. + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": true, + "msg": err.Error(), + }) + } + + fileContent, err := minioClient.GetObject(ctx, bucketName, objectName, minio.GetObjectOptions{}) + if err != nil { + log.Fatalln(err) + } + defer fileContent.Close() + + // Tentukan Content-Type berdasarkan ekstensi file + contentType := mime.TypeByExtension("." + getFileExtension(objectName)) + if contentType == "" { + contentType = "application/octet-stream" // fallback jika tidak ada tipe MIME yang cocok + } + + c.Set("Content-Type", contentType) + + if _, err := io.Copy(c.Response().BodyWriter(), fileContent); err != nil { + return err + } + + return +} + +func getFileExtension(filename string) string { + // split file name + parts := strings.Split(filename, ".") + + // jika tidak ada ekstensi, kembalikan string kosong + if len(parts) == 1 || (len(parts) == 2 && parts[0] == "") { + return "" + } + + // ambil ekstensi terakhir + return parts[len(parts)-1] } func (_i *magazineFilesService) Update(id uint, req request.MagazineFilesUpdateRequest) (err error) { diff --git a/app/module/magazines/controller/magazines.controller.go b/app/module/magazines/controller/magazines.controller.go index fc79f3b..14901c3 100644 --- a/app/module/magazines/controller/magazines.controller.go +++ b/app/module/magazines/controller/magazines.controller.go @@ -35,10 +35,9 @@ func NewMagazinesController(magazinesService service.MagazinesService) Magazines // @Tags Magazines // @Security Bearer // @Success 200 {object} response.Response -// @Failure 401 {object} response.Response -// @Failure 404 {object} response.Response -// @Failure 422 {object} response.Response -// @Failure 500 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError // @Router /magazines [get] func (_i *magazinesController) All(c *fiber.Ctx) error { paginate, err := paginator.Paginate(c) @@ -68,10 +67,9 @@ func (_i *magazinesController) All(c *fiber.Ctx) error { // @Security Bearer // @Param id path int true "Magazines ID" // @Success 200 {object} response.Response -// @Failure 401 {object} response.Response -// @Failure 404 {object} response.Response -// @Failure 422 {object} response.Response -// @Failure 500 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError // @Router /magazines/{id} [get] func (_i *magazinesController) Show(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) @@ -95,12 +93,12 @@ func (_i *magazinesController) Show(c *fiber.Ctx) error { // @Description API for create Magazines // @Tags Magazines // @Security Bearer -// @Body request.MagazinesCreateRequest +// @Param Authorization header string true "Insert your access token" default(Bearer ) +// @Param payload body request.MagazinesCreateRequest true "Required payload" // @Success 200 {object} response.Response -// @Failure 401 {object} response.Response -// @Failure 404 {object} response.Response -// @Failure 422 {object} response.Response -// @Failure 500 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError // @Router /magazines [post] func (_i *magazinesController) Save(c *fiber.Ctx) error { req := new(request.MagazinesCreateRequest) @@ -108,7 +106,8 @@ func (_i *magazinesController) Save(c *fiber.Ctx) error { return err } - err := _i.magazinesService.Save(*req) + authToken := c.Get("Authorization") + err := _i.magazinesService.Save(*req, authToken) if err != nil { return err } @@ -123,13 +122,12 @@ func (_i *magazinesController) Save(c *fiber.Ctx) error { // @Description API for update Magazines // @Tags Magazines // @Security Bearer -// @Body request.MagazinesUpdateRequest // @Param id path int true "Magazines ID" +// @Param payload body request.MagazinesUpdateRequest true "Required payload" // @Success 200 {object} response.Response -// @Failure 401 {object} response.Response -// @Failure 404 {object} response.Response -// @Failure 422 {object} response.Response -// @Failure 500 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError // @Router /magazines/{id} [put] func (_i *magazinesController) Update(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) @@ -159,10 +157,9 @@ func (_i *magazinesController) Update(c *fiber.Ctx) error { // @Security Bearer // @Param id path int true "Magazines ID" // @Success 200 {object} response.Response -// @Failure 401 {object} response.Response -// @Failure 404 {object} response.Response -// @Failure 422 {object} response.Response -// @Failure 500 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError // @Router /magazines/{id} [delete] func (_i *magazinesController) Delete(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 0) diff --git a/app/module/magazines/service/magazines.service.go b/app/module/magazines/service/magazines.service.go index c48b3f1..581f104 100644 --- a/app/module/magazines/service/magazines.service.go +++ b/app/module/magazines/service/magazines.service.go @@ -6,30 +6,34 @@ import ( "go-humas-be/app/module/magazines/repository" "go-humas-be/app/module/magazines/request" "go-humas-be/app/module/magazines/response" + usersRepository "go-humas-be/app/module/users/repository" "go-humas-be/utils/paginator" + utilSvc "go-humas-be/utils/service" ) // MagazinesService type magazinesService struct { - Repo repository.MagazinesRepository - Log zerolog.Logger + Repo repository.MagazinesRepository + UsersRepo usersRepository.UsersRepository + Log zerolog.Logger } // MagazinesService define interface of IMagazinesService type MagazinesService interface { All(req request.MagazinesQueryRequest) (magazines []*response.MagazinesResponse, paging paginator.Pagination, err error) Show(id uint) (magazines *response.MagazinesResponse, err error) - Save(req request.MagazinesCreateRequest) (err error) + Save(req request.MagazinesCreateRequest, authToken string) (err error) Update(id uint, req request.MagazinesUpdateRequest) (err error) Delete(id uint) error } // NewMagazinesService init MagazinesService -func NewMagazinesService(repo repository.MagazinesRepository, log zerolog.Logger) MagazinesService { +func NewMagazinesService(repo repository.MagazinesRepository, usersRepo usersRepository.UsersRepository, log zerolog.Logger) MagazinesService { return &magazinesService{ - Repo: repo, - Log: log, + Repo: repo, + UsersRepo: usersRepo, + Log: log, } } @@ -56,10 +60,14 @@ func (_i *magazinesService) Show(id uint) (magazines *response.MagazinesResponse return mapper.MagazinesResponseMapper(result), nil } -func (_i *magazinesService) Save(req request.MagazinesCreateRequest) (err error) { +func (_i *magazinesService) Save(req request.MagazinesCreateRequest, authToken string) (err error) { _i.Log.Info().Interface("data", req).Msg("") + newReq := req.ToEntity() - return _i.Repo.Create(req.ToEntity()) + createdBy := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken) + newReq.CreatedById = &createdBy.ID + + return _i.Repo.Create(newReq) } func (_i *magazinesService) Update(id uint, req request.MagazinesUpdateRequest) (err error) { diff --git a/app/module/users/controller/users.controller.go b/app/module/users/controller/users.controller.go index 30af1e5..3f9a667 100644 --- a/app/module/users/controller/users.controller.go +++ b/app/module/users/controller/users.controller.go @@ -23,6 +23,7 @@ type UsersController interface { Save(c *fiber.Ctx) error Update(c *fiber.Ctx) error Login(c *fiber.Ctx) error + ParetoLogin(c *fiber.Ctx) error Delete(c *fiber.Ctx) error } @@ -233,6 +234,39 @@ func (_i *usersController) Login(c *fiber.Ctx) error { }) } +// ParetoLogin Users +// @Summary ParetoLogin Users +// @Description API for ParetoLogin Users +// @Tags Users +// @Security Bearer +// @Param payload body request.UserLogin true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /users/pareto-login [post] +func (_i *usersController) ParetoLogin(c *fiber.Ctx) error { + req := new(request.UserLogin) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + loginResponse, err := _i.usersService.ParetoLogin(*req) + if err != nil { + return utilRes.Resp(c, utilRes.Response{ + Success: false, + Code: 401, + Messages: utilRes.Messages{err.Error()}, + }) + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Users successfully login"}, + Data: loginResponse, + }) +} + // Delete Users // @Summary delete Users // @Description API for delete Users diff --git a/app/module/users/response/users.response.go b/app/module/users/response/users.response.go index 6b4d174..ea52bfe 100644 --- a/app/module/users/response/users.response.go +++ b/app/module/users/response/users.response.go @@ -26,3 +26,7 @@ type UsersResponse struct { CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } + +type ParetoLoginResponse struct { + AccessToken string `json:"accessToken"` +} diff --git a/app/module/users/service/users.service.go b/app/module/users/service/users.service.go index e99c7b5..8e48020 100644 --- a/app/module/users/service/users.service.go +++ b/app/module/users/service/users.service.go @@ -1,6 +1,10 @@ package service import ( + paseto "aidanwoods.dev/go-paseto" + "encoding/base64" + "encoding/json" + "fmt" "github.com/Nerzal/gocloak/v13" "github.com/rs/zerolog" "go-humas-be/app/database/entity" @@ -12,6 +16,8 @@ import ( "go-humas-be/config/config" "go-humas-be/utils/paginator" utilSvc "go-humas-be/utils/service" + "strings" + "time" ) // UsersService @@ -29,6 +35,7 @@ type UsersService interface { ShowUserInfo(authToken string) (users *response.UsersResponse, err error) Save(req request.UsersCreateRequest, authToken string) (userReturn *entity.Users, err error) Login(req request.UserLogin) (res *gocloak.JWT, err error) + ParetoLogin(req request.UserLogin) (res *response.ParetoLoginResponse, err error) Update(id uint, req request.UsersUpdateRequest) (err error) Delete(id uint) error } @@ -110,6 +117,81 @@ func (_i *usersService) Login(req request.UserLogin) (res *gocloak.JWT, err erro return loginResponse, nil } +func (_i *usersService) ParetoLogin(req request.UserLogin) (res *response.ParetoLoginResponse, err error) { + _i.Log.Info().Interface("data", req).Msg("") + + var loginResponse *gocloak.JWT + token := paseto.NewToken() + secretKeyHex := "bdc42b1a0ba2bac3e27ba84241f9de06dee71b70f838af8d1beb0417f03d1d00" + secretKey, _ := paseto.V4SymmetricKeyFromHex(secretKeyHex) + // secretKey := paseto.NewV4SymmetricKey() // to change the secretKey periodically + + if req.RefreshToken == nil { + loginResponse, err = _i.Keycloak.Login(*req.Username, *req.Password) + } else { + // Retrieve Refresh Token + parser := paseto.NewParser() + verifiedToken, err := parser.ParseV4Local(secretKey, *req.RefreshToken, nil) + if err != nil { + panic(err) + } + + refreshToken, _ := verifiedToken.GetString("refresh_token") + _i.Log.Info().Interface("Pareto parse refresh token", refreshToken).Msg("") + + loginResponse, err = _i.Keycloak.RefreshToken(refreshToken) + } + + _i.Log.Info().Interface("loginResponse", loginResponse).Msg("") + + if err != nil { + return nil, err + } + + parseToken, err := ParseJWTToken(loginResponse.AccessToken) + if err != nil { + return nil, err + } + + issuedAt := parseToken["iat"].(float64) + expirationTime := parseToken["exp"].(float64) + issuer := parseToken["iss"].(string) + jti := parseToken["jti"].(string) + subject := parseToken["sub"].(string) + + token.SetIssuedAt(time.Unix(int64(issuedAt), 0)) + token.SetNotBefore(time.Unix(int64(issuedAt), 0)) + token.SetExpiration(time.Unix(int64(expirationTime), 0)) + token.SetIssuer(issuer) + token.SetJti(jti) + token.SetSubject(subject) + token.SetString("access_token", loginResponse.AccessToken) + token.SetString("refresh_token", loginResponse.RefreshToken) + + _i.Log.Info().Interface("Pareto Generated Key", secretKey.ExportHex()).Msg("") + + tokenEncrypted := token.V4Encrypt(secretKey, nil) + + parser := paseto.NewParser() + verifiedToken, err := parser.ParseV4Local(secretKey, tokenEncrypted, nil) + if err != nil { + panic(err) + } + + tokenParsing, _ := verifiedToken.GetString("access_token") + _i.Log.Info().Interface("Pareto parse token", tokenParsing).Msg("") + + resLogin := &response.ParetoLoginResponse{ + AccessToken: tokenEncrypted, + } + + if err != nil { + return nil, err + } + + return resLogin, nil +} + func (_i *usersService) Update(id uint, req request.UsersUpdateRequest) (err error) { _i.Log.Info().Interface("data", req).Msg("") newReq := req.ToEntity() @@ -137,3 +219,25 @@ func (_i *usersService) Delete(id uint) error { result.IsActive = &isActive return _i.Repo.Update(id, result) } + +func ParseJWTToken(token string) (map[string]interface{}, error) { + // Pisahkan JWT menjadi 3 bagian: header, payload, dan signature + parts := strings.Split(token, ".") + if len(parts) != 3 { + return nil, fmt.Errorf("Invalid JWT token") + } + + // Decode bagian payload (index ke-1) + payloadData, err := base64.RawURLEncoding.DecodeString(parts[1]) + if err != nil { + return nil, fmt.Errorf("Failed to decode payload: %v", err) + } + + // Ubah payload menjadi map[string]interface{} + var payload map[string]interface{} + if err := json.Unmarshal(payloadData, &payload); err != nil { + return nil, fmt.Errorf("Failed to parse payload JSON: %v", err) + } + + return payload, nil +} diff --git a/app/module/users/users.module.go b/app/module/users/users.module.go index abf60ae..ba8e856 100644 --- a/app/module/users/users.module.go +++ b/app/module/users/users.module.go @@ -50,6 +50,7 @@ func (_i *UsersRouter) RegisterUsersRoutes() { router.Post("/", usersController.Save) router.Put("/:id", usersController.Update) router.Post("/login", usersController.Login) + router.Post("/pareto-login", usersController.ParetoLogin) router.Delete("/:id", usersController.Delete) }) } diff --git a/docs/swagger/docs.go b/docs/swagger/docs.go index 48b9f75..73f4e20 100644 --- a/docs/swagger/docs.go +++ b/docs/swagger/docs.go @@ -2813,33 +2813,29 @@ const docTemplate = `{ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } - }, - "post": { + } + }, + "/magazine-files/viewer/{filename}": { + "get": { "security": [ { "Bearer": [] @@ -2850,6 +2846,15 @@ const docTemplate = `{ "Magazine Files" ], "summary": "Create MagazineFiles", + "parameters": [ + { + "type": "string", + "description": "Magazine File Name", + "name": "filename", + "in": "path", + "required": true + } + ], "responses": { "200": { "description": "OK", @@ -2857,28 +2862,22 @@ const docTemplate = `{ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -2912,28 +2911,22 @@ const docTemplate = `{ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -2965,28 +2958,22 @@ const docTemplate = `{ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -3018,29 +3005,79 @@ const docTemplate = `{ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/magazine-files/{magazineId}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create MagazineFiles", + "tags": [ + "Magazine Files" + ], + "summary": "Create MagazineFiles", + "parameters": [ + { + "type": "file", + "description": "Upload file", + "name": "files", + "in": "formData", + "required": true + }, + { + "type": "integer", + "description": "Magazine ID", + "name": "magazineId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", "schema": { "$ref": "#/definitions/response.Response" } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } } } } @@ -3064,28 +3101,22 @@ const docTemplate = `{ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -3101,6 +3132,25 @@ const docTemplate = `{ "Magazines" ], "summary": "Create Magazines", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.MagazinesCreateRequest" + } + } + ], "responses": { "200": { "description": "OK", @@ -3108,28 +3158,22 @@ const docTemplate = `{ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -3163,28 +3207,22 @@ const docTemplate = `{ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -3207,6 +3245,15 @@ const docTemplate = `{ "name": "id", "in": "path", "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.MagazinesUpdateRequest" + } } ], "responses": { @@ -3216,28 +3263,22 @@ const docTemplate = `{ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -3269,28 +3310,22 @@ const docTemplate = `{ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -5886,6 +5921,57 @@ const docTemplate = `{ } } }, + "/users/pareto-login": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ParetoLogin Users", + "tags": [ + "Users" + ], + "summary": "ParetoLogin Users", + "parameters": [ + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLogin" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, "/users/{id}": { "put": { "security": [ @@ -6376,6 +6462,110 @@ const docTemplate = `{ } } }, + "request.MagazinesCreateRequest": { + "type": "object", + "required": [ + "created_by_id", + "description", + "is_active", + "is_publish", + "page_url", + "published_at", + "status_id", + "thumbnail_path", + "thumbnail_url", + "title" + ], + "properties": { + "created_by_id": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "is_active": { + "type": "boolean" + }, + "is_publish": { + "type": "boolean" + }, + "page_url": { + "type": "string" + }, + "published_at": { + "type": "string" + }, + "status_id": { + "type": "integer" + }, + "thumbnail_path": { + "type": "string" + }, + "thumbnail_url": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.MagazinesUpdateRequest": { + "type": "object", + "required": [ + "created_by_id", + "description", + "id", + "is_active", + "is_publish", + "page_url", + "published_at", + "status_id", + "thumbnail_path", + "thumbnail_url", + "title" + ], + "properties": { + "created_at": { + "type": "string" + }, + "created_by_id": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "is_active": { + "type": "boolean" + }, + "is_publish": { + "type": "boolean" + }, + "page_url": { + "type": "string" + }, + "published_at": { + "type": "string" + }, + "status_id": { + "type": "integer" + }, + "thumbnail_path": { + "type": "string" + }, + "thumbnail_url": { + "type": "string" + }, + "title": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, "request.MasterMenusCreateRequest": { "type": "object", "required": [ diff --git a/docs/swagger/swagger.json b/docs/swagger/swagger.json index 316b70c..a2433e1 100644 --- a/docs/swagger/swagger.json +++ b/docs/swagger/swagger.json @@ -2802,33 +2802,29 @@ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } - }, - "post": { + } + }, + "/magazine-files/viewer/{filename}": { + "get": { "security": [ { "Bearer": [] @@ -2839,6 +2835,15 @@ "Magazine Files" ], "summary": "Create MagazineFiles", + "parameters": [ + { + "type": "string", + "description": "Magazine File Name", + "name": "filename", + "in": "path", + "required": true + } + ], "responses": { "200": { "description": "OK", @@ -2846,28 +2851,22 @@ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -2901,28 +2900,22 @@ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -2954,28 +2947,22 @@ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -3007,29 +2994,79 @@ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/magazine-files/{magazineId}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create MagazineFiles", + "tags": [ + "Magazine Files" + ], + "summary": "Create MagazineFiles", + "parameters": [ + { + "type": "file", + "description": "Upload file", + "name": "files", + "in": "formData", + "required": true + }, + { + "type": "integer", + "description": "Magazine ID", + "name": "magazineId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", "schema": { "$ref": "#/definitions/response.Response" } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } } } } @@ -3053,28 +3090,22 @@ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -3090,6 +3121,25 @@ "Magazines" ], "summary": "Create Magazines", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.MagazinesCreateRequest" + } + } + ], "responses": { "200": { "description": "OK", @@ -3097,28 +3147,22 @@ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -3152,28 +3196,22 @@ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -3196,6 +3234,15 @@ "name": "id", "in": "path", "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.MagazinesUpdateRequest" + } } ], "responses": { @@ -3205,28 +3252,22 @@ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -3258,28 +3299,22 @@ "$ref": "#/definitions/response.Response" } }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/response.Response" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.UnauthorizedError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/response.Response" + "$ref": "#/definitions/response.InternalServerError" } } } @@ -5875,6 +5910,57 @@ } } }, + "/users/pareto-login": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ParetoLogin Users", + "tags": [ + "Users" + ], + "summary": "ParetoLogin Users", + "parameters": [ + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLogin" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, "/users/{id}": { "put": { "security": [ @@ -6365,6 +6451,110 @@ } } }, + "request.MagazinesCreateRequest": { + "type": "object", + "required": [ + "created_by_id", + "description", + "is_active", + "is_publish", + "page_url", + "published_at", + "status_id", + "thumbnail_path", + "thumbnail_url", + "title" + ], + "properties": { + "created_by_id": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "is_active": { + "type": "boolean" + }, + "is_publish": { + "type": "boolean" + }, + "page_url": { + "type": "string" + }, + "published_at": { + "type": "string" + }, + "status_id": { + "type": "integer" + }, + "thumbnail_path": { + "type": "string" + }, + "thumbnail_url": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.MagazinesUpdateRequest": { + "type": "object", + "required": [ + "created_by_id", + "description", + "id", + "is_active", + "is_publish", + "page_url", + "published_at", + "status_id", + "thumbnail_path", + "thumbnail_url", + "title" + ], + "properties": { + "created_at": { + "type": "string" + }, + "created_by_id": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "is_active": { + "type": "boolean" + }, + "is_publish": { + "type": "boolean" + }, + "page_url": { + "type": "string" + }, + "published_at": { + "type": "string" + }, + "status_id": { + "type": "integer" + }, + "thumbnail_path": { + "type": "string" + }, + "thumbnail_url": { + "type": "string" + }, + "title": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, "request.MasterMenusCreateRequest": { "type": "object", "required": [ diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index 013236a..9fcf080 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -265,6 +265,81 @@ definitions: - slug - title type: object + request.MagazinesCreateRequest: + properties: + created_by_id: + type: integer + description: + type: string + is_active: + type: boolean + is_publish: + type: boolean + page_url: + type: string + published_at: + type: string + status_id: + type: integer + thumbnail_path: + type: string + thumbnail_url: + type: string + title: + type: string + required: + - created_by_id + - description + - is_active + - is_publish + - page_url + - published_at + - status_id + - thumbnail_path + - thumbnail_url + - title + type: object + request.MagazinesUpdateRequest: + properties: + created_at: + type: string + created_by_id: + type: integer + description: + type: string + id: + type: integer + is_active: + type: boolean + is_publish: + type: boolean + page_url: + type: string + published_at: + type: string + status_id: + type: integer + thumbnail_path: + type: string + thumbnail_url: + type: string + title: + type: string + updated_at: + type: string + required: + - created_by_id + - description + - id + - is_active + - is_publish + - page_url + - published_at + - status_id + - thumbnail_path + - thumbnail_url + - title + type: object request.MasterMenusCreateRequest: properties: description: @@ -2381,55 +2456,23 @@ paths: description: OK schema: $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' "401": description: Unauthorized schema: - $ref: '#/definitions/response.Response' - "404": - description: Not Found - schema: - $ref: '#/definitions/response.Response' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.UnauthorizedError' "500": description: Internal Server Error schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.InternalServerError' security: - Bearer: [] summary: Get all MagazineFiles tags: - Magazine Files - post: - description: API for create MagazineFiles - responses: - "200": - description: OK - schema: - $ref: '#/definitions/response.Response' - "401": - description: Unauthorized - schema: - $ref: '#/definitions/response.Response' - "404": - description: Not Found - schema: - $ref: '#/definitions/response.Response' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/response.Response' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/response.Response' - security: - - Bearer: [] - summary: Create MagazineFiles - tags: - - Magazine Files /magazine-files/{id}: delete: description: API for delete MagazineFiles @@ -2444,22 +2487,18 @@ paths: description: OK schema: $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' "401": description: Unauthorized schema: - $ref: '#/definitions/response.Response' - "404": - description: Not Found - schema: - $ref: '#/definitions/response.Response' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.UnauthorizedError' "500": description: Internal Server Error schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.InternalServerError' security: - Bearer: [] summary: delete MagazineFiles @@ -2478,22 +2517,18 @@ paths: description: OK schema: $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' "401": description: Unauthorized schema: - $ref: '#/definitions/response.Response' - "404": - description: Not Found - schema: - $ref: '#/definitions/response.Response' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.UnauthorizedError' "500": description: Internal Server Error schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.InternalServerError' security: - Bearer: [] summary: Get one MagazineFiles @@ -2512,27 +2547,90 @@ paths: description: OK schema: $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' "401": description: Unauthorized schema: - $ref: '#/definitions/response.Response' - "404": - description: Not Found - schema: - $ref: '#/definitions/response.Response' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.UnauthorizedError' "500": description: Internal Server Error schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.InternalServerError' security: - Bearer: [] summary: Update MagazineFiles tags: - Magazine Files + /magazine-files/{magazineId}: + post: + description: API for create MagazineFiles + parameters: + - description: Upload file + in: formData + name: files + required: true + type: file + - description: Magazine ID + in: path + name: magazineId + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create MagazineFiles + tags: + - Magazine Files + /magazine-files/viewer/{filename}: + get: + description: API for create MagazineFiles + parameters: + - description: Magazine File Name + in: path + name: filename + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create MagazineFiles + tags: + - Magazine Files /magazines: get: description: API for getting all Magazines @@ -2541,22 +2639,18 @@ paths: description: OK schema: $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' "401": description: Unauthorized schema: - $ref: '#/definitions/response.Response' - "404": - description: Not Found - schema: - $ref: '#/definitions/response.Response' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.UnauthorizedError' "500": description: Internal Server Error schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.InternalServerError' security: - Bearer: [] summary: Get all Magazines @@ -2564,27 +2658,36 @@ paths: - Magazines post: description: API for create Magazines + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.MagazinesCreateRequest' responses: "200": description: OK schema: $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' "401": description: Unauthorized schema: - $ref: '#/definitions/response.Response' - "404": - description: Not Found - schema: - $ref: '#/definitions/response.Response' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.UnauthorizedError' "500": description: Internal Server Error schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.InternalServerError' security: - Bearer: [] summary: Create Magazines @@ -2604,22 +2707,18 @@ paths: description: OK schema: $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' "401": description: Unauthorized schema: - $ref: '#/definitions/response.Response' - "404": - description: Not Found - schema: - $ref: '#/definitions/response.Response' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.UnauthorizedError' "500": description: Internal Server Error schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.InternalServerError' security: - Bearer: [] summary: Delete Magazines @@ -2638,22 +2737,18 @@ paths: description: OK schema: $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' "401": description: Unauthorized schema: - $ref: '#/definitions/response.Response' - "404": - description: Not Found - schema: - $ref: '#/definitions/response.Response' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.UnauthorizedError' "500": description: Internal Server Error schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.InternalServerError' security: - Bearer: [] summary: Get one Magazines @@ -2667,27 +2762,29 @@ paths: name: id required: true type: integer + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.MagazinesUpdateRequest' responses: "200": description: OK schema: $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' "401": description: Unauthorized schema: - $ref: '#/definitions/response.Response' - "404": - description: Not Found - schema: - $ref: '#/definitions/response.Response' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.UnauthorizedError' "500": description: Internal Server Error schema: - $ref: '#/definitions/response.Response' + $ref: '#/definitions/response.InternalServerError' security: - Bearer: [] summary: Update Magazines @@ -4394,4 +4491,36 @@ paths: summary: Login Users tags: - Users + /users/pareto-login: + post: + description: API for ParetoLogin Users + parameters: + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserLogin' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: ParetoLogin Users + tags: + - Users swagger: "2.0" diff --git a/go.mod b/go.mod index ee34d40..73398de 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module go-humas-be go 1.21.6 require ( + aidanwoods.dev/go-paseto v1.5.3 github.com/Nerzal/gocloak/v13 v13.9.0 github.com/arsmn/fiber-swagger/v2 v2.31.1 github.com/efectn/fx-zerolog v1.1.0 @@ -21,6 +22,7 @@ require ( ) require ( + aidanwoods.dev/go-result v0.1.0 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -65,11 +67,11 @@ require ( go.uber.org/dig v1.17.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.19.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.21.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3ea4963..a4917e3 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,7 @@ +aidanwoods.dev/go-paseto v1.5.3 h1:y3pRY9MLWBhfO9VuCN0Bkyxa7Xmkt5coipYJfaOZgOs= +aidanwoods.dev/go-paseto v1.5.3/go.mod h1://T4uDrCXnzls7pKeCXaQ/zC3xv0KtgGMk4wnlOAHSs= +aidanwoods.dev/go-result v0.1.0 h1:y/BMIRX6q3HwaorX1Wzrjo3WUdiYeyWbvGe18hKS3K8= +aidanwoods.dev/go-result v0.1.0/go.mod h1:yridkWghM7AXSFA6wzx0IbsurIm1Lhuro3rYef8FBHM= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= @@ -191,13 +195,13 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -210,12 +214,14 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -232,8 +238,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -244,16 +250,16 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= -golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=