*: implement delete organization member

This commit is contained in:
Simone Gotti 2019-05-09 17:05:13 +02:00
parent d0309db97f
commit b0fe7e4115
7 changed files with 144 additions and 0 deletions

View File

@ -262,3 +262,62 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
_, err = h.dm.WriteWal(ctx, actions, cgt) _, err = h.dm.WriteWal(ctx, actions, cgt)
return orgmember, err return orgmember, err
} }
// DeleteOrgMember deletes an org member.
func (h *ActionHandler) DeleteOrgMember(ctx context.Context, orgRef, userRef string) error {
var org *types.Organization
var user *types.User
var orgmember *types.OrganizationMember
var cgt *datamanager.ChangeGroupsUpdateToken
// must do all the checks in a single transaction to avoid concurrent changes
err := h.readDB.Do(func(tx *db.Tx) error {
var err error
// check existing org
org, err = h.readDB.GetOrg(tx, orgRef)
if err != nil {
return err
}
if org == nil {
return util.NewErrBadRequest(errors.Errorf("org %q doesn't exists", orgRef))
}
// check existing user
user, err = h.readDB.GetUser(tx, userRef)
if err != nil {
return err
}
if user == nil {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't exists", userRef))
}
// check that org member exists
orgmember, err = h.readDB.GetOrgMemberByOrgUserID(tx, org.ID, user.ID)
if err != nil {
return err
}
if orgmember == nil {
return util.NewErrBadRequest(errors.Errorf("orgmember for org %q, user %q doesn't exists", orgRef, userRef))
}
cgNames := []string{util.EncodeSha256Hex(fmt.Sprintf("orgmember-%s-%s", org.ID, user.ID))}
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
actions := []*datamanager.Action{}
actions = append(actions, &datamanager.Action{
ActionType: datamanager.ActionTypeDelete,
DataType: string(types.ConfigTypeOrgMember),
ID: orgmember.ID,
})
_, err = h.dm.WriteWal(ctx, actions, cgt)
return err
}

View File

@ -474,6 +474,10 @@ func (c *Client) AddOrgMember(ctx context.Context, orgRef, userRef string, role
return orgmember, resp, err return orgmember, resp, err
} }
func (c *Client) DeleteOrgMember(ctx context.Context, orgRef, userRef string) (*http.Response, error) {
return c.getResponse(ctx, "DELETE", fmt.Sprintf("/orgs/%s/members/%s", orgRef, userRef), nil, jsonContent, nil)
}
func (c *Client) GetOrgs(ctx context.Context, start string, limit int, asc bool) ([]*types.Organization, *http.Response, error) { func (c *Client) GetOrgs(ctx context.Context, start string, limit int, asc bool) ([]*types.Organization, *http.Response, error) {
q := url.Values{} q := url.Values{}
if start != "" { if start != "" {

View File

@ -114,6 +114,7 @@ func (h *DeleteOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := h.ah.DeleteOrg(ctx, orgRef) err := h.ah.DeleteOrg(ctx, orgRef)
if httpError(w, err) { if httpError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := httpResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
@ -215,3 +216,30 @@ func (h *AddOrgMemberHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
type DeleteOrgMemberHandler struct {
log *zap.SugaredLogger
ah *action.ActionHandler
}
func NewDeleteOrgMemberHandler(logger *zap.Logger, ah *action.ActionHandler) *DeleteOrgMemberHandler {
return &DeleteOrgMemberHandler{log: logger.Sugar(), ah: ah}
}
func (h *DeleteOrgMemberHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
orgRef := vars["orgref"]
userRef := vars["userref"]
err := h.ah.DeleteOrgMember(ctx, orgRef, userRef)
if httpError(w, err) {
h.log.Errorf("err: %+v", err)
return
}
if err := httpResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err)
}
}

View File

@ -164,6 +164,7 @@ func (s *Configstore) Run(ctx context.Context) error {
deleteOrgHandler := api.NewDeleteOrgHandler(logger, s.ah) deleteOrgHandler := api.NewDeleteOrgHandler(logger, s.ah)
addOrgMemberHandler := api.NewAddOrgMemberHandler(logger, s.ah) addOrgMemberHandler := api.NewAddOrgMemberHandler(logger, s.ah)
deleteOrgMemberHandler := api.NewDeleteOrgMemberHandler(logger, s.ah)
remoteSourceHandler := api.NewRemoteSourceHandler(logger, s.readDB) remoteSourceHandler := api.NewRemoteSourceHandler(logger, s.readDB)
remoteSourcesHandler := api.NewRemoteSourcesHandler(logger, s.readDB) remoteSourcesHandler := api.NewRemoteSourcesHandler(logger, s.readDB)
@ -216,6 +217,7 @@ func (s *Configstore) Run(ctx context.Context) error {
apirouter.Handle("/orgs", createOrgHandler).Methods("POST") apirouter.Handle("/orgs", createOrgHandler).Methods("POST")
apirouter.Handle("/orgs/{orgref}", deleteOrgHandler).Methods("DELETE") apirouter.Handle("/orgs/{orgref}", deleteOrgHandler).Methods("DELETE")
apirouter.Handle("/orgs/{orgref}/members/{userref}", addOrgMemberHandler).Methods("PUT") apirouter.Handle("/orgs/{orgref}/members/{userref}", addOrgMemberHandler).Methods("PUT")
apirouter.Handle("/orgs/{orgref}/members/{userref}", deleteOrgMemberHandler).Methods("DELETE")
apirouter.Handle("/remotesources/{remotesourceref}", remoteSourceHandler).Methods("GET") apirouter.Handle("/remotesources/{remotesourceref}", remoteSourceHandler).Methods("GET")
apirouter.Handle("/remotesources", remoteSourcesHandler).Methods("GET") apirouter.Handle("/remotesources", remoteSourcesHandler).Methods("GET")

View File

@ -136,3 +136,25 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
User: user, User: user,
}, nil }, nil
} }
func (h *ActionHandler) DeleteOrgMember(ctx context.Context, orgRef, userRef string) error {
org, resp, err := h.configstoreClient.GetOrg(ctx, orgRef)
if err != nil {
return ErrFromRemote(resp, err)
}
isOrgOwner, err := h.IsOrgOwner(ctx, org.ID)
if err != nil {
return errors.Wrapf(err, "failed to determine ownership")
}
if !isOrgOwner {
return util.NewErrForbidden(errors.Errorf("user not authorized"))
}
resp, err = h.configstoreClient.DeleteOrgMember(ctx, orgRef, userRef)
if err != nil {
return ErrFromRemote(resp, errors.Wrapf(err, "failed to add/update organization member"))
}
return nil
}

View File

@ -248,3 +248,30 @@ func (h *AddOrgMemberHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
type DeleteOrgMemberHandler struct {
log *zap.SugaredLogger
ah *action.ActionHandler
}
func NewDeleteOrgMemberHandler(logger *zap.Logger, ah *action.ActionHandler) *DeleteOrgMemberHandler {
return &DeleteOrgMemberHandler{log: logger.Sugar(), ah: ah}
}
func (h *DeleteOrgMemberHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
orgRef := vars["orgref"]
userRef := vars["userref"]
err := h.ah.DeleteOrgMember(ctx, orgRef, userRef)
if httpError(w, err) {
h.log.Errorf("err: %+v", err)
return
}
if err := httpResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err)
}
}

View File

@ -189,6 +189,7 @@ func (g *Gateway) Run(ctx context.Context) error {
deleteOrgHandler := api.NewDeleteOrgHandler(logger, g.ah) deleteOrgHandler := api.NewDeleteOrgHandler(logger, g.ah)
addOrgMemberHandler := api.NewAddOrgMemberHandler(logger, g.ah) addOrgMemberHandler := api.NewAddOrgMemberHandler(logger, g.ah)
deleteOrgMemberHandler := api.NewDeleteOrgMemberHandler(logger, g.ah)
runHandler := api.NewRunHandler(logger, g.ah) runHandler := api.NewRunHandler(logger, g.ah)
runsHandler := api.NewRunsHandler(logger, g.ah) runsHandler := api.NewRunsHandler(logger, g.ah)
@ -264,6 +265,7 @@ func (g *Gateway) Run(ctx context.Context) error {
apirouter.Handle("/orgs", authForcedHandler(createOrgHandler)).Methods("POST") apirouter.Handle("/orgs", authForcedHandler(createOrgHandler)).Methods("POST")
apirouter.Handle("/orgs/{orgref}", authForcedHandler(deleteOrgHandler)).Methods("DELETE") apirouter.Handle("/orgs/{orgref}", authForcedHandler(deleteOrgHandler)).Methods("DELETE")
apirouter.Handle("/orgs/{orgref}/members/{userref}", authForcedHandler(addOrgMemberHandler)).Methods("PUT") apirouter.Handle("/orgs/{orgref}/members/{userref}", authForcedHandler(addOrgMemberHandler)).Methods("PUT")
apirouter.Handle("/orgs/{orgref}/members/{userref}", authForcedHandler(deleteOrgMemberHandler)).Methods("DELETE")
apirouter.Handle("/runs/{runid}", authForcedHandler(runHandler)).Methods("GET") apirouter.Handle("/runs/{runid}", authForcedHandler(runHandler)).Methods("GET")
apirouter.Handle("/runs/{runid}/actions", authForcedHandler(runActionsHandler)).Methods("PUT") apirouter.Handle("/runs/{runid}/actions", authForcedHandler(runActionsHandler)).Methods("PUT")