Add trial license api (#14603)
* Initial request trial api creation * Adding test license public certificate * Adding go client method * Applying changes to use production environment * Removing accidentally added strings Co-authored-by: mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
1c9891c65e
Коммит
e0edd2bebb
@@ -5,7 +5,9 @@ package api4
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/v5/audit"
|
"github.com/mattermost/mattermost-server/v5/audit"
|
||||||
@@ -13,6 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (api *API) InitLicense() {
|
func (api *API) InitLicense() {
|
||||||
|
api.BaseRoutes.ApiRoot.Handle("/trial-license", api.ApiSessionRequired(requestTrialLicense)).Methods("POST")
|
||||||
api.BaseRoutes.ApiRoot.Handle("/license", api.ApiSessionRequired(addLicense)).Methods("POST")
|
api.BaseRoutes.ApiRoot.Handle("/license", api.ApiSessionRequired(addLicense)).Methods("POST")
|
||||||
api.BaseRoutes.ApiRoot.Handle("/license", api.ApiSessionRequired(removeLicense)).Methods("DELETE")
|
api.BaseRoutes.ApiRoot.Handle("/license", api.ApiSessionRequired(removeLicense)).Methods("DELETE")
|
||||||
api.BaseRoutes.ApiRoot.Handle("/license/client", api.ApiHandler(getClientLicense)).Methods("GET")
|
api.BaseRoutes.ApiRoot.Handle("/license/client", api.ApiHandler(getClientLicense)).Methods("GET")
|
||||||
@@ -138,3 +141,59 @@ func removeLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
ReturnStatusOK(w)
|
ReturnStatusOK(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func requestTrialLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
auditRec := c.MakeAuditRecord("requestTrialLicense", audit.Fail)
|
||||||
|
defer c.LogAuditRec(auditRec)
|
||||||
|
c.LogAudit("attempt")
|
||||||
|
|
||||||
|
if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
|
||||||
|
c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||||
|
c.Err = model.NewAppError("removeLicense", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var usersNumber struct {
|
||||||
|
Users int `json:"users"`
|
||||||
|
}
|
||||||
|
|
||||||
|
b, readErr := ioutil.ReadAll(r.Body)
|
||||||
|
if readErr != nil {
|
||||||
|
c.Err = model.NewAppError("removeLicense", "api.license.request-trial.bad-request", nil, "", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
json.Unmarshal(b, &usersNumber)
|
||||||
|
if usersNumber.Users == 0 {
|
||||||
|
c.Err = model.NewAppError("removeLicense", "api.license.request-trial.bad-request", nil, "", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
currentUser, err := c.App.GetUser(c.App.Session().UserId)
|
||||||
|
if err != nil {
|
||||||
|
c.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
trialLicenseRequest := &model.TrialLicenseRequest{
|
||||||
|
ServerID: c.App.DiagnosticId(),
|
||||||
|
Name: currentUser.GetDisplayName(model.SHOW_FULLNAME),
|
||||||
|
Email: currentUser.Email,
|
||||||
|
SiteName: *c.App.Config().TeamSettings.SiteName,
|
||||||
|
SiteURL: *c.App.Config().ServiceSettings.SiteURL,
|
||||||
|
Users: usersNumber.Users,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.App.RequestTrialLicense(trialLicenseRequest); err != nil {
|
||||||
|
c.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
auditRec.Success()
|
||||||
|
c.LogAudit("success")
|
||||||
|
|
||||||
|
ReturnStatusOK(w)
|
||||||
|
}
|
||||||
|
|||||||
@@ -253,6 +253,8 @@ type AppIface interface {
|
|||||||
RenameChannel(channel *model.Channel, newChannelName string, newDisplayName string) (*model.Channel, *model.AppError)
|
RenameChannel(channel *model.Channel, newChannelName string, newDisplayName string) (*model.Channel, *model.AppError)
|
||||||
// RenameTeam is used to rename the team Name and the DisplayName fields
|
// RenameTeam is used to rename the team Name and the DisplayName fields
|
||||||
RenameTeam(team *model.Team, newTeamName string, newDisplayName string) (*model.Team, *model.AppError)
|
RenameTeam(team *model.Team, newTeamName string, newDisplayName string) (*model.Team, *model.AppError)
|
||||||
|
// RequestTrialLicense request a trial license from the mattermost offical license server
|
||||||
|
RequestTrialLicense(trialRequest *model.TrialLicenseRequest) *model.AppError
|
||||||
// RevokeSessionsFromAllUsers will go through all the sessions active
|
// RevokeSessionsFromAllUsers will go through all the sessions active
|
||||||
// in the server and revoke them
|
// in the server and revoke them
|
||||||
RevokeSessionsFromAllUsers() *model.AppError
|
RevokeSessionsFromAllUsers() *model.AppError
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -12,6 +13,8 @@ import (
|
|||||||
"github.com/mattermost/mattermost-server/v5/utils"
|
"github.com/mattermost/mattermost-server/v5/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const requestTrialURL = "https://customers.mattermost.com/api/v1/trials"
|
||||||
|
|
||||||
func (a *App) LoadLicense() {
|
func (a *App) LoadLicense() {
|
||||||
licenseId := ""
|
licenseId := ""
|
||||||
props, err := a.Srv().Store.System().Get()
|
props, err := a.Srv().Store.System().Get()
|
||||||
@@ -214,3 +217,22 @@ func (a *App) GetSanitizedClientLicense() map[string]string {
|
|||||||
|
|
||||||
return sanitizedLicense
|
return sanitizedLicense
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RequestTrialLicense request a trial license from the mattermost offical license server
|
||||||
|
func (a *App) RequestTrialLicense(trialRequest *model.TrialLicenseRequest) *model.AppError {
|
||||||
|
resp, err := http.Post(requestTrialURL, "application/json", bytes.NewBuffer([]byte(trialRequest.ToJson())))
|
||||||
|
if err != nil {
|
||||||
|
return model.NewAppError("RequestTrialLicense", "api.license.request_trial_license.app_error", nil, err.Error(), http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
licenseResponse := model.MapFromJson(resp.Body)
|
||||||
|
|
||||||
|
if _, err := a.SaveLicense([]byte(licenseResponse["license"])); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
a.ReloadConfig()
|
||||||
|
a.InvalidateAllCaches()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -11395,6 +11395,28 @@ func (a *OpenTracingAppLayer) RenameTeam(team *model.Team, newTeamName string, n
|
|||||||
return resultVar0, resultVar1
|
return resultVar0, resultVar1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *OpenTracingAppLayer) RequestTrialLicense(trialRequest *model.TrialLicenseRequest) *model.AppError {
|
||||||
|
origCtx := a.ctx
|
||||||
|
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.RequestTrialLicense")
|
||||||
|
|
||||||
|
a.ctx = newCtx
|
||||||
|
a.app.Srv().Store.SetContext(newCtx)
|
||||||
|
defer func() {
|
||||||
|
a.app.Srv().Store.SetContext(origCtx)
|
||||||
|
a.ctx = origCtx
|
||||||
|
}()
|
||||||
|
|
||||||
|
defer span.Finish()
|
||||||
|
resultVar0 := a.app.RequestTrialLicense(trialRequest)
|
||||||
|
|
||||||
|
if resultVar0 != nil {
|
||||||
|
span.LogFields(spanlog.Error(resultVar0))
|
||||||
|
ext.Error.Set(span, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultVar0
|
||||||
|
}
|
||||||
|
|
||||||
func (a *OpenTracingAppLayer) ResetPasswordFromToken(userSuppliedTokenString string, newPassword string) *model.AppError {
|
func (a *OpenTracingAppLayer) ResetPasswordFromToken(userSuppliedTokenString string, newPassword string) *model.AppError {
|
||||||
origCtx := a.ctx
|
origCtx := a.ctx
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.ResetPasswordFromToken")
|
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.ResetPasswordFromToken")
|
||||||
|
|||||||
@@ -1488,6 +1488,14 @@
|
|||||||
"id": "api.license.remove_expired_license.failed.error",
|
"id": "api.license.remove_expired_license.failed.error",
|
||||||
"translation": "Failed to send the disable license email successfully."
|
"translation": "Failed to send the disable license email successfully."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "api.license.request-trial.bad-request",
|
||||||
|
"translation": "The number of users requested is not correct."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "api.license.request_trial_license.app_error",
|
||||||
|
"translation": "Unable to get a trial license, please try again or contact with support@mattermost.com."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "api.marshal_error",
|
"id": "api.marshal_error",
|
||||||
"translation": "marshal error"
|
"translation": "marshal error"
|
||||||
|
|||||||
@@ -5102,3 +5102,14 @@ func (c *Client4) GetChannelMemberCountsByGroup(channelID string, includeTimezon
|
|||||||
defer closeBody(r)
|
defer closeBody(r)
|
||||||
return ChannelMemberCountsByGroupFromJson(r.Body), BuildResponse(r)
|
return ChannelMemberCountsByGroupFromJson(r.Body), BuildResponse(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RequestTrialLicense will request a trial license and install it in the server
|
||||||
|
func (c *Client4) RequestTrialLicense(users int) (bool, *Response) {
|
||||||
|
b, _ := json.Marshal(map[string]int{"users": users})
|
||||||
|
r, err := c.DoApiPost("/trial-license", string(b))
|
||||||
|
if err != nil {
|
||||||
|
return false, BuildErrorResponse(r, err)
|
||||||
|
}
|
||||||
|
defer closeBody(r)
|
||||||
|
return CheckStatusOK(r), BuildResponse(r)
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,6 +40,20 @@ type Customer struct {
|
|||||||
Company string `json:"company"`
|
Company string `json:"company"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TrialLicenseRequest struct {
|
||||||
|
ServerID string `json:"server_id"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
SiteURL string `json:"site_url"`
|
||||||
|
SiteName string `json:"site_name"`
|
||||||
|
Users int `json:"users"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tlr *TrialLicenseRequest) ToJson() string {
|
||||||
|
b, _ := json.Marshal(tlr)
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
type Features struct {
|
type Features struct {
|
||||||
Users *int `json:"users"`
|
Users *int `json:"users"`
|
||||||
LDAP *bool `json:"ldap"`
|
LDAP *bool `json:"ldap"`
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user