forked from ebhomengo/niki
add store role feature
This commit is contained in:
parent
3b22e99697
commit
7a54387722
|
|
@ -0,0 +1,69 @@
|
||||||
|
package authorizationapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/authorizationapp/delivery/http"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/domain/authorization/repository"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/domain/authorization/service"
|
||||||
|
cfgloader "git.gocasts.ir/ebhomengo/niki/pkg/cfg_loader"
|
||||||
|
mySql "git.gocasts.ir/ebhomengo/niki/pkg/database/mysql"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/pkg/httpserver"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/pkg/path"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
HTTPServer httpserver.Config `koanf:"http_server"`
|
||||||
|
MySQLDB mySql.Config `koanf:"mariadb"`
|
||||||
|
}
|
||||||
|
type Application struct {
|
||||||
|
RoleRepo *repository.DB
|
||||||
|
AuthorizationService service.Authorization
|
||||||
|
RoleHandler http.RoleHandler
|
||||||
|
RoleServer http.RoleServer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Application) Setup() Application {
|
||||||
|
appConfig := a.getYamlConfigPath()
|
||||||
|
db := mySql.New(appConfig.MySQLDB)
|
||||||
|
roleRepo := repository.New(db)
|
||||||
|
authorizationService := service.NewAuthorization(roleRepo)
|
||||||
|
roleHandler := http.NewRoleHandler(authorizationService)
|
||||||
|
server := http.NewRoleServer(appConfig.HTTPServer, roleHandler)
|
||||||
|
|
||||||
|
return Application{
|
||||||
|
RoleRepo: roleRepo,
|
||||||
|
AuthorizationService: authorizationService,
|
||||||
|
RoleHandler: roleHandler,
|
||||||
|
RoleServer: server,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Application) getYamlConfigPath() Config {
|
||||||
|
var appConfig Config
|
||||||
|
|
||||||
|
projectRoot, err := path.PathProjectRoot()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error finding project root: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig := filepath.Join(projectRoot, "deploy", "authorization", "config.yml")
|
||||||
|
_, err = os.Stat(defaultConfig)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
options := cfgloader.Option{
|
||||||
|
Prefix: "AUTHORIZATION_",
|
||||||
|
Delimiter: ".",
|
||||||
|
Separator: "__",
|
||||||
|
YamlFilePath: defaultConfig,
|
||||||
|
CallbackEnv: nil,
|
||||||
|
}
|
||||||
|
err = cfgloader.Load(options, &appConfig)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed loading authorization config: %v", err)
|
||||||
|
}
|
||||||
|
return appConfig
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/domain/authorization/service"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoleHandler struct {
|
||||||
|
service service.Authorization
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRoleHandler(service service.Authorization) RoleHandler {
|
||||||
|
return RoleHandler{service: service}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RoleHandler) Store(c *gin.Context) {
|
||||||
|
var request service.StoreRoleRequest
|
||||||
|
err := c.ShouldBindJSON(&request)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
role, err := r.service.Store(c, request)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("role %s created successfully", role.Title_fa)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/pkg/httpserver"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoleServer struct {
|
||||||
|
cfg httpserver.Config
|
||||||
|
handler RoleHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRoleServer(cfg httpserver.Config, handler RoleHandler) RoleServer {
|
||||||
|
return RoleServer{cfg: cfg, handler: handler}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s RoleServer) Start() {
|
||||||
|
r := gin.Default()
|
||||||
|
r.POST("/role/create", s.handler.Store)
|
||||||
|
|
||||||
|
err := r.Run(fmt.Sprintf("%s:%s", s.cfg.Host, s.cfg.Port))
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
database:
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package entity
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/types"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Role struct {
|
||||||
|
ID types.ID `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Title_fa string `json:"title_Fa"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
-- +migrate Up
|
||||||
|
CREATE TABLE IF NOT EXISTS `roles` (
|
||||||
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||||
|
`title` VARCHAR(255) NOT NULL,
|
||||||
|
`title_fa` VARCHAR(255) NOT NULL,
|
||||||
|
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `idx_roles_title` (`title`),
|
||||||
|
UNIQUE KEY `idx_roles_title_fa` (`title_fa`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- +migrate Down
|
||||||
|
DROP TABLE IF EXISTS `roles`;
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/domain/authorization/service"
|
||||||
|
|
||||||
|
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/pkg/database/mysql"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DB struct {
|
||||||
|
conn *mysql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(conn *mysql.DB) *DB {
|
||||||
|
return &DB{conn: conn}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m DB) Store(ctx context.Context, req service.StoreRoleRequest) (types.ID, error) {
|
||||||
|
const op = "domain.authorization.repository.role.store"
|
||||||
|
|
||||||
|
result, err := m.conn.Conn().ExecContext(ctx, "INSERT INTO roles VALUES (`?,?`)", req.Title, req.TitleFa)
|
||||||
|
if err != nil {
|
||||||
|
return 0, richerror.New(op).WithErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
roleID, err := result.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
return 0, richerror.New(op).WithErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return types.ID(roleID), nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/domain/authorization/entity"
|
||||||
|
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
|
||||||
|
"github.com/go-ozzo/ozzo-validation/v4"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Authorization struct {
|
||||||
|
roleRepo RoleRepo
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAuthorization(roleRepo RoleRepo) Authorization {
|
||||||
|
return Authorization{roleRepo: roleRepo}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Authorization) Store(ctx context.Context, req StoreRoleRequest) (entity.Role, error) {
|
||||||
|
const op = "authorizationservice.Store"
|
||||||
|
|
||||||
|
if err := a.validateRole(req); err != nil {
|
||||||
|
return entity.Role{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
|
||||||
|
}
|
||||||
|
|
||||||
|
role, err := a.roleRepo.Store(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
return entity.Role{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
|
||||||
|
}
|
||||||
|
return role, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Authorization) validateRole(req StoreRoleRequest) error {
|
||||||
|
return validation.ValidateStruct(&req,
|
||||||
|
validation.Field(&req.Title,
|
||||||
|
validation.Required,
|
||||||
|
validation.Length(4, 0),
|
||||||
|
validation.Match(regexp.MustCompile(`^[a-zA-Z\s]+$`))),
|
||||||
|
|
||||||
|
validation.Field(&req.TitleFa,
|
||||||
|
validation.Required,
|
||||||
|
validation.Length(4, 0),
|
||||||
|
validation.Match(regexp.MustCompile(`^[\x{0600}-\x{06FF}\s]+$`))),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
type StoreRoleRequest struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
TitleFa string `json:"title_fa"`
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoleRepo interface {
|
||||||
|
Store(ctx context.Context, req StoreRoleRequest) (types.ID, error)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue