*: add organizations visibility

This commit is contained in:
Simone Gotti 2019-05-14 10:56:17 +02:00
parent c41de71694
commit c5cdf01332
8 changed files with 51 additions and 15 deletions

View File

@ -19,6 +19,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sorintlab/agola/internal/services/gateway/api" "github.com/sorintlab/agola/internal/services/gateway/api"
"github.com/sorintlab/agola/internal/services/types"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -34,7 +35,8 @@ var cmdOrgCreate = &cobra.Command{
} }
type orgCreateOptions struct { type orgCreateOptions struct {
name string name string
visibility string
} }
var orgCreateOpts orgCreateOptions var orgCreateOpts orgCreateOptions
@ -43,6 +45,7 @@ func init() {
flags := cmdOrgCreate.Flags() flags := cmdOrgCreate.Flags()
flags.StringVarP(&orgCreateOpts.name, "name", "n", "", "organization name") flags.StringVarP(&orgCreateOpts.name, "name", "n", "", "organization name")
flags.StringVar(&orgCreateOpts.visibility, "visibility", "public", `organization visibility (public or private)`)
cmdOrgCreate.MarkFlagRequired("name") cmdOrgCreate.MarkFlagRequired("name")
@ -52,8 +55,14 @@ func init() {
func orgCreate(cmd *cobra.Command, args []string) error { func orgCreate(cmd *cobra.Command, args []string) error {
gwclient := api.NewClient(gatewayURL, token) gwclient := api.NewClient(gatewayURL, token)
// TODO(sgotti) make this a custom pflag Value?
if !types.IsValidVisibility(types.Visibility(orgCreateOpts.visibility)) {
return errors.Errorf("invalid visibility %q", orgCreateOpts.visibility)
}
req := &api.CreateOrgRequest{ req := &api.CreateOrgRequest{
Name: orgCreateOpts.name, Name: orgCreateOpts.name,
Visibility: types.Visibility(orgCreateOpts.visibility),
} }
log.Infof("creating org") log.Infof("creating org")

View File

@ -36,6 +36,9 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
if !util.ValidateName(org.Name) { if !util.ValidateName(org.Name) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid organization name %q", org.Name)) return nil, util.NewErrBadRequest(errors.Errorf("invalid organization name %q", org.Name))
} }
if !types.IsValidVisibility(org.Visibility) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid organization visibility"))
}
var cgt *datamanager.ChangeGroupsUpdateToken var cgt *datamanager.ChangeGroupsUpdateToken
// changegroup is the org name // changegroup is the org name
@ -109,8 +112,11 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
}) })
} }
// create root org project group
pg := &types.ProjectGroup{ pg := &types.ProjectGroup{
ID: uuid.NewV4().String(), ID: uuid.NewV4().String(),
// use same org visibility
Visibility: org.Visibility,
Parent: types.Parent{ Parent: types.Parent{
Type: types.ConfigTypeOrg, Type: types.ConfigTypeOrg,
ID: org.ID, ID: org.ID,

View File

@ -117,8 +117,11 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
return nil, errors.Wrapf(err, "failed to marshal user") return nil, errors.Wrapf(err, "failed to marshal user")
} }
// create root user project group
pg := &types.ProjectGroup{ pg := &types.ProjectGroup{
ID: uuid.NewV4().String(), ID: uuid.NewV4().String(),
// use public visibility
Visibility: types.VisibilityPublic,
Parent: types.Parent{ Parent: types.Parent{
Type: types.ConfigTypeUser, Type: types.ConfigTypeUser,
ID: user.ID, ID: user.ID,

View File

@ -102,13 +102,23 @@ func getGlobalVisibility(readDB *readdb.ReadDB, tx *db.Tx, curVisibility types.V
return "", err return "", err
} }
if projectGroup.Visibility == types.VisibilityPrivate { if projectGroup.Visibility == types.VisibilityPrivate {
curVisibility = types.VisibilityPrivate return types.VisibilityPrivate, nil
continue
} }
curParent = &projectGroup.Parent curParent = &projectGroup.Parent
} }
// check parent visibility
if curParent.Type == types.ConfigTypeOrg {
org, err := readDB.GetOrg(tx, curParent.ID)
if err != nil {
return "", err
}
if org.Visibility == types.VisibilityPrivate {
return types.VisibilityPrivate, nil
}
}
return curVisibility, nil return curVisibility, nil
} }

View File

@ -386,7 +386,7 @@ func TestProjectGroupsAndProjects(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected err: %v", err) t.Fatalf("unexpected err: %v", err)
} }
org, err := cs.ah.CreateOrg(ctx, &types.Organization{Name: "org01"}) org, err := cs.ah.CreateOrg(ctx, &types.Organization{Name: "org01", Visibility: types.VisibilityPublic})
if err != nil { if err != nil {
t.Fatalf("unexpected err: %v", err) t.Fatalf("unexpected err: %v", err)
} }
@ -533,7 +533,7 @@ func TestProjectGroupDelete(t *testing.T) {
//if err != nil { //if err != nil {
// t.Fatalf("unexpected err: %v", err) // t.Fatalf("unexpected err: %v", err)
//} //}
org, err := cs.ah.CreateOrg(ctx, &types.Organization{Name: "org01"}) org, err := cs.ah.CreateOrg(ctx, &types.Organization{Name: "org01", Visibility: types.VisibilityPublic})
if err != nil { if err != nil {
t.Fatalf("unexpected err: %v", err) t.Fatalf("unexpected err: %v", err)
} }
@ -674,7 +674,7 @@ func TestOrgMembers(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected err: %v", err) t.Fatalf("unexpected err: %v", err)
} }
org, err := cs.ah.CreateOrg(ctx, &types.Organization{Name: "org01", CreatorUserID: user.ID}) org, err := cs.ah.CreateOrg(ctx, &types.Organization{Name: "org01", Visibility: types.VisibilityPublic, CreatorUserID: user.ID})
if err != nil { if err != nil {
t.Fatalf("unexpected err: %v", err) t.Fatalf("unexpected err: %v", err)
} }
@ -700,7 +700,7 @@ func TestOrgMembers(t *testing.T) {
orgs := []*types.Organization{} orgs := []*types.Organization{}
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
org, err := cs.ah.CreateOrg(ctx, &types.Organization{Name: fmt.Sprintf("org%d", i), CreatorUserID: user.ID}) org, err := cs.ah.CreateOrg(ctx, &types.Organization{Name: fmt.Sprintf("org%d", i), Visibility: types.VisibilityPublic, CreatorUserID: user.ID})
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }

View File

@ -46,7 +46,8 @@ func (h *ActionHandler) GetOrgs(ctx context.Context, req *GetOrgsRequest) ([]*ty
} }
type CreateOrgRequest struct { type CreateOrgRequest struct {
Name string Name string
Visibility types.Visibility
CreatorUserID string CreatorUserID string
} }
@ -64,7 +65,8 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, req *CreateOrgRequest) (*
} }
org := &types.Organization{ org := &types.Organization{
Name: req.Name, Name: req.Name,
Visibility: req.Visibility,
} }
if req.CreatorUserID != "" { if req.CreatorUserID != "" {
org.CreatorUserID = req.CreatorUserID org.CreatorUserID = req.CreatorUserID

View File

@ -29,7 +29,8 @@ import (
) )
type CreateOrgRequest struct { type CreateOrgRequest struct {
Name string `json:"name"` Name string `json:"name"`
Visibility types.Visibility `json:"visibility"`
} }
type CreateOrgHandler struct { type CreateOrgHandler struct {
@ -60,6 +61,7 @@ func (h *CreateOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
creq := &action.CreateOrgRequest{ creq := &action.CreateOrgRequest{
Name: req.Name, Name: req.Name,
Visibility: req.Visibility,
CreatorUserID: userID, CreatorUserID: userID,
} }
@ -127,14 +129,16 @@ func (h *OrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
type OrgResponse struct { type OrgResponse struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Visibility types.Visibility `json:"visibility,omitempty"`
} }
func createOrgResponse(o *types.Organization) *OrgResponse { func createOrgResponse(o *types.Organization) *OrgResponse {
org := &OrgResponse{ org := &OrgResponse{
ID: o.ID, ID: o.ID,
Name: o.Name, Name: o.Name,
Visibility: o.Visibility,
} }
return org return org
} }

View File

@ -107,6 +107,8 @@ type Organization struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Visibility Visibility `json:"visibility,omitempty"`
// CreatorUserID is the user id that created the organization. It could be empty // CreatorUserID is the user id that created the organization. It could be empty
// if the org was created by using the admin user or the user has been removed. // if the org was created by using the admin user or the user has been removed.
CreatorUserID string `json:"creator_user_id,omitempty"` CreatorUserID string `json:"creator_user_id,omitempty"`