diff --git a/pkg/internal/web/api/index.go b/pkg/internal/web/api/index.go index 30ae399..ed7f4c0 100644 --- a/pkg/internal/web/api/index.go +++ b/pkg/internal/web/api/index.go @@ -198,6 +198,9 @@ func MapControllers(app *fiber.App, baseURL string) { } } + api.Post("/permissions/check", checkPermission) + api.Post("/permissions/check/:userId", checkUserPermission) + api.All("/*", func(c *fiber.Ctx) error { return fiber.ErrNotFound }) diff --git a/pkg/internal/web/api/perms_api.go b/pkg/internal/web/api/perms_api.go new file mode 100644 index 0000000..737c6e4 --- /dev/null +++ b/pkg/internal/web/api/perms_api.go @@ -0,0 +1,53 @@ +package api + +import ( + "git.solsynth.dev/hypernet/passport/pkg/authkit/models" + "git.solsynth.dev/hypernet/passport/pkg/internal/services" + "git.solsynth.dev/hypernet/passport/pkg/internal/web/exts" + "github.com/gofiber/fiber/v2" + jsoniter "github.com/json-iterator/go" +) + +func checkPermission(c *fiber.Ctx) error { + var data struct { + PermNode string `json:"perm_node" validate:"required"` + Value any `json:"value" validate:"required"` + } + if err := exts.BindAndValidate(c, &data); err != nil { + return err + } + if err := exts.EnsureAuthenticated(c); err != nil { + return err + } + user := c.Locals("user").(models.Account) + var heldPerms map[string]any + rawHeldPerms, _ := jsoniter.Marshal(user.PermNodes) + _ = jsoniter.Unmarshal(rawHeldPerms, &heldPerms) + valid := services.HasPermNode(heldPerms, data.PermNode, data.Value) + if !valid { + return c.SendStatus(fiber.StatusForbidden) + } + return c.SendStatus(fiber.StatusOK) +} + +func checkUserPermission(c *fiber.Ctx) error { + var data struct { + PermNode string `json:"perm_node" validate:"required"` + Value any `json:"value" validate:"required"` + } + if err := exts.EnsureAuthenticated(c); err != nil { + return err + } + user := c.Locals("user").(models.Account) + relatedId, _ := c.ParamsInt("userId") + relation, err := services.GetRelationWithTwoNode(user.ID, uint(relatedId)) + if err != nil { + return err + } + defaultPerm := relation.Status == models.RelationshipFriend + valid := services.HasPermNodeWithDefault(relation.PermNodes, data.PermNode, data.Value, defaultPerm) + if !valid { + return c.SendStatus(fiber.StatusForbidden) + } + return c.SendStatus(fiber.StatusOK) +}