[CLD-7567] Deprecate Self Serve: Second Pass (#26853)
* Deprecate Self Serve: First Pass * Fix ci * Fix more ci * Remmove outdated server tests * Fix a missed spot opening purchase modal in Self Hosted * Fix i18n * Clean up some more server code, fix webapp test * Fix alignment of button * Fix linter * Fix i18n server side * Deprecate in product true up * Add back translation * Remove client functions * Put back client functions * webapp deprecation * Deprecate Self Serve: Second Pass * Fix various pipeline issues * Fix linter * Fix pipelines * Fix handlers_test.go * Fix console.error around hostedCustomer in reducer * PICKY LINTER PLEASE * Fix webapp tests, various other fixes for the CI pipelines * Fix i18n * Updates to accomadate enterprise code removal * Fix mocks * More removal * Fix * Adjustments from PR * Fixes for QA Feedback * Update * Add migrations to remove true up review history * Fix migrations check --------- Co-authored-by: Mattermost Build <build@mattermost.com> Co-authored-by: maria.nunez <maria.nunez@mattermost.com>
Этот коммит содержится в:
@@ -35,7 +35,6 @@ 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/self-serve-status", api.APISessionRequired(getLicenseSelfServeStatus)).Methods("GET")
|
||||
|
||||
// GET /api/v4/cloud/validate-business-email
|
||||
api.BaseRoutes.Cloud.Handle("/validate-business-email", api.APISessionRequired(validateBusinessEmail)).Methods("POST")
|
||||
@@ -378,40 +377,6 @@ func getInstallation(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// getLicenseSelfServeStatus makes check for the license in the CWS self-serve portal and establishes if the license is renewable, expandable etc.
|
||||
func getLicenseSelfServeStatus(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
ensured := ensureCloudInterface(c, "Api4.getLicenseSelfServeStatus")
|
||||
if !ensured {
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
status, cloudErr := c.App.Cloud().GetLicenseSelfServeStatus(c.AppContext.Session().UserId, token)
|
||||
if cloudErr != nil {
|
||||
c.Err = model.NewAppError("Api4.getLicenseSelfServeStatus", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(cloudErr)
|
||||
return
|
||||
}
|
||||
|
||||
json, jsonErr := json.Marshal(status)
|
||||
if jsonErr != nil {
|
||||
c.Err = model.NewAppError("Api4.getLicenseSelfServeStatus", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(json)
|
||||
}
|
||||
|
||||
func updateCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
ensured := ensureCloudInterface(c, "Api4.updateCloudCustomer")
|
||||
if !ensured {
|
||||
|
||||
@@ -5,9 +5,7 @@ package api4
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
b64 "encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
@@ -23,10 +21,7 @@ func (api *API) InitLicense() {
|
||||
api.BaseRoutes.APIRoot.Handle("/trial-license/prev", api.APISessionRequired(getPrevTrialLicense)).Methods("GET")
|
||||
api.BaseRoutes.APIRoot.Handle("/license", api.APISessionRequired(addLicense, handlerParamFileAPI)).Methods("POST")
|
||||
api.BaseRoutes.APIRoot.Handle("/license", api.APISessionRequired(removeLicense)).Methods("DELETE")
|
||||
api.BaseRoutes.APIRoot.Handle("/license/renewal", api.APISessionRequired(requestRenewalLink)).Methods("GET")
|
||||
api.BaseRoutes.APIRoot.Handle("/license/client", api.APIHandler(getClientLicense)).Methods("GET")
|
||||
api.BaseRoutes.APIRoot.Handle("/license/review", api.APISessionRequired(requestTrueUpReview)).Methods("POST")
|
||||
api.BaseRoutes.APIRoot.Handle("/license/review/status", api.APISessionRequired(trueUpReviewStatus)).Methods("GET")
|
||||
}
|
||||
|
||||
func getClientLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
@@ -238,54 +233,6 @@ func requestTrialLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
func requestRenewalLink(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord("requestRenewalLink", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
c.LogAudit("attempt")
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageLicenseInformation) {
|
||||
c.SetPermissionError(model.PermissionManageLicenseInformation)
|
||||
return
|
||||
}
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("requestRenewalLink", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
renewalLink, token, err := c.App.Srv().GenerateLicenseRenewalLink()
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if c.App.Cloud() == nil {
|
||||
c.Err = model.NewAppError("requestRenewalLink", "api.license.upgrade_needed.app_error", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// check if it is possible to renew license on the portal with generated token
|
||||
status, e := c.App.Cloud().GetLicenseSelfServeStatus(c.AppContext.Session().UserId, token)
|
||||
if e != nil {
|
||||
c.Err = model.NewAppError("requestRenewalLink", "api.license.request_renewal_link.cannot_renew_on_cws", nil, "", http.StatusInternalServerError).Wrap(e)
|
||||
return
|
||||
}
|
||||
|
||||
if !status.IsRenewable {
|
||||
c.Err = model.NewAppError("requestRenewalLink", "api.license.request_renewal_link.cannot_renew_on_cws", nil, "License is not self-serve renewable", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
c.LogAudit("success")
|
||||
|
||||
_, werr := w.Write([]byte(fmt.Sprintf(`{"renewal_link": "%s"}`, renewalLink)))
|
||||
if werr != nil {
|
||||
c.Err = model.NewAppError("requestRenewalLink", "api.license.request_renewal_link.app_error", nil, "", http.StatusForbidden).Wrap(werr)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func getPrevTrialLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if c.App.Srv().Platform().LicenseManager() == nil {
|
||||
c.Err = model.NewAppError("getPrevTrialLicense", "api.license.upgrade_needed.app_error", nil, "", http.StatusForbidden)
|
||||
@@ -308,102 +255,3 @@ func getPrevTrialLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.Write([]byte(model.MapToJSON(clientLicense)))
|
||||
}
|
||||
|
||||
func requestTrueUpReview(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
// Only admins can request a true up review.
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) {
|
||||
c.SetPermissionError(model.PermissionManageLicenseInformation)
|
||||
return
|
||||
}
|
||||
|
||||
license := c.App.Channels().License()
|
||||
if license == nil {
|
||||
c.Err = model.NewAppError("requestTrueUpReview", "api.license.true_up_review.license_required", nil, "", http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
|
||||
if license.IsCloud() {
|
||||
c.Err = model.NewAppError("requestTrueUpReview", "api.license.true_up_review.not_allowed_for_cloud", nil, "", http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
|
||||
status, appErr := c.App.GetOrCreateTrueUpReviewStatus(c.AppContext)
|
||||
if appErr != nil {
|
||||
c.Err = appErr
|
||||
return
|
||||
}
|
||||
|
||||
// If a true up review has already been submitted for the current due date, complete the request
|
||||
// with no errors.
|
||||
if status.Completed {
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
profileMap, err := c.App.GetTrueUpProfile()
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("requestTrueUpReview", "api.license.true_up_review.get_status_error", nil, "", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
profileMapJson, err := json.Marshal(profileMap)
|
||||
if err != nil {
|
||||
c.SetJSONEncodingError(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Only report the true up review to CWS if the connection is available.
|
||||
if err := c.App.Cloud().CheckCWSConnection(c.AppContext.Session().UserId); err == nil {
|
||||
err = c.App.Cloud().SubmitTrueUpReview(c.AppContext.Session().UserId, profileMap)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("requestTrueUpReview", "api.license.true_up_review.failed_to_submit", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Update the review status to reflect the completion.
|
||||
status.Completed = true
|
||||
c.App.Srv().Store().TrueUpReview().Update(status)
|
||||
|
||||
// Encode to string rather than byte[] otherwise json.Marshal will encode it further.
|
||||
encodedData := b64.StdEncoding.EncodeToString(profileMapJson)
|
||||
responseContent := struct {
|
||||
Content string `json:"content"`
|
||||
}{Content: encodedData}
|
||||
response, _ := json.Marshal(responseContent)
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(response)
|
||||
}
|
||||
|
||||
func trueUpReviewStatus(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
// Only admins can request a true up review.
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) {
|
||||
c.SetPermissionError(model.PermissionManageLicenseInformation)
|
||||
return
|
||||
}
|
||||
|
||||
// Check for license
|
||||
license := c.App.Channels().License()
|
||||
if license == nil {
|
||||
c.Err = model.NewAppError("cloudTrueUpReviewNotAllowed", "api.license.true_up_review.license_required", nil, "True up review requires a license", http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
|
||||
if license.IsCloud() {
|
||||
c.Err = model.NewAppError("cloudTrueUpReviewNotAllowed", "api.license.true_up_review.not_allowed_for_cloud", nil, "True up review is not allowed for cloud instances", http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
|
||||
status, appErr := c.App.GetOrCreateTrueUpReviewStatus(c.AppContext)
|
||||
if appErr != nil {
|
||||
c.Err = appErr
|
||||
}
|
||||
|
||||
json, err := json.Marshal(status)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("trueUpReviewStatus", "api.marshal_error", nil, "", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(json)
|
||||
}
|
||||
|
||||
@@ -459,116 +459,3 @@ func TestRequestTrialLicense(t *testing.T) {
|
||||
CheckForbiddenStatus(t, resp)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRequestRenewalLink(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
cloudImpl := th.App.Srv().Cloud
|
||||
defer func() {
|
||||
th.App.Srv().Cloud = cloudImpl
|
||||
}()
|
||||
th.App.Srv().Cloud = nil
|
||||
resp, err := th.SystemAdminClient.DoAPIGet(context.Background(), "/license/renewal", "")
|
||||
CheckErrorID(t, err, "app.license.generate_renewal_token.no_license")
|
||||
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRequestTrueUpReview(t *testing.T) {
|
||||
t.Run("returns status 200 when telemetry data sent", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
th.App.Srv().SetLicense(model.NewTestLicense())
|
||||
|
||||
th.Client.Login(context.Background(), th.SystemAdminUser.Email, th.SystemAdminUser.Password)
|
||||
|
||||
cloud := mocks.CloudInterface{}
|
||||
cloud.Mock.On("SubmitTrueUpReview", mock.Anything, mock.Anything).Return(nil)
|
||||
cloud.Mock.On("CheckCWSConnection", mock.Anything).Return(nil)
|
||||
|
||||
cloudImpl := th.App.Srv().Cloud
|
||||
defer func() {
|
||||
th.App.Srv().Cloud = cloudImpl
|
||||
}()
|
||||
th.App.Srv().Cloud = &cloud
|
||||
|
||||
var reviewProfile map[string]any
|
||||
resp, err := th.Client.SubmitTrueUpReview(context.Background(), reviewProfile)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("returns 501 when ran by cloud user", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
th.App.Srv().SetLicense(model.NewTestLicense())
|
||||
|
||||
th.App.Srv().SetLicense(model.NewTestLicense("cloud"))
|
||||
|
||||
resp, err := th.SystemAdminClient.DoAPIPost(context.Background(), "/license/review", "")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
|
||||
|
||||
th.App.Srv().SetLicense(model.NewTestLicense())
|
||||
})
|
||||
|
||||
t.Run("returns 403 when user does not have permissions", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
th.App.Srv().SetLicense(model.NewTestLicense())
|
||||
|
||||
resp, err := th.Client.DoAPIPost(context.Background(), "/license/review", "")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, http.StatusForbidden, resp.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("returns 400 when license is nil", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
th.App.Srv().SetLicense(nil)
|
||||
|
||||
resp, err := th.SystemAdminClient.DoAPIPost(context.Background(), "/license/review", "")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTrueUpReviewStatus(t *testing.T) {
|
||||
th := Setup(t)
|
||||
|
||||
defer th.TearDown()
|
||||
th.App.Srv().SetLicense(model.NewTestLicense())
|
||||
|
||||
t.Run("returns 200 when status retrieved", func(t *testing.T) {
|
||||
resp, err := th.SystemAdminClient.DoAPIGet(context.Background(), "/license/review/status", "")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("returns 501 when ran by cloud user", func(t *testing.T) {
|
||||
th.App.Srv().SetLicense(model.NewTestLicense("cloud"))
|
||||
|
||||
resp, err := th.SystemAdminClient.DoAPIGet(context.Background(), "/license/review/status", "")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
|
||||
|
||||
th.App.Srv().SetLicense(model.NewTestLicense())
|
||||
})
|
||||
|
||||
t.Run("returns 403 when user does not have permissions", func(t *testing.T) {
|
||||
resp, err := th.Client.DoAPIGet(context.Background(), "/license/review/status", "")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, http.StatusForbidden, resp.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("returns 400 when license is nil", func(t *testing.T) {
|
||||
th.App.Srv().SetLicense(nil)
|
||||
|
||||
resp, err := th.SystemAdminClient.DoAPIGet(context.Background(), "/license/review/status", "")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
|
||||
})
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user