-
Notifications
You must be signed in to change notification settings - Fork 1.3k
feat/enterpriseportal: all subscriptions APIs use enterprise portal DB #63959
feat/enterpriseportal: all subscriptions APIs use enterprise portal DB #63959
Conversation
7e86a43 to
152047a
Compare
fa7d5bc to
2ada484
Compare
152047a to
16bc317
Compare
2ada484 to
42751d4
Compare
Check notice
Code scanning / Semgrep OSS
Semgrep Finding: security-semgrep-rules.semgrep-rules.generic.comment-tagging-rule
Check notice
Code scanning / Semgrep OSS
Semgrep Finding: security-semgrep-rules.semgrep-rules.generic.comment-tagging-rule
42751d4 to
23df245
Compare
16bc317 to
d0bce4c
Compare
23df245 to
c2e0a5d
Compare
d0bce4c to
80c6ad1
Compare
c2e0a5d to
cca76b4
Compare
80c6ad1 to
99e6e2a
Compare
cca76b4 to
1cc2185
Compare
99e6e2a to
38aaf6b
Compare
1cc2185 to
c6041c4
Compare
38aaf6b to
d279b4e
Compare
c6041c4 to
aea1c9a
Compare
480c94b to
8fd0533
Compare
06eecf1 to
2e737a6
Compare
2e737a6 to
b042f89
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throughout this file it seems to use the string literal permission in numerous places rather than using the exported value from the sdk
| requiredScope := samsm2m.EnterprisePortalScope("subscription", scopes.ActionRead) | |
| requiredScope := samsm2m.EnterprisePortalScope(scopes.PermissionEnterprisePortalSubscription, scopes.ActionRead) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, this predates the change to make the permissions public consts - updated, thank you!
b042f89 to
9ae24a6
Compare
| // 🚨 SECURITY: Require appropriate M2M scope. | ||
| requiredScope := samsm2m.EnterprisePortalScope( | ||
| scopes.PermissionEnterprisePortalSubscription, scopes.ActionWrite) | ||
| clientAttrs, err := samsm2m.RequireScope(ctx, logger, s.store, requiredScope, req) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| logger = logger.With(clientAttrs...) | ||
|
|
||
| sub := req.Msg.GetSubscription() | ||
| if sub == nil { | ||
| return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("subscription details are required")) | ||
| } | ||
|
|
||
| // Validate required arguments. | ||
| if strings.TrimSpace(sub.GetDisplayName()) == "" { | ||
| return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("display_name is required")) | ||
| } | ||
|
|
||
| // Generate a new ID for the subscription. | ||
| if sub.Id != "" { | ||
| return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("subscription_id can not be set")) | ||
| } | ||
| sub.Id, err = s.store.GenerateSubscriptionID() | ||
| if err != nil { | ||
| return nil, connectutil.InternalError(ctx, s.logger, err, "failed to generate new subscription ID") | ||
| } | ||
|
|
||
| // Check for an existing subscription, just in case. | ||
| if _, err := s.store.GetEnterpriseSubscription(ctx, sub.Id); err == nil { | ||
| return nil, connect.NewError(connect.CodeAlreadyExists, err) |
Check notice
Code scanning / Semgrep OSS
Semgrep Finding: security-semgrep-rules.semgrep-rules.generic.comment-tagging-rule
| // 🚨 SECURITY: Require appropriate M2M scope. | ||
| requiredScope := samsm2m.EnterprisePortalScope( | ||
| scopes.PermissionEnterprisePortalSubscription, scopes.ActionWrite) | ||
| clientAttrs, err := samsm2m.RequireScope(ctx, logger, s.store, requiredScope, req) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| logger = logger.With(clientAttrs...) | ||
|
|
||
| subscriptionID := req.Msg.GetSubscriptionId() | ||
| if subscriptionID == "" { | ||
| return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("subscription_id is required")) | ||
| } | ||
|
|
||
| if _, err := s.store.GetEnterpriseSubscription(ctx, subscriptionID); err != nil { | ||
| if errors.Is(err, subscriptions.ErrSubscriptionNotFound) { | ||
| return nil, connect.NewError(connect.CodeNotFound, err) | ||
| } | ||
| return nil, connectutil.InternalError(ctx, logger, err, "failed to find subscription") | ||
| } | ||
|
|
||
| archivedAt := s.store.Now() | ||
|
|
||
| // First, revoke all licenses associated with this subscription | ||
| licenses, err := s.store.ListEnterpriseSubscriptionLicenses(ctx, subscriptions.ListLicensesOpts{ | ||
| SubscriptionID: subscriptionID, | ||
| }) | ||
| if err != nil { | ||
| return nil, connectutil.InternalError(ctx, logger, err, "failed to list licenses for subscription") | ||
| } | ||
| revokedLicenses := make([]string, 0, len(licenses)) |
Check notice
Code scanning / Semgrep OSS
Semgrep Finding: security-semgrep-rules.semgrep-rules.generic.comment-tagging-rule
| // 🚨 SECURITY: Require appropriate M2M scope. | ||
| requiredScope := samsm2m.EnterprisePortalScope( | ||
| scopes.PermissionEnterprisePortalSubscription, scopes.ActionWrite) | ||
| clientAttrs, err := samsm2m.RequireScope(ctx, logger, s.store, requiredScope, req) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| logger = logger.With(clientAttrs...) | ||
|
|
||
| create := req.Msg.GetLicense() | ||
| if create.GetId() != "" { | ||
| return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("license.id cannot be set")) | ||
| } | ||
| subscriptionID := create.GetSubscriptionId() | ||
| if subscriptionID == "" { | ||
| return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("license.subscription_id is required")) | ||
| } | ||
| sub, err := s.store.GetEnterpriseSubscription(ctx, subscriptionID) | ||
| if err != nil { | ||
| if errors.Is(err, subscriptions.ErrSubscriptionNotFound) { | ||
| return nil, connect.NewError(connect.CodeNotFound, err) | ||
| } | ||
| return nil, connectutil.InternalError(ctx, logger, err, "failed to find subscription") | ||
| } | ||
| if sub.ArchivedAt != nil { | ||
| return nil, connect.NewError(connect.CodeInvalidArgument, | ||
| errors.New("target subscription is archived")) | ||
| } | ||
|
|
||
| createdAt := s.store.Now() |
Check notice
Code scanning / Semgrep OSS
Semgrep Finding: security-semgrep-rules.semgrep-rules.generic.comment-tagging-rule

This change follows https://github.com/sourcegraph/sourcegraph/pull/63858 by making the all subscriptions APIs read and write to the Enterprise Portal database, instead of dotcomdb, using the data that we sync from dotcomdb into Enterprise Portal.
With this PR, all initially proposed subscriptions APIs are at least partially implemented.
Uses hexops/valast#27 for custom
autogoldrendering ofutctime.TimeCloses https://linear.app/sourcegraph/issue/CORE-156
Part of https://linear.app/sourcegraph/issue/CORE-158
Test plan