Backend: Fix organization API endpoints and RBAC
- Fix member list API response format to match frontend expectations - Fix join requests API response format - Add proper JSON tags to Invitation struct - Grant OrgManage permission to admin role for proper RBAC These changes ensure frontend-backend API contracts are aligned and admins can manage organizations.
This commit is contained in:
BIN
go_cloud/api
BIN
go_cloud/api
Binary file not shown.
@@ -117,14 +117,14 @@ type Membership struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Invitation struct {
|
type Invitation struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID `json:"id"`
|
||||||
OrgID uuid.UUID
|
OrgID uuid.UUID `json:"orgId"`
|
||||||
InvitedBy uuid.UUID
|
InvitedBy uuid.UUID `json:"invitedBy"`
|
||||||
Username string
|
Username string `json:"username"`
|
||||||
Role string
|
Role string `json:"role"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
ExpiresAt time.Time
|
ExpiresAt time.Time `json:"expiresAt"`
|
||||||
AcceptedAt *time.Time
|
AcceptedAt *time.Time `json:"acceptedAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type JoinRequest struct {
|
type JoinRequest struct {
|
||||||
|
|||||||
@@ -888,6 +888,21 @@ func activityHandler(w http.ResponseWriter, r *http.Request, db *database.DB) {
|
|||||||
json.NewEncoder(w).Encode(activities)
|
json.NewEncoder(w).Encode(activities)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type memberResponse struct {
|
||||||
|
UserID string `json:"userId"`
|
||||||
|
OrgID string `json:"orgId"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
User userInfo `json:"user"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type userInfo struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
}
|
||||||
|
|
||||||
func listMembersHandler(w http.ResponseWriter, r *http.Request, db *database.DB) {
|
func listMembersHandler(w http.ResponseWriter, r *http.Request, db *database.DB) {
|
||||||
orgID := r.Context().Value(middleware.OrgKey).(uuid.UUID)
|
orgID := r.Context().Value(middleware.OrgKey).(uuid.UUID)
|
||||||
|
|
||||||
@@ -898,8 +913,25 @@ func listMembersHandler(w http.ResponseWriter, r *http.Request, db *database.DB)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert to proper response format
|
||||||
|
var response []memberResponse
|
||||||
|
for _, m := range members {
|
||||||
|
response = append(response, memberResponse{
|
||||||
|
UserID: m.Membership.UserID.String(),
|
||||||
|
OrgID: m.Membership.OrgID.String(),
|
||||||
|
Role: m.Membership.Role,
|
||||||
|
CreatedAt: m.Membership.CreatedAt,
|
||||||
|
User: userInfo{
|
||||||
|
ID: m.User.ID.String(),
|
||||||
|
Username: m.User.Username,
|
||||||
|
DisplayName: m.User.DisplayName,
|
||||||
|
Email: m.User.Email,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(members)
|
json.NewEncoder(w).Encode(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateMemberRoleHandler(w http.ResponseWriter, r *http.Request, db *database.DB, auditLogger *audit.Logger) {
|
func updateMemberRoleHandler(w http.ResponseWriter, r *http.Request, db *database.DB, auditLogger *audit.Logger) {
|
||||||
@@ -1126,6 +1158,16 @@ func createJoinRequestHandler(w http.ResponseWriter, r *http.Request, db *databa
|
|||||||
json.NewEncoder(w).Encode(joinRequest)
|
json.NewEncoder(w).Encode(joinRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type joinRequestResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
OrgID string `json:"orgId"`
|
||||||
|
UserID string `json:"userId"`
|
||||||
|
InviteToken *string `json:"inviteToken"`
|
||||||
|
RequestedAt time.Time `json:"requestedAt"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
User userInfo `json:"user"`
|
||||||
|
}
|
||||||
|
|
||||||
func listJoinRequestsHandler(w http.ResponseWriter, r *http.Request, db *database.DB) {
|
func listJoinRequestsHandler(w http.ResponseWriter, r *http.Request, db *database.DB) {
|
||||||
orgID := r.Context().Value(middleware.OrgKey).(uuid.UUID)
|
orgID := r.Context().Value(middleware.OrgKey).(uuid.UUID)
|
||||||
|
|
||||||
@@ -1136,8 +1178,27 @@ func listJoinRequestsHandler(w http.ResponseWriter, r *http.Request, db *databas
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert to proper response format
|
||||||
|
var response []joinRequestResponse
|
||||||
|
for _, req := range requests {
|
||||||
|
response = append(response, joinRequestResponse{
|
||||||
|
ID: req.JoinRequest.ID.String(),
|
||||||
|
OrgID: req.JoinRequest.OrgID.String(),
|
||||||
|
UserID: req.JoinRequest.UserID.String(),
|
||||||
|
InviteToken: req.JoinRequest.InviteToken,
|
||||||
|
RequestedAt: req.JoinRequest.RequestedAt,
|
||||||
|
Status: req.JoinRequest.Status,
|
||||||
|
User: userInfo{
|
||||||
|
ID: req.User.ID.String(),
|
||||||
|
Username: req.User.Username,
|
||||||
|
DisplayName: req.User.DisplayName,
|
||||||
|
Email: req.User.Email,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(requests)
|
json.NewEncoder(w).Encode(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func acceptJoinRequestHandler(w http.ResponseWriter, r *http.Request, db *database.DB, auditLogger *audit.Logger) {
|
func acceptJoinRequestHandler(w http.ResponseWriter, r *http.Request, db *database.DB, auditLogger *audit.Logger) {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const (
|
|||||||
|
|
||||||
var rolePermissions = map[string][]Permission{
|
var rolePermissions = map[string][]Permission{
|
||||||
"owner": {FileRead, FileWrite, FileDelete, DocumentView, DocumentEdit, OrgManage},
|
"owner": {FileRead, FileWrite, FileDelete, DocumentView, DocumentEdit, OrgManage},
|
||||||
"admin": {FileRead, FileWrite, FileDelete, DocumentView, DocumentEdit},
|
"admin": {FileRead, FileWrite, FileDelete, DocumentView, DocumentEdit, OrgManage},
|
||||||
"member": {FileRead, DocumentView},
|
"member": {FileRead, DocumentView},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user