Skip to content

Commit fc19249

Browse files
authored
feat: implement create demo organization (#2009)
1 parent 0c64a5e commit fc19249

36 files changed

Lines changed: 2973 additions & 1298 deletions

File tree

api-description/apidocs.swagger.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5112,6 +5112,7 @@ definitions:
51125112
- ORGANIZATION_TRIAL_CONVERTED
51135113
- ORGANIZATION_OWNER_EMAIL_CHANGED
51145114
- ORGANIZATION_UPDATED
5115+
- DEMO_ORGANIZATION_CREATED
51155116
- FLAG_TRIGGER_CREATED
51165117
- FLAG_TRIGGER_RESET
51175118
- FLAG_TRIGGER_DESCRIPTION_CHANGED

api-description/web-api.swagger.yaml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2929,6 +2929,64 @@ paths:
29292929
$ref: '#/definitions/environmentConvertTrialProjectRequest'
29302930
tags:
29312931
- Project
2932+
/v1/environment/create_demo_organization:
2933+
post:
2934+
summary: Create Demo Organization
2935+
description: Create a demo organization. To call this API, you need an `SYSTEM_ADMIN` role.
2936+
operationId: web.v1.environment.create_demo_organization
2937+
responses:
2938+
"200":
2939+
description: A successful response.
2940+
schema:
2941+
$ref: '#/definitions/environmentCreateDemoOrganizationResponse'
2942+
"400":
2943+
description: Returned for bad requests that may have failed validation.
2944+
schema:
2945+
$ref: '#/definitions/googlerpcStatus'
2946+
examples:
2947+
application/json:
2948+
code: 3
2949+
details: []
2950+
message: invalid arguments error
2951+
"401":
2952+
description: Request could not be authenticated (authentication required).
2953+
schema:
2954+
$ref: '#/definitions/googlerpcStatus'
2955+
examples:
2956+
application/json:
2957+
code: 16
2958+
details: []
2959+
message: not authenticated
2960+
"403":
2961+
description: Request does not have permission to access the resource.
2962+
schema:
2963+
$ref: '#/definitions/googlerpcStatus'
2964+
examples:
2965+
application/json:
2966+
code: 7
2967+
details: []
2968+
message: not authorized
2969+
"503":
2970+
description: Returned for internal errors.
2971+
schema:
2972+
$ref: '#/definitions/googlerpcStatus'
2973+
examples:
2974+
application/json:
2975+
code: 13
2976+
details: []
2977+
message: internal
2978+
default:
2979+
description: An unexpected error response.
2980+
schema:
2981+
$ref: '#/definitions/googlerpcStatus'
2982+
parameters:
2983+
- name: body
2984+
in: body
2985+
required: true
2986+
schema:
2987+
$ref: '#/definitions/environmentCreateDemoOrganizationRequest'
2988+
tags:
2989+
- Organization
29322990
/v1/environment/create_environment:
29332991
post:
29342992
summary: Create
@@ -10600,6 +10658,7 @@ definitions:
1060010658
- ORGANIZATION_TRIAL_CONVERTED
1060110659
- ORGANIZATION_OWNER_EMAIL_CHANGED
1060210660
- ORGANIZATION_UPDATED
10661+
- DEMO_ORGANIZATION_CREATED
1060310662
- FLAG_TRIGGER_CREATED
1060410663
- FLAG_TRIGGER_RESET
1060510664
- FLAG_TRIGGER_DESCRIPTION_CHANGED
@@ -10710,6 +10769,23 @@ definitions:
1071010769
$ref: '#/definitions/environmentConvertTrialProjectCommand'
1071110770
environmentConvertTrialProjectResponse:
1071210771
type: object
10772+
environmentCreateDemoOrganizationRequest:
10773+
type: object
10774+
properties:
10775+
name:
10776+
type: string
10777+
urlCode:
10778+
type: string
10779+
description:
10780+
type: string
10781+
required:
10782+
- name
10783+
- urlCode
10784+
environmentCreateDemoOrganizationResponse:
10785+
type: object
10786+
properties:
10787+
organization:
10788+
$ref: '#/definitions/bucketeerenvironmentOrganization'
1071310789
environmentCreateEnvironmentV2Command:
1071410790
type: object
1071510791
properties:

pkg/account/api/account_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2023,5 +2023,5 @@ func setToken(ctx context.Context, isSystemAdmin bool) context.Context {
20232023
Email: "email",
20242024
IsSystemAdmin: isSystemAdmin,
20252025
}
2026-
return context.WithValue(ctx, rpc.Key, t)
2026+
return context.WithValue(ctx, rpc.AccessTokenKey, t)
20272027
}

