diff --git a/api/v1/domain/admin/admin.go b/api/v1/domain/admin/admin.go new file mode 100644 index 0000000..25b0251 --- /dev/null +++ b/api/v1/domain/admin/admin.go @@ -0,0 +1,15 @@ +package admin + +import ( + "github.com/gin-gonic/gin" +) + +// ApplyRoutes applies router to gin Router +func ApplyRoutes(r *gin.RouterGroup) { + g := r.Group("/admin") + { + g.GET("", getAdmin) + g.POST("", createAdmin) + g.DELETE("", deleteAdmin) + } +} diff --git a/api/v1/domain/admin/create.go b/api/v1/domain/admin/create.go new file mode 100644 index 0000000..dcab124 --- /dev/null +++ b/api/v1/domain/admin/create.go @@ -0,0 +1,73 @@ +package admin + +import ( + "errors" + "fmt" + "net/http" + + "github.com/NetSepio/gateway/api/middleware/auth/paseto" + "github.com/NetSepio/gateway/config/dbconfig" + "github.com/NetSepio/gateway/models" + "github.com/NetSepio/gateway/util/pkg/logwrapper" + "github.com/TheLazarusNetwork/go-helpers/httpo" + "github.com/gin-gonic/gin" + "github.com/jackc/pgconn" + "gorm.io/gorm" +) + +func createAdmin(c *gin.Context) { + db := dbconfig.GetDb() + var request CreateAdminRequest + err := c.BindJSON(&request) + if err != nil { + //TODO not override status or not set status again + httpo.NewErrorResponse(http.StatusBadRequest, fmt.Sprintf("payload is invalid %s", err)).SendD(c) + return + } + + walletAddress := c.GetString(paseto.CTX_WALLET_ADDRES) + + err = db.Model(&models.DomainAdmin{}). + Where(&models.DomainAdmin{DomainId: request.DomainId, AdminWalletAddress: walletAddress}). + First(&models.DomainAdmin{}).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + httpo.NewErrorResponse(http.StatusNotFound, "domain not exist or user is not admin of the domain").SendD(c) + return + } + + logwrapper.Errorf("failed to get domain admin: %s", err) + httpo.NewErrorResponse(http.StatusInternalServerError, "failed to update admin").SendD(c) + } + + adminDetails := make([]models.DomainAdmin, len(request.Admins)) + + i := 0 + for _, v := range request.Admins { + adminDetails[i].DomainId = request.DomainId + adminDetails[i].AdminWalletAddress = v.AdminWalletAddress + adminDetails[i].UpdatedByAddress = walletAddress + adminDetails[i].Name = v.AdminName + adminDetails[i].Role = v.AdminRole + } + err = db.Create(&adminDetails).Error + if err != nil { + var pgError *pgconn.PgError + if errors.As(err, &pgError) { + if pgError.Code == "23503" && pgError.ConstraintName == "fk_domain_admins_admin" { + httpo.NewErrorResponse(http.StatusBadRequest, "admin address not found").SendD(c) + return + } + + if pgError.Code == "23505" && pgError.ConstraintName == "domain_admins_pkey" { + httpo.NewErrorResponse(http.StatusBadRequest, "admin already exist").SendD(c) + return + } + } + logwrapper.Errorf("failed to get domain admin: %s", err) + httpo.NewErrorResponse(http.StatusInternalServerError, "failed to update admin").SendD(c) + return + } + + httpo.NewSuccessResponse(200, "updated admins").SendD(c) +} diff --git a/api/v1/domain/admin/delete.go b/api/v1/domain/admin/delete.go new file mode 100644 index 0000000..a6a7bf6 --- /dev/null +++ b/api/v1/domain/admin/delete.go @@ -0,0 +1,56 @@ +package admin + +import ( + "errors" + "fmt" + "net/http" + "strings" + + "github.com/NetSepio/gateway/api/middleware/auth/paseto" + "github.com/NetSepio/gateway/config/dbconfig" + "github.com/NetSepio/gateway/models" + "github.com/NetSepio/gateway/util/pkg/logwrapper" + "github.com/TheLazarusNetwork/go-helpers/httpo" + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +func deleteAdmin(c *gin.Context) { + db := dbconfig.GetDb() + var request DeleteAdminRequest + err := c.BindJSON(&request) + if err != nil { + //TODO not override status or not set status again + httpo.NewErrorResponse(http.StatusBadRequest, fmt.Sprintf("payload is invalid %s", err)).SendD(c) + return + } + + walletAddress := c.GetString(paseto.CTX_WALLET_ADDRES) + + err = db.Model(&models.DomainAdmin{}). + Where(&models.DomainAdmin{DomainId: request.DomainId, AdminWalletAddress: walletAddress}). + First(&models.DomainAdmin{}).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + httpo.NewErrorResponse(http.StatusNotFound, "domain not exist or user is not admin of the domain").SendD(c) + return + } + + logwrapper.Errorf("failed to get domain admin: %s", err) + httpo.NewErrorResponse(http.StatusInternalServerError, "failed to update admin").SendD(c) + } + + res := db.Delete(&models.DomainAdmin{DomainId: request.DomainId, AdminWalletAddress: strings.ToLower(request.AdminWalletAddres)}) + if res.Error != nil { + logwrapper.Errorf("failed to delete domain admin: %s", err) + httpo.NewErrorResponse(http.StatusInternalServerError, "failed to remove admin").SendD(c) + return + } + + if res.RowsAffected == 0 { + httpo.NewErrorResponse(http.StatusNotFound, "admin not exist for that domain").SendD(c) + return + } + + httpo.NewSuccessResponse(200, "admin removed").SendD(c) +} diff --git a/api/v1/domain/admin/query.go b/api/v1/domain/admin/query.go new file mode 100644 index 0000000..b3afd64 --- /dev/null +++ b/api/v1/domain/admin/query.go @@ -0,0 +1,50 @@ +package admin + +import ( + "errors" + "fmt" + "net/http" + + "github.com/NetSepio/gateway/api/middleware/auth/paseto" + "github.com/NetSepio/gateway/config/dbconfig" + "github.com/NetSepio/gateway/models" + "github.com/NetSepio/gateway/util/pkg/logwrapper" + "github.com/TheLazarusNetwork/go-helpers/httpo" + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +func getAdmin(c *gin.Context) { + db := dbconfig.GetDb() + var request GetAdminQuery + err := c.BindJSON(&request) + if err != nil { + //TODO not override status or not set status again + httpo.NewErrorResponse(http.StatusBadRequest, fmt.Sprintf("payload is invalid %s", err)).SendD(c) + return + } + + walletAddress := c.GetString(paseto.CTX_WALLET_ADDRES) + + err = db.Model(&models.DomainAdmin{}). + Where(&models.DomainAdmin{DomainId: request.DomainId, AdminWalletAddress: walletAddress}). + First(&models.DomainAdmin{}).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + httpo.NewErrorResponse(http.StatusNotFound, "domain not exist or user is not admin of the domain").SendD(c) + return + } + + logwrapper.Errorf("failed to get domain admin: %s", err) + httpo.NewErrorResponse(http.StatusInternalServerError, "failed to get admins").SendD(c) + } + + var domainAdmins []models.DomainAdmin + err = db.Where(&models.DomainAdmin{DomainId: request.DomainId}).Find(&domainAdmins).Error + if err != nil { + logwrapper.Errorf("failed to get domain admins: %s", err) + httpo.NewErrorResponse(http.StatusInternalServerError, "failed to get admins").SendD(c) + } + + httpo.NewSuccessResponseP(200, "fetch admins", domainAdmins).SendD(c) +} diff --git a/api/v1/domain/admin/type.go b/api/v1/domain/admin/type.go new file mode 100644 index 0000000..693eb8b --- /dev/null +++ b/api/v1/domain/admin/type.go @@ -0,0 +1,21 @@ +package admin + +type GetAdminQuery struct { + DomainId string `json:"domainId" binding:"required"` +} + +type DeleteAdminRequest struct { + AdminWalletAddres string `json:"adminWalletAddress" binding:"required,min=5"` + DomainId string `json:"domainId" binding:"required,min=10"` +} + +type AdminDetails struct { + AdminName string `json:"adminName" binding:"required,min=1"` + AdminRole string `json:"adminRole" binding:"required,min=1"` + AdminWalletAddress string `json:"adminWalletAddress" binding:"required,min=1"` +} + +type CreateAdminRequest struct { + Admins []AdminDetails `json:"admins" binding:"min=1,dive"` + DomainId string `json:"domainId" binding:"required,min=10"` +} diff --git a/api/v1/domain/domain.go b/api/v1/domain/domain.go index 2252897..8b5f12c 100644 --- a/api/v1/domain/domain.go +++ b/api/v1/domain/domain.go @@ -2,6 +2,7 @@ package domain import ( "github.com/NetSepio/gateway/api/middleware/auth/paseto" + "github.com/NetSepio/gateway/api/v1/domain/admin" "github.com/gin-gonic/gin" ) @@ -15,5 +16,6 @@ func ApplyRoutes(r *gin.RouterGroup) { g.DELETE("", deleteDomain) g.PATCH("", patchDomain) g.PATCH("/verify", verifyDomain) + admin.ApplyRoutes(g) } } diff --git a/models/Domain.go b/models/Domain.go index 2902304..089cb83 100644 --- a/models/Domain.go +++ b/models/Domain.go @@ -22,12 +22,12 @@ type Domain struct { } type DomainAdmin struct { - DomainId string - Domain Domain `gorm:"foreignkey:DomainId"` - Admin User `gorm:"foreignkey:AdminWalletAddress"` - UpdatedBy User `gorm:"foreignkey:UpdatedByAddress"` - UpdatedByAddress string - Name string - Role string - AdminWalletAddress string + DomainId string `gorm:"primary_key" json:"domainId"` + Domain Domain `gorm:"foreignkey:DomainId" json:"-"` + Admin User `gorm:"foreignkey:AdminWalletAddress" json:"-"` + UpdatedBy User `gorm:"foreignkey:UpdatedByAddress" json:"-"` + UpdatedByAddress string `json:"updatedBy"` + Name string `json:"name"` + Role string `json:"role"` + AdminWalletAddress string `gorm:"primary_key" json:"walletAddress"` }