diff --git a/object/application.go b/object/application.go
index b14128eb..3777910d 100644
--- a/object/application.go
+++ b/object/application.go
@@ -24,16 +24,16 @@ type Application struct {
Name string `xorm:"varchar(100) notnull pk" json:"name"`
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
- DisplayName string `xorm:"varchar(100)" json:"displayName"`
- Logo string `xorm:"varchar(100)" json:"logo"`
- HomepageUrl string `xorm:"varchar(100)" json:"homepageUrl"`
- Description string `xorm:"varchar(100)" json:"description"`
- Organization string `xorm:"varchar(100)" json:"organization"`
- EnablePassword bool `json:"enablePassword"`
- EnableSignUp bool `json:"enableSignUp"`
- Providers []string `xorm:"varchar(1000)" json:"providers"`
- ProviderObjs []*Provider `xorm:"-" json:"providerObjs"`
- OrganizationObj *Organization `xorm:"-" json:"organizationObj"`
+ DisplayName string `xorm:"varchar(100)" json:"displayName"`
+ Logo string `xorm:"varchar(100)" json:"logo"`
+ HomepageUrl string `xorm:"varchar(100)" json:"homepageUrl"`
+ Description string `xorm:"varchar(100)" json:"description"`
+ Organization string `xorm:"varchar(100)" json:"organization"`
+ EnablePassword bool `json:"enablePassword"`
+ EnableSignUp bool `json:"enableSignUp"`
+ Providers []ProviderItem `xorm:"varchar(1000)" json:"providers"`
+ ProviderObjs []*Provider `xorm:"-" json:"providerObjs"`
+ OrganizationObj *Organization `xorm:"-" json:"organizationObj"`
ClientId string `xorm:"varchar(100)" json:"clientId"`
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
@@ -68,8 +68,8 @@ func extendApplicationWithProviders(application *Application) {
}
application.ProviderObjs = []*Provider{}
- for _, providerName := range application.Providers {
- if provider, ok := m[providerName]; ok {
+ for _, providerItem := range application.Providers {
+ if provider, ok := m[providerItem.Name]; ok {
application.ProviderObjs = append(application.ProviderObjs, provider)
}
}
@@ -183,8 +183,8 @@ func (application *Application) getProviderByCategory(category string) *Provider
m[provider.Name] = provider
}
- for _, providerName := range application.Providers {
- if provider, ok := m[providerName]; ok {
+ for _, providerItem := range application.Providers {
+ if provider, ok := m[providerItem.Name]; ok {
return provider
}
}
diff --git a/object/init.go b/object/init.go
index e736e585..efca1723 100644
--- a/object/init.go
+++ b/object/init.go
@@ -66,7 +66,7 @@ func initBuiltInApplication() {
Organization: "built-in",
EnablePassword: true,
EnableSignUp: true,
- Providers: []string{},
+ Providers: []ProviderItem{},
RedirectUris: []string{},
ExpireInHours: 168,
}
diff --git a/object/provider.go b/object/provider.go
index bf4f8d9b..27296289 100644
--- a/object/provider.go
+++ b/object/provider.go
@@ -19,6 +19,13 @@ import (
"xorm.io/core"
)
+type ProviderItem struct {
+ Name string `json:"name"`
+ CanSignUp bool `json:"canSignUp"`
+ CanSignIn bool `json:"canSignIn"`
+ CanUnbind bool `json:"canUnbind"`
+}
+
type Provider struct {
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
Name string `xorm:"varchar(100) notnull pk" json:"name"`
diff --git a/web/src/ApplicationEditPage.js b/web/src/ApplicationEditPage.js
index 4240c3ba..202551a3 100644
--- a/web/src/ApplicationEditPage.js
+++ b/web/src/ApplicationEditPage.js
@@ -23,6 +23,7 @@ import SignupPage from "./auth/SignupPage";
import LoginPage from "./auth/LoginPage";
import i18next from "i18next";
import UrlTable from "./UrlTable";
+import ProviderTable from "./ProviderTable";
const { Option } = Select;
@@ -272,15 +273,12 @@ class ApplicationEditPage extends React.Component {
{i18next.t("general:Providers")}:
-
+ { this.updateApplicationField('providers', value)}}
+ />
diff --git a/web/src/ProviderTable.js b/web/src/ProviderTable.js
new file mode 100644
index 00000000..11d0aba6
--- /dev/null
+++ b/web/src/ProviderTable.js
@@ -0,0 +1,177 @@
+// Copyright 2021 The casbin Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from "react";
+import {DownOutlined, DeleteOutlined, UpOutlined, LinkOutlined} from '@ant-design/icons';
+import {Button, Col, Input, Row, Select, Switch, Table, Tooltip} from 'antd';
+import * as Setting from "./Setting";
+import i18next from "i18next";
+
+const { Option } = Select;
+
+class ProviderTable extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ classes: props,
+ };
+ }
+
+ updateTable(table) {
+ this.props.onUpdateTable(table);
+ }
+
+ updateField(table, index, key, value) {
+ table[index][key] = value;
+ this.updateTable(table);
+ }
+
+ addRow(table) {
+ let row = {name: "", canSignUp: false, canSignIn: true, canUnbind: true};
+ if (table === undefined) {
+ table = [];
+ }
+ table = Setting.addRow(table, row);
+ this.updateTable(table);
+ }
+
+ deleteRow(table, i) {
+ table = Setting.deleteRow(table, i);
+ this.updateTable(table);
+ }
+
+ upRow(table, i) {
+ table = Setting.swapRow(table, i - 1, i);
+ this.updateTable(table);
+ }
+
+ downRow(table, i) {
+ table = Setting.swapRow(table, i, i + 1);
+ this.updateTable(table);
+ }
+
+ renderTable(table) {
+ const columns = [
+ {
+ title: i18next.t("provider:Name"),
+ dataIndex: 'name',
+ key: 'name',
+ render: (text, record, index) => {
+ return (
+
+ )
+ return (
+ } value={text} onChange={e => {
+ this.updateField(table, index, 'name', e.target.value);
+ }} />
+ )
+ }
+ },
+ {
+ title: i18next.t("provider:canSignUp"),
+ dataIndex: 'canSignUp',
+ key: 'canSignUp',
+ width: '120px',
+ render: (text, record, index) => {
+ return (
+ {
+ this.updateField(table, index, 'canSignUp', checked);
+ }} />
+ )
+ }
+ },
+ {
+ title: i18next.t("provider:canSignIn"),
+ dataIndex: 'canSignIn',
+ key: 'canSignIn',
+ width: '120px',
+ render: (text, record, index) => {
+ return (
+ {
+ this.updateField(table, index, 'canSignIn', checked);
+ }} />
+ )
+ }
+ },
+ {
+ title: i18next.t("provider:canUnbind"),
+ dataIndex: 'canUnbind',
+ key: 'canUnbind',
+ width: '120px',
+ render: (text, record, index) => {
+ return (
+ {
+ this.updateField(table, index, 'canUnbind', checked);
+ }} />
+ )
+ }
+ },
+ {
+ title: i18next.t("general:Action"),
+ key: 'action',
+ width: '100px',
+ render: (text, record, index) => {
+ return (
+
+
+ } size="small" onClick={() => this.upRow(table, index)} />
+
+
+ } size="small" onClick={() => this.downRow(table, index)} />
+
+
+ } size="small" onClick={() => this.deleteRow(table, index)} />
+
+
+ );
+ }
+ },
+ ];
+
+ return (
+ (
+
+ {this.props.title}
+
+
+ )}
+ />
+ );
+ }
+
+ render() {
+ return (
+
+
+
+ {
+ this.renderTable(this.props.table)
+ }
+
+
+
+ )
+ }
+}
+
+export default ProviderTable;