pkg/account/api/api_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func createContextWithEmailToken(t *testing.T, email string, isSystemAdmin bool)
8282
IsSystemAdmin: isSystemAdmin,
8383
}
8484
ctx := context.TODO()
85-
return context.WithValue(ctx, rpc.Key, token)
85+
return context.WithValue(ctx, rpc.AccessTokenKey, token)
8686
}
8787

8888
func createContextWithInvalidEmailToken(t *testing.T) context.Context {
@@ -95,5 +95,5 @@ func createContextWithInvalidEmailToken(t *testing.T) context.Context {
9595
Email: "bucketeer@",
9696
}
9797
ctx := context.TODO()
98-
return context.WithValue(ctx, rpc.Key, token)
98+
return context.WithValue(ctx, rpc.AccessTokenKey, token)
9999
}

pkg/auditlog/api/api_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ func createContextWithToken(t *testing.T, isSystemAdmin bool) context.Context {
737737
IsSystemAdmin: isSystemAdmin,
738738
}
739739
ctx := context.TODO()
740-
return context.WithValue(ctx, rpc.Key, token)
740+
return context.WithValue(ctx, rpc.AccessTokenKey, token)
741741
}
742742

743743
func createContextWithTokenRoleUnassigned(t *testing.T) context.Context {
@@ -746,5 +746,5 @@ func createContextWithTokenRoleUnassigned(t *testing.T) context.Context {
746746
Email: "test@example.com",
747747
}
748748
ctx := context.TODO()
749-
return context.WithValue(ctx, rpc.Key, token)
749+
return context.WithValue(ctx, rpc.AccessTokenKey, token)
750750
}

pkg/auth/google/authenticator.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type googleUserInfo struct {
4444
FamilyName string `json:"family_name"`
4545
Picture string `json:"picture"`
4646
Email string `json:"email"`
47-
EmailVerified bool `json:"email_verified"`
47+
EmailVerified bool `json:"verified_email"`
4848
}
4949

