Merge pull request #22657 from mattermost/MM-50966-in-product-expansion-backend
MM-50966 - In Product Expansion Backend
Этот коммит содержится в:
@@ -10,7 +10,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -32,6 +31,8 @@ func (api *API) InitHostedCustomer() {
|
|||||||
api.BaseRoutes.HostedCustomer.Handle("/customer", api.APISessionRequired(selfHostedCustomer)).Methods("POST")
|
api.BaseRoutes.HostedCustomer.Handle("/customer", api.APISessionRequired(selfHostedCustomer)).Methods("POST")
|
||||||
// POST /api/v4/hosted_customer/confirm
|
// POST /api/v4/hosted_customer/confirm
|
||||||
api.BaseRoutes.HostedCustomer.Handle("/confirm", api.APISessionRequired(selfHostedConfirm)).Methods("POST")
|
api.BaseRoutes.HostedCustomer.Handle("/confirm", api.APISessionRequired(selfHostedConfirm)).Methods("POST")
|
||||||
|
// POST /api.v4/hosted_customer/confirm-expand
|
||||||
|
api.BaseRoutes.HostedCustomer.Handle("/confirm-expand", api.APISessionRequired(selfHostedConfirmExpand)).Methods("POST")
|
||||||
// GET /api/v4/hosted_customer/invoices
|
// GET /api/v4/hosted_customer/invoices
|
||||||
api.BaseRoutes.HostedCustomer.Handle("/invoices", api.APISessionRequired(selfHostedInvoices)).Methods("GET")
|
api.BaseRoutes.HostedCustomer.Handle("/invoices", api.APISessionRequired(selfHostedInvoices)).Methods("GET")
|
||||||
// GET /api/v4/hosted_customer/invoices/{invoice_id:in_[A-Za-z0-9]+}/pdf
|
// GET /api/v4/hosted_customer/invoices/{invoice_id:in_[A-Za-z0-9]+}/pdf
|
||||||
@@ -172,6 +173,7 @@ func selfHostedConfirm(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
c.Err = userErr
|
c.Err = userErr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmResponse, err := c.App.Cloud().ConfirmSelfHostedSignup(confirm, user.Email)
|
confirmResponse, err := c.App.Cloud().ConfirmSelfHostedSignup(confirm, user.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if confirmResponse != nil {
|
if confirmResponse != nil {
|
||||||
@@ -185,9 +187,8 @@ func selfHostedConfirm(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
license, err := c.App.Srv().Platform().SaveLicense([]byte(confirmResponse.License))
|
license, appErr := c.App.Srv().Platform().SaveLicense([]byte(confirmResponse.License))
|
||||||
// dealing with an AppError
|
if appErr != nil {
|
||||||
if !(reflect.ValueOf(err).Kind() == reflect.Ptr && reflect.ValueOf(err).IsNil()) {
|
|
||||||
if confirmResponse != nil {
|
if confirmResponse != nil {
|
||||||
c.App.NotifySelfHostedSignupProgress(confirmResponse.Progress, user.Id)
|
c.App.NotifySelfHostedSignupProgress(confirmResponse.Progress, user.Id)
|
||||||
}
|
}
|
||||||
@@ -325,3 +326,80 @@ func handleSubscribeToNewsletter(c *Context, w http.ResponseWriter, r *http.Requ
|
|||||||
|
|
||||||
ReturnStatusOK(w)
|
ReturnStatusOK(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func selfHostedConfirmExpand(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
const where = "Api4.selfHostedConfirmExpand"
|
||||||
|
|
||||||
|
ensureSelfHostedAdmin(c, where)
|
||||||
|
if c.Err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !checkSelfHostedPurchaseEnabled(c) {
|
||||||
|
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusNotImplemented)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyBytes, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusBadRequest).Wrap(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var confirm model.SelfHostedConfirmPaymentMethodRequest
|
||||||
|
err = json.Unmarshal(bodyBytes, &confirm)
|
||||||
|
if err != nil {
|
||||||
|
c.Err = model.NewAppError(where, "api.cloud.request_error", nil, "", http.StatusBadRequest).Wrap(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user, userErr := c.App.GetUser(c.AppContext.Session().UserId)
|
||||||
|
if userErr != nil {
|
||||||
|
c.Err = userErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmResponse, err := c.App.Cloud().ConfirmSelfHostedExpansion(confirm, user.Email)
|
||||||
|
if err != nil {
|
||||||
|
if confirmResponse != nil {
|
||||||
|
c.App.NotifySelfHostedSignupProgress(confirmResponse.Progress, user.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err.Error() == fmt.Sprintf("%d", http.StatusUnprocessableEntity) {
|
||||||
|
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusUnprocessableEntity).Wrap(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
license, appErr := c.App.Srv().Platform().SaveLicense([]byte(confirmResponse.License))
|
||||||
|
// dealing with an AppError
|
||||||
|
if appErr != nil {
|
||||||
|
if confirmResponse != nil {
|
||||||
|
c.App.NotifySelfHostedSignupProgress(confirmResponse.Progress, user.Id)
|
||||||
|
}
|
||||||
|
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
clientResponse, err := json.Marshal(model.SelfHostedSignupConfirmClientResponse{
|
||||||
|
License: utils.GetClientLicense(license),
|
||||||
|
Progress: confirmResponse.Progress,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if confirmResponse != nil {
|
||||||
|
c.App.NotifySelfHostedSignupProgress(confirmResponse.Progress, user.Id)
|
||||||
|
}
|
||||||
|
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
err := c.App.Cloud().ConfirmSelfHostedSignupLicenseApplication()
|
||||||
|
if err != nil {
|
||||||
|
c.Logger.Warn("Unable to confirm license application", mlog.Err(err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, _ = w.Write(clientResponse)
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ type CloudInterface interface {
|
|||||||
BootstrapSelfHostedSignup(req model.BootstrapSelfHostedSignupRequest) (*model.BootstrapSelfHostedSignupResponse, error)
|
BootstrapSelfHostedSignup(req model.BootstrapSelfHostedSignupRequest) (*model.BootstrapSelfHostedSignupResponse, error)
|
||||||
CreateCustomerSelfHostedSignup(req model.SelfHostedCustomerForm, requesterEmail string) (*model.SelfHostedSignupCustomerResponse, error)
|
CreateCustomerSelfHostedSignup(req model.SelfHostedCustomerForm, requesterEmail string) (*model.SelfHostedSignupCustomerResponse, error)
|
||||||
ConfirmSelfHostedSignup(req model.SelfHostedConfirmPaymentMethodRequest, requesterEmail string) (*model.SelfHostedSignupConfirmResponse, error)
|
ConfirmSelfHostedSignup(req model.SelfHostedConfirmPaymentMethodRequest, requesterEmail string) (*model.SelfHostedSignupConfirmResponse, error)
|
||||||
|
ConfirmSelfHostedExpansion(req model.SelfHostedConfirmPaymentMethodRequest, requesterEmail string) (*model.SelfHostedSignupConfirmResponse, error)
|
||||||
ConfirmSelfHostedSignupLicenseApplication() error
|
ConfirmSelfHostedSignupLicenseApplication() error
|
||||||
GetSelfHostedInvoices() ([]*model.Invoice, error)
|
GetSelfHostedInvoices() ([]*model.Invoice, error)
|
||||||
GetSelfHostedInvoicePDF(invoiceID string) ([]byte, string, error)
|
GetSelfHostedInvoicePDF(invoiceID string) ([]byte, string, error)
|
||||||
|
|||||||
@@ -94,6 +94,32 @@ func (_m *CloudInterface) ConfirmCustomerPayment(userID string, confirmRequest *
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfirmSelfHostedExpansion provides a mock function with given fields: req, requesterEmail
|
||||||
|
func (_m *CloudInterface) ConfirmSelfHostedExpansion(req model.SelfHostedConfirmPaymentMethodRequest, requesterEmail string) (*model.SelfHostedSignupConfirmResponse, error) {
|
||||||
|
ret := _m.Called(req, requesterEmail)
|
||||||
|
|
||||||
|
var r0 *model.SelfHostedSignupConfirmResponse
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(model.SelfHostedConfirmPaymentMethodRequest, string) (*model.SelfHostedSignupConfirmResponse, error)); ok {
|
||||||
|
return rf(req, requesterEmail)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(model.SelfHostedConfirmPaymentMethodRequest, string) *model.SelfHostedSignupConfirmResponse); ok {
|
||||||
|
r0 = rf(req, requesterEmail)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*model.SelfHostedSignupConfirmResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(model.SelfHostedConfirmPaymentMethodRequest, string) error); ok {
|
||||||
|
r1 = rf(req, requesterEmail)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
// ConfirmSelfHostedSignup provides a mock function with given fields: req, requesterEmail
|
// ConfirmSelfHostedSignup provides a mock function with given fields: req, requesterEmail
|
||||||
func (_m *CloudInterface) ConfirmSelfHostedSignup(req model.SelfHostedConfirmPaymentMethodRequest, requesterEmail string) (*model.SelfHostedSignupConfirmResponse, error) {
|
func (_m *CloudInterface) ConfirmSelfHostedSignup(req model.SelfHostedConfirmPaymentMethodRequest, requesterEmail string) (*model.SelfHostedSignupConfirmResponse, error) {
|
||||||
ret := _m.Called(req, requesterEmail)
|
ret := _m.Called(req, requesterEmail)
|
||||||
|
|||||||
@@ -35,8 +35,9 @@ type SelfHostedCustomerForm struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SelfHostedConfirmPaymentMethodRequest struct {
|
type SelfHostedConfirmPaymentMethodRequest struct {
|
||||||
StripeSetupIntentID string `json:"stripe_setup_intent_id"`
|
StripeSetupIntentID string `json:"stripe_setup_intent_id"`
|
||||||
Subscription CreateSubscriptionRequest `json:"subscription"`
|
Subscription *CreateSubscriptionRequest `json:"subscription"`
|
||||||
|
ExpandRequest *SelfHostedExpansionRequest `json:"expand_request"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelfHostedSignupPaymentResponse contains feels needed for self hosted signup to confirm payment and receive license.
|
// SelfHostedSignupPaymentResponse contains feels needed for self hosted signup to confirm payment and receive license.
|
||||||
@@ -65,3 +66,8 @@ type SelfHostedBillingAccessRequest struct {
|
|||||||
type SelfHostedBillingAccessResponse struct {
|
type SelfHostedBillingAccessResponse struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SelfHostedExpansionRequest struct {
|
||||||
|
Seats int `json:"seats"`
|
||||||
|
LicenseId string `json:"license_id"`
|
||||||
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user