From 8d686411eef338697e1a122b51336d46aca4a498 Mon Sep 17 00:00:00 2001 From: Yaodong Yu <2814461814@qq.com> Date: Fri, 4 Nov 2022 21:31:08 +0800 Subject: [PATCH] feat: support add providers inside the Organization scope (#1250) * feat: support add providers inside the Organization scope Signed-off-by: magicwind <2814461814@qq.com> * Update ProviderListPage.js * fix: gloabal admin can see all providers * fix: table fixed column warning * fix: edit application page can get all providers Signed-off-by: magicwind <2814461814@qq.com> Co-authored-by: hsluoyz --- controllers/provider.go | 24 +++++++++++ object/provider.go | 33 ++++++++++++++- routers/router.go | 1 + web/src/AdapterListPage.js | 30 +++++++------- web/src/App.js | 15 +++---- web/src/ApplicationEditPage.js | 20 ++++++--- web/src/ModelListPage.js | 30 +++++++------- web/src/PaymentListPage.js | 65 +++++++++++++++--------------- web/src/PermissionListPage.js | 31 +++++++------- web/src/ProviderEditPage.js | 3 +- web/src/ProviderListPage.js | 24 +++++++++-- web/src/RoleListPage.js | 30 +++++++------- web/src/SyncerListPage.js | 30 +++++++------- web/src/WebhookListPage.js | 30 +++++++------- web/src/backend/ProviderBackend.js | 10 +++++ 15 files changed, 236 insertions(+), 140 deletions(-) diff --git a/controllers/provider.go b/controllers/provider.go index 20b98b4f..a6a1636f 100644 --- a/controllers/provider.go +++ b/controllers/provider.go @@ -48,6 +48,30 @@ func (c *ApiController) GetProviders() { } } +// GetGlobalProviders +// @Title GetGlobalProviders +// @Tag Provider API +// @Description get Global providers +// @Success 200 {array} object.Provider The Response object +// @router /get-global-providers [get] +func (c *ApiController) GetGlobalProviders() { + limit := c.Input().Get("pageSize") + page := c.Input().Get("p") + field := c.Input().Get("field") + value := c.Input().Get("value") + sortField := c.Input().Get("sortField") + sortOrder := c.Input().Get("sortOrder") + if limit == "" || page == "" { + c.Data["json"] = object.GetMaskedProviders(object.GetGlobalProviders()) + c.ServeJSON() + } else { + limit := util.ParseInt(limit) + paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetGlobalProviderCount(field, value))) + providers := object.GetMaskedProviders(object.GetPaginationGlobalProviders(paginator.Offset(), limit, field, value, sortField, sortOrder)) + c.ResponseOk(providers, paginator.Nums()) + } +} + // GetProvider // @Title GetProvider // @Tag Provider API diff --git a/object/provider.go b/object/provider.go index ef30894e..5007e486 100644 --- a/object/provider.go +++ b/object/provider.go @@ -102,6 +102,16 @@ func GetProviderCount(owner, field, value string) int { return int(count) } +func GetGlobalProviderCount(field, value string) int { + session := GetSession("", -1, -1, field, value, "", "") + count, err := session.Count(&Provider{}) + if err != nil { + panic(err) + } + + return int(count) +} + func GetProviders(owner string) []*Provider { providers := []*Provider{} err := adapter.Engine.Desc("created_time").Find(&providers, &Provider{Owner: owner}) @@ -112,8 +122,18 @@ func GetProviders(owner string) []*Provider { return providers } -func GetPaginationProviders(owner string, offset, limit int, field, value, sortField, sortOrder string) []*Provider { +func GetGlobalProviders() []*Provider { providers := []*Provider{} + err := adapter.Engine.Desc("created_time").Find(&providers) + if err != nil { + panic(err) + } + + return providers +} + +func GetPaginationProviders(owner string, offset, limit int, field, value, sortField, sortOrder string) []*Provider { + var providers []*Provider session := GetSession(owner, offset, limit, field, value, sortField, sortOrder) err := session.Find(&providers) if err != nil { @@ -123,6 +143,17 @@ func GetPaginationProviders(owner string, offset, limit int, field, value, sortF return providers } +func GetPaginationGlobalProviders(offset, limit int, field, value, sortField, sortOrder string) []*Provider { + var providers []*Provider + session := GetSession("", offset, limit, field, value, sortField, sortOrder) + err := session.Find(&providers) + if err != nil { + panic(err) + } + + return providers +} + func getProvider(owner string, name string) *Provider { if owner == "" || name == "" { return nil diff --git a/routers/router.go b/routers/router.go index e4d04b0c..2b662b9d 100644 --- a/routers/router.go +++ b/routers/router.go @@ -123,6 +123,7 @@ func initAPI() { beego.Router("/api/get-providers", &controllers.ApiController{}, "GET:GetProviders") beego.Router("/api/get-provider", &controllers.ApiController{}, "GET:GetProvider") + beego.Router("/api/get-global-providers", &controllers.ApiController{}, "GET:GetGlobalProviders") beego.Router("/api/update-provider", &controllers.ApiController{}, "POST:UpdateProvider") beego.Router("/api/add-provider", &controllers.ApiController{}, "POST:AddProvider") beego.Router("/api/delete-provider", &controllers.ApiController{}, "POST:DeleteProvider") diff --git a/web/src/AdapterListPage.js b/web/src/AdapterListPage.js index 0c45e064..09f653b7 100644 --- a/web/src/AdapterListPage.js +++ b/web/src/AdapterListPage.js @@ -70,21 +70,6 @@ class AdapterListPage extends BaseListPage { renderTable(adapters) { const columns = [ - { - title: i18next.t("general:Organization"), - dataIndex: "organization", - key: "organization", - width: "120px", - sorter: true, - ...this.getColumnSearchProps("organization"), - render: (text, record, index) => { - return ( - - {text} - - ); - }, - }, { title: i18next.t("general:Name"), dataIndex: "name", @@ -101,6 +86,21 @@ class AdapterListPage extends BaseListPage { ); }, }, + { + title: i18next.t("general:Organization"), + dataIndex: "organization", + key: "organization", + width: "120px", + sorter: true, + ...this.getColumnSearchProps("organization"), + render: (text, record, index) => { + return ( + + {text} + + ); + }, + }, { title: i18next.t("general:Created time"), dataIndex: "createdTime", diff --git a/web/src/App.js b/web/src/App.js index 97525368..7b26dd69 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -420,13 +420,6 @@ class App extends Component { ); - res.push( - - - {i18next.t("general:Providers")} - - - ); res.push( @@ -437,6 +430,13 @@ class App extends Component { } if (Setting.isLocalAdminUser(this.state.account)) { + res.push( + + + {i18next.t("general:Providers")} + + + ); res.push( @@ -566,6 +566,7 @@ class App extends Component { this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> + this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> diff --git a/web/src/ApplicationEditPage.js b/web/src/ApplicationEditPage.js index 01052923..c8db477a 100644 --- a/web/src/ApplicationEditPage.js +++ b/web/src/ApplicationEditPage.js @@ -91,6 +91,7 @@ class ApplicationEditPage extends React.Component { super(props); this.state = { classes: props, + owner: props.account.owner, applicationName: props.match.params.applicationName, application: null, organizations: [], @@ -141,12 +142,21 @@ class ApplicationEditPage extends React.Component { } getProviders() { - ProviderBackend.getProviders("admin") - .then((res) => { - this.setState({ - providers: res, + if (Setting.isAdminUser(this.props.account)) { + ProviderBackend.getGlobalProviders() + .then((res) => { + this.setState({ + providers: res, + }); }); - }); + } else { + ProviderBackend.getProviders(this.state.owner) + .then((res) => { + this.setState({ + providers: res, + }); + }); + } } getSamlMetadata() { diff --git a/web/src/ModelListPage.js b/web/src/ModelListPage.js index a674ae53..c00c7cf0 100644 --- a/web/src/ModelListPage.js +++ b/web/src/ModelListPage.js @@ -63,21 +63,6 @@ class ModelListPage extends BaseListPage { renderTable(models) { const columns = [ - { - title: i18next.t("general:Organization"), - dataIndex: "owner", - key: "owner", - width: "120px", - sorter: true, - ...this.getColumnSearchProps("owner"), - render: (text, record, index) => { - return ( - - {text} - - ); - }, - }, { title: i18next.t("general:Name"), dataIndex: "name", @@ -94,6 +79,21 @@ class ModelListPage extends BaseListPage { ); }, }, + { + title: i18next.t("general:Organization"), + dataIndex: "owner", + key: "owner", + width: "120px", + sorter: true, + ...this.getColumnSearchProps("owner"), + render: (text, record, index) => { + return ( + + {text} + + ); + }, + }, { title: i18next.t("general:Created time"), dataIndex: "createdTime", diff --git a/web/src/PaymentListPage.js b/web/src/PaymentListPage.js index acef20dc..451c42d1 100644 --- a/web/src/PaymentListPage.js +++ b/web/src/PaymentListPage.js @@ -76,6 +76,38 @@ class PaymentListPage extends BaseListPage { renderTable(payments) { const columns = [ + { + title: i18next.t("general:Name"), + dataIndex: "name", + key: "name", + width: "180px", + fixed: "left", + sorter: true, + ...this.getColumnSearchProps("name"), + render: (text, record, index) => { + return ( + + {text} + + ); + }, + }, + { + title: i18next.t("general:Provider"), + dataIndex: "provider", + key: "provider", + width: "150px", + fixed: "left", + sorter: true, + ...this.getColumnSearchProps("provider"), + render: (text, record, index) => { + return ( + + {text} + + ); + }, + }, { title: i18next.t("general:Organization"), dataIndex: "organization", @@ -106,22 +138,7 @@ class PaymentListPage extends BaseListPage { ); }, }, - { - title: i18next.t("general:Name"), - dataIndex: "name", - key: "name", - width: "180px", - fixed: "left", - sorter: true, - ...this.getColumnSearchProps("name"), - render: (text, record, index) => { - return ( - - {text} - - ); - }, - }, + { title: i18next.t("general:Created time"), dataIndex: "createdTime", @@ -140,22 +157,6 @@ class PaymentListPage extends BaseListPage { // sorter: true, // ...this.getColumnSearchProps('displayName'), // }, - { - title: i18next.t("general:Provider"), - dataIndex: "provider", - key: "provider", - width: "150px", - fixed: "left", - sorter: true, - ...this.getColumnSearchProps("provider"), - render: (text, record, index) => { - return ( - - {text} - - ); - }, - }, { title: i18next.t("payment:Type"), dataIndex: "type", diff --git a/web/src/PermissionListPage.js b/web/src/PermissionListPage.js index 45ad468a..ce5a9a2d 100644 --- a/web/src/PermissionListPage.js +++ b/web/src/PermissionListPage.js @@ -77,21 +77,7 @@ class PermissionListPage extends BaseListPage { renderTable(permissions) { const columns = [ - { - title: i18next.t("general:Organization"), - dataIndex: "owner", - key: "owner", - width: "120px", - sorter: true, - ...this.getColumnSearchProps("owner"), - render: (text, record, index) => { - return ( - - {text} - - ); - }, - }, + // https://github.com/ant-design/ant-design/issues/22184 { title: i18next.t("general:Name"), dataIndex: "name", @@ -108,6 +94,21 @@ class PermissionListPage extends BaseListPage { ); }, }, + { + title: i18next.t("general:Organization"), + dataIndex: "owner", + key: "owner", + width: "120px", + sorter: true, + ...this.getColumnSearchProps("owner"), + render: (text, record, index) => { + return ( + + {text} + + ); + }, + }, { title: i18next.t("general:Created time"), dataIndex: "createdTime", diff --git a/web/src/ProviderEditPage.js b/web/src/ProviderEditPage.js index ea04cc79..8aeb8512 100644 --- a/web/src/ProviderEditPage.js +++ b/web/src/ProviderEditPage.js @@ -32,6 +32,7 @@ class ProviderEditPage extends React.Component { this.state = { classes: props, providerName: props.match.params.providerName, + owner: props.organizationName !== undefined ? props.organizationName : props.match.params.organizationName, provider: null, mode: props.location.mode !== undefined ? props.location.mode : "edit", }; @@ -42,7 +43,7 @@ class ProviderEditPage extends React.Component { } getProvider() { - ProviderBackend.getProvider("admin", this.state.providerName) + ProviderBackend.getProvider(this.state.owner, this.state.providerName) .then((provider) => { this.setState({ provider: provider, diff --git a/web/src/ProviderListPage.js b/web/src/ProviderListPage.js index 295a9e68..f9ddf74e 100644 --- a/web/src/ProviderListPage.js +++ b/web/src/ProviderListPage.js @@ -23,10 +23,25 @@ import i18next from "i18next"; import BaseListPage from "./BaseListPage"; class ProviderListPage extends BaseListPage { + constructor(props) { + super(props); + this.state = { + classes: props, + owner: Setting.isAdminUser(props.account) ? "admin" : props.account.organization.name, + data: [], + pagination: { + current: 1, + pageSize: 10, + }, + loading: false, + searchText: "", + searchedColumn: "", + }; + } newProvider() { const randomName = Setting.getRandomName(); return { - owner: "admin", // this.props.account.providername, + owner: this.state.owner, name: `provider_${randomName}`, createdTime: moment().format(), displayName: `New Provider - ${randomName}`, @@ -46,7 +61,7 @@ class ProviderListPage extends BaseListPage { const newProvider = this.newProvider(); ProviderBackend.addProvider(newProvider) .then((res) => { - this.props.history.push({pathname: `/providers/${newProvider.name}`, mode: "add"}); + this.props.history.push({pathname: `/providers/${newProvider.owner}/${newProvider.name}`, mode: "add"}); } ) .catch(error => { @@ -177,7 +192,7 @@ class ProviderListPage extends BaseListPage { render: (text, record, index) => { return (
- + this.deleteProvider(index)} @@ -224,7 +239,8 @@ class ProviderListPage extends BaseListPage { value = params.type; } this.setState({loading: true}); - ProviderBackend.getProviders("admin", params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) + (Setting.isAdminUser(this.props.account) ? ProviderBackend.getGlobalProviders(params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) + : ProviderBackend.getProviders(this.state.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)) .then((res) => { if (res.status === "ok") { this.setState({ diff --git a/web/src/RoleListPage.js b/web/src/RoleListPage.js index 58b8ecba..838d84ec 100644 --- a/web/src/RoleListPage.js +++ b/web/src/RoleListPage.js @@ -65,21 +65,6 @@ class RoleListPage extends BaseListPage { renderTable(roles) { const columns = [ - { - title: i18next.t("general:Organization"), - dataIndex: "owner", - key: "owner", - width: "120px", - sorter: true, - ...this.getColumnSearchProps("owner"), - render: (text, record, index) => { - return ( - - {text} - - ); - }, - }, { title: i18next.t("general:Name"), dataIndex: "name", @@ -96,6 +81,21 @@ class RoleListPage extends BaseListPage { ); }, }, + { + title: i18next.t("general:Organization"), + dataIndex: "owner", + key: "owner", + width: "120px", + sorter: true, + ...this.getColumnSearchProps("owner"), + render: (text, record, index) => { + return ( + + {text} + + ); + }, + }, { title: i18next.t("general:Created time"), dataIndex: "createdTime", diff --git a/web/src/SyncerListPage.js b/web/src/SyncerListPage.js index 21e14246..5b0538a7 100644 --- a/web/src/SyncerListPage.js +++ b/web/src/SyncerListPage.js @@ -88,21 +88,6 @@ class SyncerListPage extends BaseListPage { renderTable(syncers) { const columns = [ - { - title: i18next.t("general:Organization"), - dataIndex: "organization", - key: "organization", - width: "120px", - sorter: true, - ...this.getColumnSearchProps("organization"), - render: (text, record, index) => { - return ( - - {text} - - ); - }, - }, { title: i18next.t("general:Name"), dataIndex: "name", @@ -119,6 +104,21 @@ class SyncerListPage extends BaseListPage { ); }, }, + { + title: i18next.t("general:Organization"), + dataIndex: "organization", + key: "organization", + width: "120px", + sorter: true, + ...this.getColumnSearchProps("organization"), + render: (text, record, index) => { + return ( + + {text} + + ); + }, + }, { title: i18next.t("general:Created time"), dataIndex: "createdTime", diff --git a/web/src/WebhookListPage.js b/web/src/WebhookListPage.js index 2ea9ac9f..5679af98 100644 --- a/web/src/WebhookListPage.js +++ b/web/src/WebhookListPage.js @@ -67,21 +67,6 @@ class WebhookListPage extends BaseListPage { renderTable(webhooks) { const columns = [ - { - title: i18next.t("general:Organization"), - dataIndex: "organization", - key: "organization", - width: "110px", - sorter: true, - ...this.getColumnSearchProps("organization"), - render: (text, record, index) => { - return ( - - {text} - - ); - }, - }, { title: i18next.t("general:Name"), dataIndex: "name", @@ -98,6 +83,21 @@ class WebhookListPage extends BaseListPage { ); }, }, + { + title: i18next.t("general:Organization"), + dataIndex: "organization", + key: "organization", + width: "110px", + sorter: true, + ...this.getColumnSearchProps("organization"), + render: (text, record, index) => { + return ( + + {text} + + ); + }, + }, { title: i18next.t("general:Created time"), dataIndex: "createdTime", diff --git a/web/src/backend/ProviderBackend.js b/web/src/backend/ProviderBackend.js index 9fe5db3c..75495b06 100644 --- a/web/src/backend/ProviderBackend.js +++ b/web/src/backend/ProviderBackend.js @@ -24,6 +24,16 @@ export function getProviders(owner, page = "", pageSize = "", field = "", value }).then(res => res.json()); } +export function getGlobalProviders(page = "", pageSize = "", field = "", value = "", sortField = "", sortOrder = "") { + return fetch(`${Setting.ServerUrl}/api/get-global-providers?p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, { + method: "GET", + credentials: "include", + headers: { + "Accept-Language": Setting.getAcceptLanguage(), + }, + }).then(res => res.json()); +} + export function getProvider(owner, name) { return fetch(`${Setting.ServerUrl}/api/get-provider?id=${owner}/${encodeURIComponent(name)}`, { method: "GET",