5050
type Authenticator struct {
@@ -110,6 +110,7 @@ func (a Authenticator) getGoogleUserInfo(
110110
) (googleUserInfo, error) {
111111
var userInfo googleUserInfo
112112
client := config.Client(ctx, t)
113+
// API doc: https://googleoauth2.apidog.io/
113114
resp, err := client.Get("https://www.googleapis.com/oauth2/v2/userinfo")
114115
if err != nil {
115116
a.logger.Error("auth/google: failed to get user info", zap.Error(err))

pkg/autoops/api/api_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,7 +1937,7 @@ func createContextWithTokenRoleUnassigned(t *testing.T) context.Context {
19371937
Email: "email",
19381938
}
19391939
ctx := context.TODO()
1940-
return context.WithValue(ctx, rpc.Key, token)
1940+
return context.WithValue(ctx, rpc.AccessTokenKey, token)
19411941
}
19421942

19431943
func createContextWithTokenRoleOwner(t *testing.T) context.Context {
@@ -1951,5 +1951,5 @@ func createContextWithTokenRoleOwner(t *testing.T) context.Context {
19511951
IsSystemAdmin: true,
19521952
}
19531953
ctx := context.TODO()
1954-
return context.WithValue(ctx, rpc.Key, token)
1954+
return context.WithValue(ctx, rpc.AccessTokenKey, token)
19551955
}

pkg/domainevent/domain/message.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,14 @@ func LocalizedMessage(eventType proto.Event_Type, localizer locale.Localizer) *p
13111311
localizer.MustLocalizeWithTemplate(locale.Organization),
13121312
),
13131313
}
1314+
case proto.Event_DEMO_ORGANIZATION_CREATED:
1315+
return &proto.LocalizedMessage{
1316+
Locale: localizer.GetLocale(),
1317+
Message: localizer.MustLocalizeWithTemplate(
1318+
locale.CreatedTemplate,
1319+
localizer.MustLocalizeWithTemplate(locale.Organization),
1320+
),
1321+
}
13141322
case proto.Event_ORGANIZATION_NAME_CHANGED:
13151323
return &proto.LocalizedMessage{
13161324
Locale: localizer.GetLocale(),

pkg/environment/api/api.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
accountclient "github.com/bucketeer-io/bucketeer/pkg/account/client"
3030
accdomain "github.com/bucketeer-io/bucketeer/pkg/account/domain"
3131
accstorage "github.com/bucketeer-io/bucketeer/pkg/account/storage/v2"
32+
v2acc "github.com/bucketeer-io/bucketeer/pkg/account/storage/v2"
3233
"github.com/bucketeer-io/bucketeer/pkg/auth"
3334
"github.com/bucketeer-io/bucketeer/pkg/auth/google"
3435
v2 "github.com/bucketeer-io/bucketeer/pkg/environment/storage/v2"
@@ -79,6 +80,7 @@ type EnvironmentService struct {
7980
projectStorage v2.ProjectStorage
8081
orgStorage v2.OrganizationStorage
8182
environmentStorage v2.EnvironmentStorage
83+
accountStorage v2acc.AccountStorage
8284
publisher publisher.Publisher
8385
googleAuthenticator auth.Authenticator
8486
verifier token.Verifier
@@ -110,6 +112,7 @@ func NewEnvironmentService(
110112
projectStorage: v2.NewProjectStorage(mysqlClient),
111113
orgStorage: v2.NewOrganizationStorage(mysqlClient),
112114
environmentStorage: v2.NewEnvironmentStorage(mysqlClient),
115+
accountStorage: v2acc.NewAccountStorage(mysqlClient),
113116
publisher: publisher,
114117
googleAuthenticator: google.NewAuthenticator(
115118
&config.GoogleConfig, logger,

pkg/environment/api/api_test.go

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"go.uber.org/zap"
2626

2727
acmock "github.com/bucketeer-io/bucketeer/pkg/account/client/mock"
28+
accstoragemock "github.com/bucketeer-io/bucketeer/pkg/account/storage/v2/mock"
2829
"github.com/bucketeer-io/bucketeer/pkg/auth"
2930
storagemock "github.com/bucketeer-io/bucketeer/pkg/environment/storage/v2/mock"
3031
"github.com/bucketeer-io/bucketeer/pkg/log"
@@ -60,7 +61,20 @@ func createContextWithToken(t *testing.T) context.Context {
6061
IsSystemAdmin: true,
6162
}
6263
ctx := context.TODO()
63-
return context.WithValue(ctx, rpc.Key, token)
64+
return context.WithValue(ctx, rpc.AccessTokenKey, token)
65+
}
66+
67+
func createDemoContextWithToken(t *testing.T) context.Context {
68+
t.Helper()
69+
token := &token.DemoCreationToken{
70+
Issuer: "issuer",
71+
Audience: "audience",
72+
Expiry: time.Now().AddDate(100, 0, 0),
73+
IssuedAt: time.Now(),
74+
Email: "test@example.com",
75+
}
76+
ctx := context.TODO()
77+
return context.WithValue(ctx, rpc.DemoCreationTokenKey, token)
6478
}
6579

6680
func createContextWithTokenRoleUnassigned(t *testing.T) context.Context {
@@ -73,7 +87,7 @@ func createContextWithTokenRoleUnassigned(t *testing.T) context.Context {
7387
Email: "email",
7488
}
7589
ctx := context.TODO()
76-
return context.WithValue(ctx, rpc.Key, token)
90+
return context.WithValue(ctx, rpc.AccessTokenKey, token)
7791
}
7892
func newEnvironmentService(t *testing.T, mockController *gomock.Controller, s storage.Client) *EnvironmentService {
7993
t.Helper()
@@ -85,7 +99,28 @@ func newEnvironmentService(t *testing.T, mockController *gomock.Controller, s st
8599
orgStorage: storagemock.NewMockOrganizationStorage(mockController),
86100
projectStorage: storagemock.NewMockProjectStorage(mockController),
87101
environmentStorage: storagemock.NewMockEnvironmentStorage(mockController),
102+
accountStorage: accstoragemock.NewMockAccountStorage(mockController),
103+
publisher: publishermock.NewMockPublisher(mockController),
104+
logger: logger.Named("api"),
105+
}
106+
}
107+
108+
func newDemoEnvironmentService(t *testing.T, mockController *gomock.Controller, s storage.Client) *EnvironmentService {
109+
t.Helper()
110+
logger, err := log.NewLogger()
111+
require.NoError(t, err)
112+
return &EnvironmentService{
113+
accountClient: acmock.NewMockClient(mockController),
114+
mysqlClient: mysqlmock.NewMockClient(mockController),
115+
orgStorage: storagemock.NewMockOrganizationStorage(mockController),
116+
projectStorage: storagemock.NewMockProjectStorage(mockController),
117+
environmentStorage: storagemock.NewMockEnvironmentStorage(mockController),
118+
accountStorage: accstoragemock.NewMockAccountStorage(mockController),
88119
publisher: publishermock.NewMockPublisher(mockController),
89120
logger: logger.Named("api"),
121+
opts: &options{
122+
logger: logger,
123+
isDemoSiteEnabled: true,
124+
},
90125
}
91126
}

0 commit comments

Comments
 (0)