[CLD-6678] Various improvements for IP filtering feature (#25485)
* Add GetInstallation function, allow IP Filtering page to fetch installation state, other fixes for IP filter feature * Fix pipelines * Run make build-templates * Fixing i18n * Fix openapi docs * Fix openapi docs again * make build-templates * Update test to ensure that spinner is removed after installation becomes stable * Fix types, style * update openapi because I can't validate locally... * Updates according to Matt's feedback * Add a limit to number of times installation is requested before an error is displayed * Make button disable immediately * Updates based on PR feedback * A couple missed occurrences of whitespace * Grammar fix in failed to fetch error --------- Co-authored-by: Gabe Jackson <3694686+gabrieljackson@users.noreply.github.com> Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
@@ -54,6 +54,9 @@ func (api *API) InitCloud() {
|
||||
// POST /api/v4/cloud/webhook
|
||||
api.BaseRoutes.Cloud.Handle("/webhook", api.CloudAPIKeyRequired(handleCWSWebhook)).Methods("POST")
|
||||
|
||||
// GET /api/v4/cloud/installation
|
||||
api.BaseRoutes.Cloud.Handle("/installation", api.APISessionRequired(getInstallation)).Methods("GET")
|
||||
|
||||
// GET /api/v4/cloud/cws-health-check
|
||||
api.BaseRoutes.Cloud.Handle("/check-cws-connection", api.APIHandler(handleCheckCWSConnection)).Methods("GET")
|
||||
|
||||
@@ -474,6 +477,29 @@ func getCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
w.Write(json)
|
||||
}
|
||||
|
||||
func getInstallation(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
ensured := ensureCloudInterface(c, "Api4.getInstallation")
|
||||
if !ensured {
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleReadIPFilters) {
|
||||
c.SetPermissionError(model.PermissionSysconsoleReadIPFilters)
|
||||
return
|
||||
}
|
||||
|
||||
installation, err := c.App.Cloud().GetInstallation(c.AppContext.Session().UserId)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("Api4.getInstallation", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(installation); err != nil {
|
||||
c.Err = model.NewAppError("Api4.getInstallation", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 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")
|
||||
|
||||
@@ -56,4 +56,5 @@ type CloudInterface interface {
|
||||
|
||||
ApplyIPFilters(userID string, ranges *model.AllowedIPRanges) (*model.AllowedIPRanges, error)
|
||||
GetIPFilters(userID string) (*model.AllowedIPRanges, error)
|
||||
GetInstallation(userID string) (*model.Installation, error)
|
||||
}
|
||||
|
||||
@@ -395,6 +395,32 @@ func (_m *CloudInterface) GetIPFilters(userID string) (*model.AllowedIPRanges, e
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetInstallation provides a mock function with given fields: userID
|
||||
func (_m *CloudInterface) GetInstallation(userID string) (*model.Installation, error) {
|
||||
ret := _m.Called(userID)
|
||||
|
||||
var r0 *model.Installation
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(string) (*model.Installation, error)); ok {
|
||||
return rf(userID)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(string) *model.Installation); ok {
|
||||
r0 = rf(userID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Installation)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(userID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetInvoicePDF provides a mock function with given fields: userID, invoiceID
|
||||
func (_m *CloudInterface) GetInvoicePDF(userID string, invoiceID string) ([]byte, string, error) {
|
||||
ret := _m.Called(userID, invoiceID)
|
||||
|
||||
@@ -301,6 +301,12 @@ type CreateSubscriptionRequest struct {
|
||||
DiscountID string `json:"discount_id"`
|
||||
}
|
||||
|
||||
type Installation struct {
|
||||
ID string `json:"id"`
|
||||
State string `json:"state"`
|
||||
AllowedIPRanges *AllowedIPRanges `json:"allowed_ip_ranges"`
|
||||
}
|
||||
|
||||
type Feedback struct {
|
||||
Reason string `json:"reason"`
|
||||
Comments string `json:"comments"`
|
||||
|
||||
@@ -367,7 +367,7 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width:132px;">
|
||||
<img alt height="21" src="{{.Props.SiteURL}}/static/images/logo_email_dark.png" style="border:0;display:block;outline:none;text-decoration:none;height:21.76px;width:100%;font-size:13px;" width="132">
|
||||
<img alt height="21" src="{{.Props.PortalURL}}/static/images/logo_email_dark.png" style="border:0;display:block;outline:none;text-decoration:none;height:21.76px;width:100%;font-size:13px;" width="132">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -441,7 +441,7 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width:312px;">
|
||||
<img alt height="auto" src="{{.Props.SiteURL}}/static/images/forgot_password_illustration.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" width="312">
|
||||
<img alt height="auto" src="{{.Props.PortalURL}}/static/images/forgot_password_illustration.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" width="312">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -4,32 +4,35 @@
|
||||
</mj-head>
|
||||
<mj-body css-class="emailBody" background-color="#FFFFFF">
|
||||
<mj-wrapper mj-class="email">
|
||||
<mj-include path="./partials/logo.mjml" />
|
||||
<mj-section padding="0px 0px 40px 0px">
|
||||
<mj-column>
|
||||
<mj-image mj-class="logo" src="{{.Props.PortalURL}}/static/images/logo_email_dark.png" />
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-include path="./partials/header.mjml" />
|
||||
<mj-section padding="0px">
|
||||
<mj-column>
|
||||
<mj-image src="{{.Props.SiteURL}}/static/images/forgot_password_illustration.png" width="312px"
|
||||
padding="0px" />
|
||||
<mj-image src="{{.Props.PortalURL}}/static/images/forgot_password_illustration.png" width="312px" padding="0px" />
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section padding="40px 0px 40px 0px">
|
||||
<mj-column>
|
||||
<mj-text padding-bottom="9px" css-class="footerTitle" padding="0px">
|
||||
{{.Props.TroubleAccessingTitle}}
|
||||
{{.Props.TroubleAccessingTitle}}
|
||||
</mj-text>
|
||||
<mj-raw>{{if .Props.ActorEmail}}</mj-raw>
|
||||
<mj-button padding-top="0px" padding-bottom="1px" font-size="14px" line-height="20px" background-color="transparent" color="#1C58D9" href="mailto:{{.Props.ActorEmail}}">
|
||||
{{.Props.SendAnEmailTo}}
|
||||
</mj-button>
|
||||
<mj-divider padding="0" css-class="divider" width="313px" border-width="1px" border-color="#3F4350"/>
|
||||
<mj-divider padding="0" css-class="divider" width="313px" border-width="1px" border-color="#3F4350" />
|
||||
<mj-raw>{{end}}</mj-raw>
|
||||
<mj-raw>{{ if .Props.LogInToCustomerPortal}}</mj-raw>
|
||||
<mj-button padding-top="6px" padding-bottom="1px" font-size="14px" line-height="20px" background-color="transparent" color="#1C58D9" href="{{.Props.PortalURL}}/console/cloud/ip-filtering">
|
||||
<mj-button padding-top="6px" padding-bottom="1px" font-size="14px" line-height="20px" background-color="transparent" color="#1C58D9" href="{{.Props.PortalURL}}/console/cloud/ip-filtering">
|
||||
{{.Props.LogInToCustomerPortal}}
|
||||
</mj-button>
|
||||
<mj-divider padding="0px" css-class="divider" width="313px" border-width="1px" border-color="#3F4350"/>
|
||||
<mj-divider padding="0px" css-class="divider" width="313px" border-width="1px" border-color="#3F4350" />
|
||||
<mj-raw>{{end}}</mj-raw>
|
||||
<mj-button padding-top="6px" font-size="14px" line-height="20px" background-color="transparent" color="#1C58D9" href="mailto:{{.Props.SupportEmail}}">
|
||||
<mj-button padding-top="6px" font-size="14px" line-height="20px" background-color="transparent" color="#1C58D9" href="mailto:{{.Props.SupportEmail}}">
|
||||
{{.Props.ContactSupport}}
|
||||
</mj-button>
|
||||
</mj-column>
|
||||
|
||||
Ссылка в новой задаче
Block a user