Skip to content

Commit

Permalink
refactor(api,cdsctl): remove group and project permission import (#6068)
Browse files Browse the repository at this point in the history
  • Loading branch information
richardlt authored Jan 24, 2022
1 parent 73a1333 commit ab62f66
Show file tree
Hide file tree
Showing 16 changed files with 174 additions and 752 deletions.
52 changes: 0 additions & 52 deletions cli/cdsctl/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (

"github.com/ovh/cds/cli"
"github.com/ovh/cds/sdk"
"github.com/ovh/cds/sdk/cdsclient"
"github.com/ovh/cds/sdk/exportentities"
)

var groupCmd = cli.Command{
Expand All @@ -27,8 +25,6 @@ func group() *cobra.Command {
cli.NewDeleteCommand(groupDeleteCmd, groupDeleteRun, nil, withAllCommandModifiers()...),
cli.NewCommand(groupGrantCmd, groupGrantRun, nil, withAllCommandModifiers()...),
cli.NewCommand(groupRevokeCmd, groupRevokeRun, nil, withAllCommandModifiers()...),
cli.NewCommand(groupExportCmd, groupExportRun, nil, withAllCommandModifiers()...),
cli.NewCommand(groupImportCmd, groupImportRun, nil, withAllCommandModifiers()...),
groupMember(),
})
}
Expand Down Expand Up @@ -206,51 +202,3 @@ func groupRevokeRun(v cli.Values) error {

return nil
}

var groupExportCmd = cli.Command{
Name: "export",
Short: "Export a CDS group",
Args: []cli.Arg{
{
Name: "group-name",
},
},
Flags: []cli.Flag{
{
Name: "format",
Usage: "Specify export format (json or yaml)",
Default: "yaml",
},
},
}

func groupExportRun(v cli.Values) error {
buf, err := client.GroupExport(v.GetString("group-name"), cdsclient.Format(v.GetString("format")))
if err != nil {
return err
}
fmt.Println(string(buf))
return nil
}

var groupImportCmd = cli.Command{
Name: "import",
Short: "Import a group",
Args: []cli.Arg{
{Name: "path"},
},
}

func groupImportRun(c cli.Values) error {
path := c.GetString("path")
contentFile, format, err := exportentities.OpenPath(path)
if err != nil {
return err
}
defer contentFile.Close() //nolint
if _, err := client.GroupImport(contentFile, cdsclient.ContentType(format.ContentType())); err != nil {
return err
}
fmt.Println("Group imported.")
return nil
}
1 change: 0 additions & 1 deletion cli/cdsctl/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ func projectCommands() []*cobra.Command {
cli.NewDeleteCommand(projectDeleteCmd, projectDeleteRun, nil, withAllCommandModifiers()...),
cli.NewCommand(projectFavoriteCmd, projectFavoriteRun, nil, withAllCommandModifiers()...),
projectKey(),
projectGroup(),
projectVariable(),
projectIntegration(),
projectRepositoryManager(),
Expand Down
85 changes: 0 additions & 85 deletions cli/cdsctl/project_group.go

This file was deleted.

3 changes: 0 additions & 3 deletions engine/api/api_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,7 @@ func (api *API) InitRouter() {

// Group
r.Handle("/group", Scope(sdk.AuthConsumerScopeGroup), r.GET(api.getGroupsHandler), r.POST(api.postGroupHandler))
r.Handle("/group/import", Scope(sdk.AuthConsumerScopeGroup), r.POST(api.postGroupImportHandler))
r.Handle("/group/{permGroupName}", Scope(sdk.AuthConsumerScopeGroup), r.GET(api.getGroupHandler), r.PUT(api.putGroupHandler), r.DELETE(api.deleteGroupHandler))
r.Handle("/group/{permGroupName}/export", Scope(sdk.AuthConsumerScopeGroup), r.GET(api.getGroupExportHandler))
r.Handle("/group/{permGroupName}/user", Scope(sdk.AuthConsumerScopeGroup), r.POST(api.postGroupUserHandler))
r.Handle("/group/{permGroupName}/user/{username}", Scope(sdk.AuthConsumerScopeGroup), r.PUT(api.putGroupUserHandler), r.DELETE(api.deleteGroupUserHandler))
r.Handle("/group/{permGroupName}/project", Scope(sdk.AuthConsumerScopeGroup), r.GET(api.getProjectGroupHandler))
Expand Down Expand Up @@ -162,7 +160,6 @@ func (api *API) InitRouter() {
r.Handle("/project/{permProjectKey}", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getProjectHandler), r.PUT(api.updateProjectHandler), r.DELETE(api.deleteProjectHandler))
r.Handle("/project/{permProjectKey}/labels", Scope(sdk.AuthConsumerScopeProject), r.PUT(api.putProjectLabelsHandler))
r.Handle("/project/{permProjectKey}/group", Scope(sdk.AuthConsumerScopeProject), r.POST(api.postGroupInProjectHandler))
r.Handle("/project/{permProjectKey}/group/import", Scope(sdk.AuthConsumerScopeProject), r.POST(api.postImportGroupsInProjectHandler))
r.Handle("/project/{permProjectKey}/group/{groupName}", Scope(sdk.AuthConsumerScopeProject), r.PUT(api.putGroupRoleOnProjectHandler), r.DELETE(api.deleteGroupFromProjectHandler))
r.Handle("/project/{permProjectKey}/variable", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getVariablesInProjectHandler))
r.Handle("/project/{permProjectKey}/encrypt", Scope(sdk.AuthConsumerScopeProject), r.POST(api.postEncryptVariableHandler), r.DELETE(api.deleteEncryptVariableHandler))
Expand Down
165 changes: 0 additions & 165 deletions engine/api/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package api

import (
"context"
"io/ioutil"
"net/http"

"github.com/gorilla/mux"
Expand All @@ -14,7 +13,6 @@ import (
"github.com/ovh/cds/engine/api/user"
"github.com/ovh/cds/engine/service"
"github.com/ovh/cds/sdk"
"github.com/ovh/cds/sdk/exportentities"
)

func (api *API) getGroupsHandler() service.Handler {
Expand Down Expand Up @@ -78,40 +76,6 @@ func (api *API) getGroupHandler() service.Handler {
}
}

func (api *API) getGroupExportHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)

groupName := vars["permGroupName"]

format := FormString(r, "format")
if format == "" {
format = "yaml"
}
f, err := exportentities.GetFormat(format)
if err != nil {
return err
}

g, err := group.LoadByName(ctx, api.mustDB(), groupName, group.LoadOptions.Default)
if err != nil {
return err
}

b, err := exportentities.Marshal(g, f)
if err != nil {
return err
}

if _, err := w.Write(b); err != nil {
return sdk.WithStack(err)
}

w.Header().Add("Content-Type", f.ContentType())
return nil
}
}

