2018-09-24 17:17:54 +00:00
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
2018-10-25 21:42:26 +00:00
|
|
|
"fmt"
|
2018-09-24 17:17:54 +00:00
|
|
|
"net/http"
|
|
|
|
"path"
|
|
|
|
|
2019-11-25 14:22:19 +00:00
|
|
|
"github.com/influxdata/httprouter"
|
2020-04-03 17:39:20 +00:00
|
|
|
"github.com/influxdata/influxdb/v2"
|
2021-09-13 19:12:35 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/kit/platform"
|
|
|
|
"github.com/influxdata/influxdb/v2/kit/platform/errors"
|
2020-04-03 17:39:20 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/pkg/httpc"
|
2019-12-08 04:10:22 +00:00
|
|
|
"go.uber.org/zap"
|
2018-09-24 17:17:54 +00:00
|
|
|
)
|
|
|
|
|
2018-11-19 03:57:14 +00:00
|
|
|
type resourceUserResponse struct {
|
2019-09-13 17:12:07 +00:00
|
|
|
Role influxdb.UserType `json:"role"`
|
2021-12-20 20:17:18 +00:00
|
|
|
*influxdb.UserResponse
|
|
|
|
}
|
|
|
|
|
|
|
|
func newUserResponse(u *influxdb.User) *influxdb.UserResponse {
|
|
|
|
return &influxdb.UserResponse{
|
|
|
|
Links: map[string]string{
|
|
|
|
"self": fmt.Sprintf("/api/v2/users/%s", u.ID),
|
|
|
|
"logs": fmt.Sprintf("/api/v2/users/%s/logs", u.ID),
|
|
|
|
},
|
|
|
|
User: *u,
|
|
|
|
}
|
2018-11-19 03:57:14 +00:00
|
|
|
}
|
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
func newResourceUserResponse(u *influxdb.User, userType influxdb.UserType) *resourceUserResponse {
|
2018-11-19 03:57:14 +00:00
|
|
|
return &resourceUserResponse{
|
|
|
|
Role: userType,
|
2019-10-09 21:01:23 +00:00
|
|
|
UserResponse: newUserResponse(u),
|
2018-11-19 03:57:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-19 12:02:04 +00:00
|
|
|
type resourceUsersResponse struct {
|
|
|
|
Links map[string]string `json:"links"`
|
|
|
|
Users []*resourceUserResponse `json:"users"`
|
|
|
|
}
|
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
func newResourceUsersResponse(opts influxdb.FindOptions, f influxdb.UserResourceMappingFilter, users []*influxdb.User) *resourceUsersResponse {
|
2018-11-19 12:02:04 +00:00
|
|
|
rs := resourceUsersResponse{
|
|
|
|
Links: map[string]string{
|
2019-01-17 21:47:58 +00:00
|
|
|
"self": fmt.Sprintf("/api/v2/%s/%s/%ss", f.ResourceType, f.ResourceID, f.UserType),
|
2018-11-19 12:02:04 +00:00
|
|
|
},
|
|
|
|
Users: make([]*resourceUserResponse, 0, len(users)),
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, user := range users {
|
|
|
|
rs.Users = append(rs.Users, newResourceUserResponse(user, f.UserType))
|
|
|
|
}
|
|
|
|
return &rs
|
|
|
|
}
|
|
|
|
|
2019-01-17 03:35:54 +00:00
|
|
|
// MemberBackend is all services and associated parameters required to construct
|
|
|
|
// member handler.
|
|
|
|
type MemberBackend struct {
|
2021-03-30 18:10:02 +00:00
|
|
|
errors.HTTPErrorHandler
|
2019-12-04 23:10:23 +00:00
|
|
|
log *zap.Logger
|
2019-01-17 03:35:54 +00:00
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
ResourceType influxdb.ResourceType
|
|
|
|
UserType influxdb.UserType
|
2019-01-17 03:35:54 +00:00
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
UserResourceMappingService influxdb.UserResourceMappingService
|
|
|
|
UserService influxdb.UserService
|
2019-01-17 03:35:54 +00:00
|
|
|
}
|
|
|
|
|
2018-09-27 22:50:32 +00:00
|
|
|
// newPostMemberHandler returns a handler func for a POST to /members or /owners endpoints
|
2019-01-17 03:35:54 +00:00
|
|
|
func newPostMemberHandler(b MemberBackend) http.HandlerFunc {
|
2018-09-27 22:50:32 +00:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ctx := r.Context()
|
2018-10-16 21:23:56 +00:00
|
|
|
req, err := decodePostMemberRequest(ctx, r)
|
2018-09-27 22:50:32 +00:00
|
|
|
if err != nil {
|
2019-06-27 01:33:20 +00:00
|
|
|
b.HandleHTTPError(ctx, err, w)
|
2018-09-27 22:50:32 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-01-17 03:35:54 +00:00
|
|
|
user, err := b.UserService.FindUserByID(ctx, req.MemberID)
|
2018-11-19 03:57:14 +00:00
|
|
|
if err != nil {
|
2019-06-27 01:33:20 +00:00
|
|
|
b.HandleHTTPError(ctx, err, w)
|
2018-11-19 03:57:14 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
mapping := &influxdb.UserResourceMapping{
|
2019-01-15 16:09:58 +00:00
|
|
|
ResourceID: req.ResourceID,
|
2019-01-17 03:35:54 +00:00
|
|
|
ResourceType: b.ResourceType,
|
2019-01-15 16:09:58 +00:00
|
|
|
UserID: req.MemberID,
|
2019-01-17 03:35:54 +00:00
|
|
|
UserType: b.UserType,
|
2018-09-27 22:50:32 +00:00
|
|
|
}
|
|
|
|
|
2019-01-17 03:35:54 +00:00
|
|
|
if err := b.UserResourceMappingService.CreateUserResourceMapping(ctx, mapping); err != nil {
|
2019-06-27 01:33:20 +00:00
|
|
|
b.HandleHTTPError(ctx, err, w)
|
2018-09-27 22:50:32 +00:00
|
|
|
return
|
|
|
|
}
|
2019-12-04 23:10:23 +00:00
|
|
|
b.log.Debug("Member/owner created", zap.String("mapping", fmt.Sprint(mapping)))
|
2018-09-27 22:50:32 +00:00
|
|
|
|
2019-01-17 03:35:54 +00:00
|
|
|
if err := encodeResponse(ctx, w, http.StatusCreated, newResourceUserResponse(user, b.UserType)); err != nil {
|
2019-06-27 01:33:20 +00:00
|
|
|
b.HandleHTTPError(ctx, err, w)
|
2018-09-27 22:50:32 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-16 21:23:56 +00:00
|
|
|
type postMemberRequest struct {
|
2021-03-30 18:10:02 +00:00
|
|
|
MemberID platform.ID
|
|
|
|
ResourceID platform.ID
|
2018-09-27 22:50:32 +00:00
|
|
|
}
|
|
|
|
|
2018-10-16 21:23:56 +00:00
|
|
|
func decodePostMemberRequest(ctx context.Context, r *http.Request) (*postMemberRequest, error) {
|
2018-09-27 22:50:32 +00:00
|
|
|
params := httprouter.ParamsFromContext(ctx)
|
|
|
|
id := params.ByName("id")
|
|
|
|
if id == "" {
|
2021-03-30 18:10:02 +00:00
|
|
|
return nil, &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2019-01-24 00:15:42 +00:00
|
|
|
Msg: "url missing id",
|
|
|
|
}
|
2018-09-27 22:50:32 +00:00
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
var rid platform.ID
|
2018-10-16 21:23:56 +00:00
|
|
|
if err := rid.DecodeFromString(id); err != nil {
|
2018-09-27 22:50:32 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
u := &influxdb.User{}
|
2018-09-27 22:50:32 +00:00
|
|
|
if err := json.NewDecoder(r.Body).Decode(u); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-10-08 13:23:42 +00:00
|
|
|
if !u.ID.Valid() {
|
2021-03-30 18:10:02 +00:00
|
|
|
return nil, &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2019-01-24 00:15:42 +00:00
|
|
|
Msg: "user id missing or invalid",
|
|
|
|
}
|
2018-09-27 22:50:32 +00:00
|
|
|
}
|
|
|
|
|
2018-10-16 21:23:56 +00:00
|
|
|
return &postMemberRequest{
|
|
|
|
MemberID: u.ID,
|
|
|
|
ResourceID: rid,
|
2018-09-27 22:50:32 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2018-11-17 07:25:15 +00:00
|
|
|
// newGetMembersHandler returns a handler func for a GET to /members or /owners endpoints
|
2019-01-17 03:35:54 +00:00
|
|
|
func newGetMembersHandler(b MemberBackend) http.HandlerFunc {
|
2018-09-27 22:50:32 +00:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ctx := r.Context()
|
2018-10-16 21:23:56 +00:00
|
|
|
req, err := decodeGetMembersRequest(ctx, r)
|
2018-09-27 22:50:32 +00:00
|
|
|
if err != nil {
|
2019-06-27 01:33:20 +00:00
|
|
|
b.HandleHTTPError(ctx, err, w)
|
2018-09-27 22:50:32 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
filter := influxdb.UserResourceMappingFilter{
|
2019-01-15 16:09:58 +00:00
|
|
|
ResourceID: req.ResourceID,
|
2019-01-17 03:35:54 +00:00
|
|
|
ResourceType: b.ResourceType,
|
|
|
|
UserType: b.UserType,
|
2018-09-27 22:50:32 +00:00
|
|
|
}
|
2018-10-25 07:45:20 +00:00
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
opts := influxdb.FindOptions{}
|
2019-01-17 03:35:54 +00:00
|
|
|
mappings, _, err := b.UserResourceMappingService.FindUserResourceMappings(ctx, filter)
|
2018-09-27 22:50:32 +00:00
|
|
|
if err != nil {
|
2019-06-27 01:33:20 +00:00
|
|
|
b.HandleHTTPError(ctx, err, w)
|
2018-09-27 22:50:32 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
users := make([]*influxdb.User, 0, len(mappings))
|
2018-11-19 12:02:04 +00:00
|
|
|
for _, m := range mappings {
|
2019-09-13 17:12:07 +00:00
|
|
|
if m.MappingType == influxdb.OrgMappingType {
|
2019-03-04 17:41:24 +00:00
|
|
|
continue
|
|
|
|
}
|
2019-01-17 03:35:54 +00:00
|
|
|
user, err := b.UserService.FindUserByID(ctx, m.UserID)
|
2018-11-19 12:02:04 +00:00
|
|
|
if err != nil {
|
2019-06-27 01:33:20 +00:00
|
|
|
b.HandleHTTPError(ctx, err, w)
|
2018-11-19 12:02:04 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
users = append(users, user)
|
|
|
|
}
|
2019-12-04 23:10:23 +00:00
|
|
|
b.log.Debug("Members/owners retrieved", zap.String("users", fmt.Sprint(users)))
|
2018-11-19 12:02:04 +00:00
|
|
|
|
|
|
|
if err := encodeResponse(ctx, w, http.StatusOK, newResourceUsersResponse(opts, filter, users)); err != nil {
|
2019-06-27 01:33:20 +00:00
|
|
|
b.HandleHTTPError(ctx, err, w)
|
2018-09-27 22:50:32 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-16 21:23:56 +00:00
|
|
|
type getMembersRequest struct {
|
2021-03-30 18:10:02 +00:00
|
|
|
MemberID platform.ID
|
|
|
|
ResourceID platform.ID
|
2018-10-16 21:23:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func decodeGetMembersRequest(ctx context.Context, r *http.Request) (*getMembersRequest, error) {
|
|
|
|
params := httprouter.ParamsFromContext(ctx)
|
|
|
|
id := params.ByName("id")
|
|
|
|
if id == "" {
|
2021-03-30 18:10:02 +00:00
|
|
|
return nil, &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2019-01-24 00:15:42 +00:00
|
|
|
Msg: "url missing id",
|
|
|
|
}
|
2018-10-16 21:23:56 +00:00
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
var i platform.ID
|
2018-10-16 21:23:56 +00:00
|
|
|
if err := i.DecodeFromString(id); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
req := &getMembersRequest{
|
|
|
|
ResourceID: i,
|
|
|
|
}
|
|
|
|
|
|
|
|
return req, nil
|
|
|
|
}
|
|
|
|
|
2018-09-27 22:50:32 +00:00
|
|
|
// newDeleteMemberHandler returns a handler func for a DELETE to /members or /owners endpoints
|
2019-01-17 03:35:54 +00:00
|
|
|
func newDeleteMemberHandler(b MemberBackend) http.HandlerFunc {
|
2018-09-27 22:50:32 +00:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ctx := r.Context()
|
2018-10-16 21:23:56 +00:00
|
|
|
req, err := decodeDeleteMemberRequest(ctx, r)
|
2018-09-27 22:50:32 +00:00
|
|
|
if err != nil {
|
2019-06-27 01:33:20 +00:00
|
|
|
b.HandleHTTPError(ctx, err, w)
|
2018-09-27 22:50:32 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-01-17 03:35:54 +00:00
|
|
|
if err := b.UserResourceMappingService.DeleteUserResourceMapping(ctx, req.ResourceID, req.MemberID); err != nil {
|
2019-06-27 01:33:20 +00:00
|
|
|
b.HandleHTTPError(ctx, err, w)
|
2018-09-27 22:50:32 +00:00
|
|
|
return
|
|
|
|
}
|
2019-12-04 23:10:23 +00:00
|
|
|
b.log.Debug("Member deleted", zap.String("resourceID", req.ResourceID.String()), zap.String("memberID", req.MemberID.String()))
|
2018-09-27 22:50:32 +00:00
|
|
|
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-16 21:23:56 +00:00
|
|
|
type deleteMemberRequest struct {
|
2021-03-30 18:10:02 +00:00
|
|
|
MemberID platform.ID
|
|
|
|
ResourceID platform.ID
|
2018-09-27 22:50:32 +00:00
|
|
|
}
|
|
|
|
|
2018-10-16 21:23:56 +00:00
|
|
|
func decodeDeleteMemberRequest(ctx context.Context, r *http.Request) (*deleteMemberRequest, error) {
|
2018-09-27 22:50:32 +00:00
|
|
|
params := httprouter.ParamsFromContext(ctx)
|
|
|
|
id := params.ByName("id")
|
|
|
|
if id == "" {
|
2021-03-30 18:10:02 +00:00
|
|
|
return nil, &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2019-01-24 00:15:42 +00:00
|
|
|
Msg: "url missing resource id",
|
|
|
|
}
|
2018-09-27 22:50:32 +00:00
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
var rid platform.ID
|
2018-10-16 21:23:56 +00:00
|
|
|
if err := rid.DecodeFromString(id); err != nil {
|
2018-09-27 22:50:32 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-10-23 17:38:26 +00:00
|
|
|
id = params.ByName("userID")
|
2018-09-27 22:50:32 +00:00
|
|
|
if id == "" {
|
2021-03-30 18:10:02 +00:00
|
|
|
return nil, &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2019-01-24 00:15:42 +00:00
|
|
|
Msg: "url missing member id",
|
|
|
|
}
|
2018-09-27 22:50:32 +00:00
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
var mid platform.ID
|
2018-09-27 22:50:32 +00:00
|
|
|
if err := mid.DecodeFromString(id); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-10-16 21:23:56 +00:00
|
|
|
return &deleteMemberRequest{
|
|
|
|
MemberID: mid,
|
|
|
|
ResourceID: rid,
|
2018-09-27 22:50:32 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-12-07 18:54:03 +00:00
|
|
|
// UserResourceMappingService is the struct of urm service
|
|
|
|
type UserResourceMappingService struct {
|
2019-12-08 04:10:22 +00:00
|
|
|
Client *httpc.Client
|
2019-12-07 18:54:03 +00:00
|
|
|
}
|
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
// FindUserResourceMappings returns the user resource mappings
|
2019-12-08 04:10:22 +00:00
|
|
|
func (s *UserResourceMappingService) FindUserResourceMappings(ctx context.Context, f influxdb.UserResourceMappingFilter, opt ...influxdb.FindOptions) ([]*influxdb.UserResourceMapping, int, error) {
|
2019-12-07 18:54:03 +00:00
|
|
|
var results resourceUsersResponse
|
2019-12-08 04:10:22 +00:00
|
|
|
err := s.Client.
|
|
|
|
Get(resourceIDPath(f.ResourceType, f.ResourceID, string(f.UserType)+"s")).
|
2019-12-07 18:54:03 +00:00
|
|
|
DecodeJSON(&results).
|
|
|
|
Do(ctx)
|
2018-09-24 17:17:54 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, 0, err
|
|
|
|
}
|
2019-10-09 21:01:23 +00:00
|
|
|
|
|
|
|
urs := make([]*influxdb.UserResourceMapping, len(results.Users))
|
|
|
|
for k, item := range results.Users {
|
|
|
|
urs[k] = &influxdb.UserResourceMapping{
|
2019-12-08 04:10:22 +00:00
|
|
|
ResourceID: f.ResourceID,
|
|
|
|
ResourceType: f.ResourceType,
|
2019-10-09 21:01:23 +00:00
|
|
|
UserID: item.User.ID,
|
|
|
|
UserType: item.Role,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return urs, len(urs), nil
|
2018-09-24 17:17:54 +00:00
|
|
|
}
|
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
// CreateUserResourceMapping will create a user resource mapping
|
|
|
|
func (s *UserResourceMappingService) CreateUserResourceMapping(ctx context.Context, m *influxdb.UserResourceMapping) error {
|
2018-12-03 16:07:08 +00:00
|
|
|
if err := m.Validate(); err != nil {
|
|
|
|
return err
|
2018-09-24 17:17:54 +00:00
|
|
|
}
|
|
|
|
|
2019-12-07 18:54:03 +00:00
|
|
|
urlPath := resourceIDPath(m.ResourceType, m.ResourceID, string(m.UserType)+"s")
|
2019-12-08 04:10:22 +00:00
|
|
|
return s.Client.
|
2019-12-12 03:26:02 +00:00
|
|
|
PostJSON(influxdb.User{ID: m.UserID}, urlPath).
|
2019-12-07 18:54:03 +00:00
|
|
|
DecodeJSON(m).
|
|
|
|
Do(ctx)
|
2018-09-24 17:17:54 +00:00
|
|
|
}
|
|
|
|
|
2019-09-13 17:12:07 +00:00
|
|
|
// DeleteUserResourceMapping will delete user resource mapping based in criteria.
|
2021-03-30 18:10:02 +00:00
|
|
|
func (s *UserResourceMappingService) DeleteUserResourceMapping(ctx context.Context, resourceID platform.ID, userID platform.ID) error {
|
2019-12-07 18:54:03 +00:00
|
|
|
urlPath := resourceIDUserPath(influxdb.OrgsResourceType, resourceID, influxdb.Member, userID)
|
2019-12-08 04:10:22 +00:00
|
|
|
return s.Client.
|
|
|
|
Delete(urlPath).
|
|
|
|
Do(ctx)
|
2018-09-24 17:17:54 +00:00
|
|
|
}
|
|
|
|
|
2020-06-25 18:13:05 +00:00
|
|
|
// SpecificURMSvc returns a urm service with specific resource and user types.
|
|
|
|
// this will help us stay compatible with the existing service contract but also allow for urm deletes to go through the correct
|
|
|
|
// api
|
|
|
|
func (s *UserResourceMappingService) SpecificURMSvc(rt influxdb.ResourceType, ut influxdb.UserType) *SpecificURMSvc {
|
|
|
|
return &SpecificURMSvc{
|
|
|
|
Client: s.Client,
|
|
|
|
rt: rt,
|
|
|
|
ut: ut,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SpecificURMSvc is a URM client that speaks to a specific resource with a specified user type
|
|
|
|
type SpecificURMSvc struct {
|
|
|
|
Client *httpc.Client
|
|
|
|
rt influxdb.ResourceType
|
|
|
|
ut influxdb.UserType
|
|
|
|
}
|
|
|
|
|
|
|
|
// FindUserResourceMappings returns the user resource mappings
|
|
|
|
func (s *SpecificURMSvc) FindUserResourceMappings(ctx context.Context, f influxdb.UserResourceMappingFilter, opt ...influxdb.FindOptions) ([]*influxdb.UserResourceMapping, int, error) {
|
|
|
|
var results resourceUsersResponse
|
|
|
|
err := s.Client.
|
|
|
|
Get(resourceIDPath(s.rt, f.ResourceID, string(s.ut)+"s")).
|
|
|
|
DecodeJSON(&results).
|
|
|
|
Do(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
urs := make([]*influxdb.UserResourceMapping, len(results.Users))
|
|
|
|
for k, item := range results.Users {
|
|
|
|
urs[k] = &influxdb.UserResourceMapping{
|
|
|
|
ResourceID: f.ResourceID,
|
|
|
|
ResourceType: f.ResourceType,
|
|
|
|
UserID: item.User.ID,
|
|
|
|
UserType: item.Role,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return urs, len(urs), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateUserResourceMapping will create a user resource mapping
|
|
|
|
func (s *SpecificURMSvc) CreateUserResourceMapping(ctx context.Context, m *influxdb.UserResourceMapping) error {
|
|
|
|
if err := m.Validate(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
urlPath := resourceIDPath(s.rt, m.ResourceID, string(s.ut)+"s")
|
|
|
|
return s.Client.
|
|
|
|
PostJSON(influxdb.User{ID: m.UserID}, urlPath).
|
|
|
|
DecodeJSON(m).
|
|
|
|
Do(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteUserResourceMapping will delete user resource mapping based in criteria.
|
2021-03-30 18:10:02 +00:00
|
|
|
func (s *SpecificURMSvc) DeleteUserResourceMapping(ctx context.Context, resourceID platform.ID, userID platform.ID) error {
|
2020-06-25 18:13:05 +00:00
|
|
|
urlPath := resourceIDUserPath(s.rt, resourceID, s.ut, userID)
|
|
|
|
return s.Client.
|
|
|
|
Delete(urlPath).
|
|
|
|
Do(ctx)
|
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
func resourceIDPath(resourceType influxdb.ResourceType, resourceID platform.ID, p string) string {
|
2019-09-13 17:12:07 +00:00
|
|
|
return path.Join("/api/v2/", string(resourceType), resourceID.String(), p)
|
2018-09-24 17:17:54 +00:00
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
func resourceIDUserPath(resourceType influxdb.ResourceType, resourceID platform.ID, userType influxdb.UserType, userID platform.ID) string {
|
2019-09-13 17:12:07 +00:00
|
|
|
return path.Join("/api/v2/", string(resourceType), resourceID.String(), string(userType)+"s", userID.String())
|
2018-09-24 17:17:54 +00:00
|
|
|
}
|