mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Mm 47648 check license expandable (#21770)
* [MM-47648] Handler for check if a subscription is expandable * Mock cloud regenerate * PR Webapp test purpose only * [MM-47648] Refactor and tests for expand stats for a subscription * Fix typos * style fix * has to be revert * CWS URL to Spinwick * new spinwick url * target portal test * Generate token instead of send licenseId * Rename * Rename methods * Revert public key and cws url Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
@@ -40,6 +40,7 @@ func (api *API) InitCloud() {
|
||||
api.BaseRoutes.Cloud.Handle("/subscription", api.APISessionRequired(getSubscription)).Methods("GET")
|
||||
api.BaseRoutes.Cloud.Handle("/subscription/invoices", api.APISessionRequired(getInvoicesForSubscription)).Methods("GET")
|
||||
api.BaseRoutes.Cloud.Handle("/subscription/invoices/{invoice_id:[A-Za-z0-9]+}/pdf", api.APISessionRequired(getSubscriptionInvoicePDF)).Methods("GET")
|
||||
api.BaseRoutes.Cloud.Handle("/subscription/expand", api.APISessionRequired(GetLicenseExpandStatus)).Methods("GET")
|
||||
api.BaseRoutes.Cloud.Handle("/subscription", api.APISessionRequired(changeSubscription)).Methods("PUT")
|
||||
|
||||
// GET /api/v4/cloud/request-trial
|
||||
@@ -413,6 +414,34 @@ func getCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
w.Write(json)
|
||||
}
|
||||
|
||||
func GetLicenseExpandStatus(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageLicenseInformation) {
|
||||
c.SetPermissionError(model.PermissionManageLicenseInformation)
|
||||
return
|
||||
}
|
||||
|
||||
_, token, err := c.App.Srv().GenerateLicenseRenewalLink()
|
||||
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
res, cloudErr := c.App.Cloud().GetLicenseExpandStatus(c.AppContext.Session().UserId, token)
|
||||
if cloudErr != nil {
|
||||
c.Err = model.NewAppError("Api4.GetLicenseExpandStatusForSubscription", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(cloudErr)
|
||||
return
|
||||
}
|
||||
|
||||
json, jsonErr := json.Marshal(res)
|
||||
if jsonErr != nil {
|
||||
c.Err = model.NewAppError("Api4.GetLicenseExpandStatusForSubscription", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(json)
|
||||
}
|
||||
|
||||
func updateCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.App.Channels().License().IsCloud() {
|
||||
c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.license_error", nil, "", http.StatusForbidden)
|
||||
|
||||
@@ -649,6 +649,58 @@ func TestGetCloudProducts(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_GetExpandStatsForSubscription(t *testing.T) {
|
||||
isExpandable := &model.SubscriptionExpandStatus{
|
||||
IsExpandable: true,
|
||||
}
|
||||
|
||||
licenseId := "licenseID"
|
||||
|
||||
t.Run("NON Admin users are UNABLE to request expand stats for the subscription", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
th.Client.Login(th.BasicUser.Email, th.BasicUser.Password)
|
||||
|
||||
cloud := mocks.CloudInterface{}
|
||||
|
||||
cloud.Mock.On("GetLicenseExpandStatus", mock.Anything).Return(isExpandable, nil)
|
||||
|
||||
cloudImpl := th.App.Srv().Cloud
|
||||
defer func() {
|
||||
th.App.Srv().Cloud = cloudImpl
|
||||
}()
|
||||
th.App.Srv().Cloud = &cloud
|
||||
|
||||
subscriptionExpandable, r, err := th.Client.GetExpandStats(licenseId)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, subscriptionExpandable)
|
||||
require.Equal(t, http.StatusForbidden, r.StatusCode, "403 Forbidden")
|
||||
})
|
||||
|
||||
t.Run("Admin users are UNABLE to request licenses is expendable due missing the id", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
th.Client.Login(th.SystemAdminUser.Email, th.SystemAdminUser.Password)
|
||||
|
||||
cloud := mocks.CloudInterface{}
|
||||
|
||||
cloud.Mock.On("GetLicenseExpandStatus", mock.Anything).Return(isExpandable, nil)
|
||||
|
||||
cloudImpl := th.App.Srv().Cloud
|
||||
defer func() {
|
||||
th.App.Srv().Cloud = cloudImpl
|
||||
}()
|
||||
th.App.Srv().Cloud = &cloud
|
||||
|
||||
subscriptionExpandable, r, err := th.Client.GetExpandStats("")
|
||||
require.Error(t, err)
|
||||
require.Nil(t, subscriptionExpandable)
|
||||
require.Equal(t, http.StatusBadRequest, r.StatusCode, "400 Bad Request")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetSelfHostedProducts(t *testing.T) {
|
||||
products := []*model.Product{
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ type CloudInterface interface {
|
||||
ConfirmCustomerPayment(userID string, confirmRequest *model.ConfirmPaymentMethodRequest) error
|
||||
|
||||
GetCloudCustomer(userID string) (*model.CloudCustomer, error)
|
||||
GetLicenseExpandStatus(userID string, token string) (*model.SubscriptionExpandStatus, error)
|
||||
UpdateCloudCustomer(userID string, customerInfo *model.CloudCustomerInfo) (*model.CloudCustomer, error)
|
||||
UpdateCloudCustomerAddress(userID string, address *model.Address) (*model.CloudCustomer, error)
|
||||
|
||||
|
||||
@@ -325,6 +325,29 @@ func (_m *CloudInterface) GetInvoicesForSubscription(userID string) ([]*model.In
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetLicenseExpandStatus provides a mock function with given fields: userID, token
|
||||
func (_m *CloudInterface) GetLicenseExpandStatus(userID string, token string) (*model.SubscriptionExpandStatus, error) {
|
||||
ret := _m.Called(userID, token)
|
||||
|
||||
var r0 *model.SubscriptionExpandStatus
|
||||
if rf, ok := ret.Get(0).(func(string, string) *model.SubscriptionExpandStatus); ok {
|
||||
r0 = rf(userID, token)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.SubscriptionExpandStatus)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||
r1 = rf(userID, token)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetLicenseRenewalStatus provides a mock function with given fields: userID, token
|
||||
func (_m *CloudInterface) GetLicenseRenewalStatus(userID string, token string) error {
|
||||
ret := _m.Called(userID, token)
|
||||
|
||||
@@ -8213,6 +8213,19 @@ func (c *Client4) GetCloudCustomer() (*CloudCustomer, *Response, error) {
|
||||
return cloudCustomer, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) GetExpandStats(licenseId string) (*SubscriptionExpandStatus, *Response, error) {
|
||||
r, err := c.DoAPIGet(fmt.Sprintf("%s%s?licenseID=%s", c.cloudRoute(), "/subscription/expand", licenseId), "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
var subscriptionExpandable *SubscriptionExpandStatus
|
||||
json.NewDecoder(r.Body).Decode(&subscriptionExpandable)
|
||||
|
||||
return subscriptionExpandable, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) GetSubscription() (*Subscription, *Response, error) {
|
||||
r, err := c.DoAPIGet(c.cloudRoute()+"/subscription", "")
|
||||
if err != nil {
|
||||
|
||||
@@ -124,6 +124,10 @@ type ValidateBusinessEmailResponse struct {
|
||||
IsValid bool `json:"is_valid"`
|
||||
}
|
||||
|
||||
type SubscriptionExpandStatus struct {
|
||||
IsExpandable bool `json:"is_expandable"`
|
||||
}
|
||||
|
||||
// CloudCustomerInfo represents editable info of a customer.
|
||||
type CloudCustomerInfo struct {
|
||||
Name string `json:"name"`
|
||||
|
||||
Reference in New Issue
Block a user