func (api *API) postGroupHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
var newGroup sdk.Group
Expand Down Expand Up @@ -493,132 +457,3 @@ func (api *API) deleteGroupUserHandler() service.Handler {
return service.WriteJSON(w, g, http.StatusOK)
}
}

func (api *API) postGroupImportHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return sdk.NewErrorWithStack(err, sdk.NewErrorFrom(sdk.ErrWrongRequest, "unable to read body"))
}

contentType := r.Header.Get("Content-Type")
if contentType == "" {
contentType = http.DetectContentType(body)
}
format, err := exportentities.GetFormatFromContentType(contentType)
if err != nil {
return err
}

var data sdk.Group
if err := exportentities.Unmarshal(body, format, &data); err != nil {
return err
}
if err := data.IsValid(); err != nil {
return err
}
if err := data.Members.IsValid(); err != nil {
return err
}

tx, err := api.mustDB().Begin()
if err != nil {
return sdk.WrapError(err, "cannot start transaction")
}
defer tx.Rollback() // nolint

oldGroup, err := group.LoadByName(ctx, tx, data.Name,
group.LoadOptions.WithMembers,
group.LoadOptions.WithOrganization,
)
if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) {
return sdk.WrapError(err, "cannot load group: %s", data.Name)
}
if oldGroup != nil {
if !isGroupAdmin(ctx, oldGroup) {
if isAdmin(ctx) {
trackSudo(ctx, w)
} else {
return sdk.WithStack(sdk.ErrForbidden)
}
}
}

// Add user data and validate members
for i := range data.Members {
var u *sdk.AuthentifiedUser
if data.Members[i].ID != "" {
u, err = user.LoadByID(ctx, tx, data.Members[i].ID)
} else {
u, err = user.LoadByUsername(ctx, tx, data.Members[i].Username)
}
if err != nil {
return err
}
data.Members[i].ID = u.ID
}

if err := group.Upsert(ctx, tx, oldGroup, &data); err != nil {
return sdk.WrapError(err, "cannot update group with id: %d", data.ID)
}

// Check that user's Organization match group Organization
if err := group.EnsureOrganization(ctx, tx, &data); err != nil {
return err
}

if oldGroup != nil {
// Remove the group from consumers for removed users
removedUserIDs := oldGroup.Members.DiffUserIDs(data.Members)
for i := range removedUserIDs {
u, err := user.LoadByID(ctx, tx, removedUserIDs[i])
if err != nil {
return err
}
if err := authentication.ConsumerInvalidateGroupForUser(ctx, tx, &data, u); err != nil {
return err
}
}

// Restore group on consumers for added users
addedUserIDs := data.Members.DiffUserIDs(oldGroup.Members)
for i := range addedUserIDs {
if err := authentication.ConsumerRestoreInvalidatedGroupForUser(ctx, tx, data.ID, addedUserIDs[i]); err != nil {
return err
}
}
}

if err := tx.Commit(); err != nil {
return sdk.WithStack(err)
}

// In case where the user remove himself from group, do not return it
consumer := getAPIConsumer(ctx)
for i := range data.Members {
var found bool
if data.Members[i].ID == consumer.AuthentifiedUser.ID {
found = true
break
}
if !found {
return service.WriteJSON(w, nil, http.StatusOK)
}
}

// Load extra data for group
if err := group.LoadOptions.Default(ctx, api.mustDB(), &data); err != nil {
return err
}

b, err := exportentities.Marshal(data, format)
if err != nil {
return err
}
if _, err := w.Write(b); err != nil {
return sdk.WithStack(err)
}
w.Header().Add("Content-Type", format.ContentType())
return nil
}
}
Loading

0 comments on commit ab62f66

Please sign in to comment.