-
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
// 🚨 SECURITY: Require appropriate M2M scope. | ||
requiredScope := samsm2m.EnterprisePortalScope("subscription", scopes.ActionRead) | ||
clientAttrs, err := samsm2m.RequireScope(ctx, logger, s.store, requiredScope, req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
logger = logger.With(clientAttrs...) | ||
|
||
subscriptionID := req.Msg.GetId() | ||
if subscriptionID == "" { | ||
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("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") | ||
} | ||
|
||
proto := convertSubscriptionToProto(sub) | ||
logger.Scoped("audit").Info("GetEnterpriseSubscription", | ||
log.String("subscription", proto.Id)) | ||
return connect.NewResponse(&subscriptionsv1.GetEnterpriseSubscriptionResponse{ | ||
Subscription: proto, | ||
}), nil |
Check notice
Code scanning / Semgrep OSS
Semgrep Finding: security-semgrep-rules.semgrep-rules.generic.comment-tagging-rule Note
// 🚨 SECURITY: Require appropriate M2M scope. | ||
requiredScope := samsm2m.EnterprisePortalScope("subscription", scopes.ActionWrite) | ||
clientAttrs, err := samsm2m.RequireScope(ctx, logger, s.store, requiredScope, req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
logger = logger.With(clientAttrs...) | ||
|
||
licenseID := req.Msg.LicenseId | ||
if licenseID == "" { | ||
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("license_id is required")) | ||
} | ||
|
||
license, err := s.store.RevokeEnterpriseSubscriptionLicense(ctx, licenseID, subscriptions.RevokeLicenseOpts{ | ||
Message: req.Msg.GetReason(), | ||
Time: pointers.Ptr(utctime.Now()), | ||
}) | ||
if err != nil { | ||
if errors.Is(err, subscriptions.ErrSubscriptionLicenseNotFound) { | ||
return nil, connect.NewError(connect.CodeNotFound, err) | ||
} | ||
return nil, connectutil.InternalError(ctx, logger, err, "failed to revoked license") | ||
} | ||
|
||
logger.Scoped("audit").Info("RevokeEnterpriseSubscriptionLicense", | ||
log.String("subscription", license.SubscriptionID), | ||
log.String("revokedLicense", license.ID)) | ||
return connect.NewResponse(&subscriptionsv1.RevokeEnterpriseSubscriptionLicenseResponse{}), nil |
Check notice
Code scanning / Semgrep OSS
Semgrep Finding: security-semgrep-rules.semgrep-rules.generic.comment-tagging-rule Note
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
logger := trace.Logger(ctx, s.logger) | ||
|
||
// 🚨 SECURITY: Require appropriate M2M scope. | ||
requiredScope := samsm2m.EnterprisePortalScope("subscription", 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.
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 Note
// 🚨 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 Note
// 🚨 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 Note
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
autogold
rendering ofutctime.Time
Closes https://linear.app/sourcegraph/issue/CORE-156
Part of https://linear.app/sourcegraph/issue/CORE-158
Test plan