mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-16 04:13:12 +00:00
feat: register workspace user api
This commit is contained in:
parent
3364d1bf39
commit
c0699f159e
@ -23,24 +23,25 @@ func (e Role) String() string {
|
||||
type WorkspaceUser struct {
|
||||
WorkspaceID int `json:"workspaceId"`
|
||||
UserID int `json:"userId"`
|
||||
User *User `json:"user"`
|
||||
Role Role `json:"role"`
|
||||
CreatedTs int64 `json:"createdTs"`
|
||||
UpdatedTs int64 `json:"updatedTs"`
|
||||
}
|
||||
|
||||
type WorkspaceUserUpsert struct {
|
||||
WorkspaceID int `json:"workspaceId"`
|
||||
UserID int `json:"userId"`
|
||||
Role Role `json:"role"`
|
||||
UpdatedTs int64 `json:"updatedTs"`
|
||||
WorkspaceID int `json:"workspaceId"`
|
||||
UserID int `json:"userId"`
|
||||
Role Role `json:"role"`
|
||||
UpdatedTs *int64 `json:"updatedTs"`
|
||||
}
|
||||
|
||||
type WorkspaceUserFind struct {
|
||||
WorkspaceID *int `json:"workspaceId"`
|
||||
UserID *int `json:"userId"`
|
||||
WorkspaceID *int
|
||||
UserID *int
|
||||
}
|
||||
|
||||
type WorkspaceUserDelete struct {
|
||||
WorkspaceID int `json:"workspaceId"`
|
||||
UserID int `json:"userId"`
|
||||
WorkspaceID int
|
||||
UserID int
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ func NewServer(profile *profile.Profile) *Server {
|
||||
s.registerAuthRoutes(apiGroup)
|
||||
s.registerUserRoutes(apiGroup)
|
||||
s.registerWorkspaceRoutes(apiGroup)
|
||||
s.registerWorkspaceUserRoutes(apiGroup)
|
||||
s.registerShortcutRoutes(apiGroup)
|
||||
|
||||
return s
|
||||
|
159
server/workspace_user.go
Normal file
159
server/workspace_user.go
Normal file
@ -0,0 +1,159 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/boojack/corgi/api"
|
||||
"github.com/boojack/corgi/common"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func (s *Server) registerWorkspaceUserRoutes(g *echo.Group) {
|
||||
g.POST("/workspace/:id/user", func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
userID, ok := c.Get(getUserIDContextKey()).(int)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing auth session")
|
||||
}
|
||||
|
||||
workspaceID, err := strconv.Atoi(c.Param("id"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted workspace id").SetInternal(err)
|
||||
}
|
||||
|
||||
currentWorkspaceUser, err := s.Store.FindWordspaceUser(ctx, &api.WorkspaceUserFind{
|
||||
WorkspaceID: &workspaceID,
|
||||
UserID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find workspace user").SetInternal(err)
|
||||
}
|
||||
if currentWorkspaceUser.Role != api.RoleAdmin {
|
||||
return echo.NewHTTPError(http.StatusForbidden, "Access forbidden to add workspace user").SetInternal(err)
|
||||
}
|
||||
|
||||
workspaceUserUpsert := &api.WorkspaceUserUpsert{
|
||||
WorkspaceID: workspaceID,
|
||||
}
|
||||
if err := json.NewDecoder(c.Request().Body).Decode(workspaceUserUpsert); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post workspace user request").SetInternal(err)
|
||||
}
|
||||
|
||||
workspaceUser, err := s.Store.UpsertWorkspaceUser(ctx, workspaceUserUpsert)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to upsert workspace user").SetInternal(err)
|
||||
}
|
||||
if err := s.Store.ComposeWorkspaceUser(ctx, workspaceUser); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose workspace user").SetInternal(err)
|
||||
}
|
||||
|
||||
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8)
|
||||
if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(workspaceUser)); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to encode workspace user response").SetInternal(err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
g.GET("/workspace/:id/user", func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
workspaceID, err := strconv.Atoi(c.Param("id"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted workspace id").SetInternal(err)
|
||||
}
|
||||
|
||||
workspaceUserList, err := s.Store.FindWordspaceUserList(ctx, &api.WorkspaceUserFind{
|
||||
WorkspaceID: &workspaceID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find workspace user list").SetInternal(err)
|
||||
}
|
||||
|
||||
for _, workspaceUser := range workspaceUserList {
|
||||
if err := s.Store.ComposeWorkspaceUser(ctx, workspaceUser); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose workspace user").SetInternal(err)
|
||||
}
|
||||
}
|
||||
|
||||
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8)
|
||||
if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(workspaceUserList)); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to encode workspace user list response").SetInternal(err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
g.GET("/workspace/:workspaceId/user/:userId", func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
workspaceID, err := strconv.Atoi(c.Param("workspaceId"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted workspace id").SetInternal(err)
|
||||
}
|
||||
userID, err := strconv.Atoi(c.Param("userId"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted user id").SetInternal(err)
|
||||
}
|
||||
|
||||
workspaceUser, err := s.Store.FindWordspaceUser(ctx, &api.WorkspaceUserFind{
|
||||
WorkspaceID: &workspaceID,
|
||||
UserID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find workspace user").SetInternal(err)
|
||||
}
|
||||
|
||||
if err := s.Store.ComposeWorkspaceUser(ctx, workspaceUser); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose workspace user").SetInternal(err)
|
||||
}
|
||||
|
||||
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8)
|
||||
if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(workspaceUser)); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to encode workspace user response").SetInternal(err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
g.DELETE("/workspace/:workspaceId/user/:userId", func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
userID, ok := c.Get(getUserIDContextKey()).(int)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing auth session")
|
||||
}
|
||||
|
||||
workspaceID, err := strconv.Atoi(c.Param("workspaceId"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted workspace id").SetInternal(err)
|
||||
}
|
||||
|
||||
currentWorkspaceUser, err := s.Store.FindWordspaceUser(ctx, &api.WorkspaceUserFind{
|
||||
WorkspaceID: &workspaceID,
|
||||
UserID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find workspace user").SetInternal(err)
|
||||
}
|
||||
if currentWorkspaceUser.Role != api.RoleAdmin {
|
||||
return echo.NewHTTPError(http.StatusForbidden, "Access forbidden to add workspace user").SetInternal(err)
|
||||
}
|
||||
|
||||
userID, err = strconv.Atoi(c.Param("userId"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted user id").SetInternal(err)
|
||||
}
|
||||
|
||||
workspaceUserDelete := &api.WorkspaceUserDelete{
|
||||
WorkspaceID: workspaceID,
|
||||
UserID: userID,
|
||||
}
|
||||
if err := s.Store.DeleteWorkspaceUser(ctx, workspaceUserDelete); err != nil {
|
||||
if common.ErrorCode(err) == common.NotFound {
|
||||
return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Workspace user not found with workspace id %d and user id %d", workspaceID, userID))
|
||||
}
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to delete workspace user").SetInternal(err)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, true)
|
||||
})
|
||||
}
|
@ -292,7 +292,7 @@ func findShortcutList(ctx context.Context, tx *sql.Tx, find *api.ShortcutFind) (
|
||||
where = append(where, fmt.Sprintf("visibility in (%s)", strings.Join(list, ",")))
|
||||
}
|
||||
if v := find.MemberID; v != nil {
|
||||
where, args = append(where, "workspace_id IN (SELECT workspace_id FROM workspace_user WHERE user_id = ? )"), append(args, *v)
|
||||
where, args = append(where, "workspace_id IN (SELECT workspace_id FROM workspace_user WHERE user_id = ?)"), append(args, *v)
|
||||
}
|
||||
|
||||
rows, err := tx.QueryContext(ctx, `
|
||||
|
@ -262,7 +262,7 @@ func findWorkspaceList(ctx context.Context, tx *sql.Tx, find *api.WorkspaceFind)
|
||||
where, args = append(where, "name = ?"), append(args, *v)
|
||||
}
|
||||
if v := find.MemberID; v != nil {
|
||||
where, args = append(where, "id IN (SELECT workspace_id FROM workspace_user WHERE user_id = ? )"), append(args, *v)
|
||||
where, args = append(where, "id IN (SELECT workspace_id FROM workspace_user WHERE user_id = ?)"), append(args, *v)
|
||||
}
|
||||
|
||||
query := `
|
||||
|
@ -29,6 +29,21 @@ func (raw *workspaceUserRaw) toWorkspaceUser() *api.WorkspaceUser {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) ComposeWorkspaceUser(ctx context.Context, workspaceUser *api.WorkspaceUser) error {
|
||||
user, err := s.FindUser(ctx, &api.UserFind{
|
||||
ID: &workspaceUser.UserID,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user.OpenID = ""
|
||||
user.UserSettingList = nil
|
||||
workspaceUser.User = user
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) UpsertWorkspaceUser(ctx context.Context, upsert *api.WorkspaceUserUpsert) (*api.WorkspaceUser, error) {
|
||||
tx, err := s.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
@ -112,14 +127,19 @@ func (s *Store) DeleteWorkspaceUser(ctx context.Context, delete *api.WorkspaceUs
|
||||
}
|
||||
|
||||
func upsertWorkspaceUser(ctx context.Context, tx *sql.Tx, upsert *api.WorkspaceUserUpsert) (*workspaceUserRaw, error) {
|
||||
set := []string{"workspace_id", "user_id", "role"}
|
||||
args := []interface{}{upsert.WorkspaceID, upsert.UserID, upsert.Role}
|
||||
placeholder := []string{"?", "?", "?"}
|
||||
|
||||
if v := upsert.UpdatedTs; v != nil {
|
||||
set, args, placeholder = append(set, "updated_ts"), append(args, *v), append(placeholder, "?")
|
||||
}
|
||||
|
||||
query := `
|
||||
INSERT INTO workspace_user (
|
||||
workspace_id,
|
||||
user_id,
|
||||
role,
|
||||
updated_ts
|
||||
` + strings.Join(set, ", ") + `
|
||||
)
|
||||
VALUES (?, ?, ?, ?)
|
||||
VALUES (` + strings.Join(placeholder, ",") + `)
|
||||
ON CONFLICT(workspace_id, user_id) DO UPDATE
|
||||
SET
|
||||
role = EXCLUDED.role,
|
||||
@ -127,12 +147,7 @@ func upsertWorkspaceUser(ctx context.Context, tx *sql.Tx, upsert *api.WorkspaceU
|
||||
RETURNING workspace_id, user_id, role, created_ts, updated_ts
|
||||
`
|
||||
var workspaceUserRaw workspaceUserRaw
|
||||
if err := tx.QueryRowContext(ctx, query,
|
||||
upsert.WorkspaceID,
|
||||
upsert.UserID,
|
||||
upsert.Role,
|
||||
upsert.UpdatedTs,
|
||||
).Scan(
|
||||
if err := tx.QueryRowContext(ctx, query, args...).Scan(
|
||||
&workspaceUserRaw.WorkspaceID,
|
||||
&workspaceUserRaw.UserID,
|
||||
&workspaceUserRaw.Role,
|
||||
|
Loading…
x
Reference in New Issue
Block a user