diff --git a/idp/baidu.go b/idp/baidu.go
new file mode 100644
index 00000000..5bab691a
--- /dev/null
+++ b/idp/baidu.go
@@ -0,0 +1,115 @@
+// 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.
+
+package idp
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+
+ "golang.org/x/oauth2"
+)
+
+type BaiduIdProvider struct {
+ Client *http.Client
+ Config *oauth2.Config
+}
+
+func NewBaiduIdProvider(clientId string, clientSecret string, redirectUrl string) *BaiduIdProvider {
+ idp := &BaiduIdProvider{}
+
+ config := idp.getConfig()
+ config.ClientID = clientId
+ config.ClientSecret = clientSecret
+ config.RedirectURL = redirectUrl
+ idp.Config = config
+
+ return idp
+}
+
+func (idp *BaiduIdProvider) SetHttpClient(client *http.Client) {
+ idp.Client = client
+}
+
+func (idp *BaiduIdProvider) getConfig() *oauth2.Config {
+ var endpoint = oauth2.Endpoint{
+ AuthURL: "https://openapi.baidu.com/oauth/2.0/authorize",
+ TokenURL: "https://openapi.baidu.com/oauth/2.0/token",
+ }
+
+ var config = &oauth2.Config{
+ Scopes: []string{"email"},
+ Endpoint: endpoint,
+ }
+
+ return config
+}
+
+func (idp *BaiduIdProvider) GetToken(code string) (*oauth2.Token, error) {
+ ctx := context.WithValue(context.Background(), oauth2.HTTPClient, idp.Client)
+ return idp.Config.Exchange(ctx, code)
+}
+
+/*
+{
+ "userid":"2097322476",
+ "username":"wl19871011",
+ "realname":"阳光",
+ "userdetail":"喜欢自由",
+ "birthday":"1987-01-01",
+ "marriage":"恋爱",
+ "sex":"男",
+ "blood":"O",
+ "constellation":"射手",
+ "figure":"小巧",
+ "education":"大学/专科",
+ "trade":"计算机/电子产品",
+ "job":"未知",
+ "birthday_year":"1987",
+ "birthday_month":"01",
+ "birthday_day":"01",
+}
+*/
+
+type BaiduUserInfo struct {
+ OpenId string `json:"openid"`
+ Username string `json:"username"`
+ Portrait string `json:"portrait"`
+}
+
+func (idp *BaiduIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
+ resp, err := idp.Client.Get(fmt.Sprintf("https://openapi.baidu.com/rest/2.0/passport/users/getInfo?access_token=%s", token.AccessToken))
+ if err != nil {
+ return nil, err
+ }
+
+ data, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return nil, err
+ }
+ baiduUser := BaiduUserInfo{}
+ if err = json.Unmarshal(data, &baiduUser); err != nil {
+ return nil, err
+ }
+
+ userInfo := UserInfo{
+ Id: baiduUser.OpenId,
+ Username: baiduUser.Username,
+ AvatarUrl: fmt.Sprintf("https://himg.bdimg.com/sys/portrait/item/%s", baiduUser.Portrait),
+ }
+ return &userInfo, nil
+}
diff --git a/idp/provider.go b/idp/provider.go
index 747e3808..04a3dd4f 100644
--- a/idp/provider.go
+++ b/idp/provider.go
@@ -60,6 +60,8 @@ func GetIdProvider(providerType string, clientId string, clientSecret string, re
return NewLarkIdProvider(clientId, clientSecret, redirectUrl)
} else if providerType == "GitLab" {
return NewGitlabIdProvider(clientId, clientSecret, redirectUrl)
+ } else if providerType == "Baidu" {
+ return NewBaiduIdProvider(clientId, clientSecret, redirectUrl)
} else if isGothSupport(providerType) {
return NewGothIdProvider(providerType, clientId, clientSecret, redirectUrl)
}
diff --git a/object/user.go b/object/user.go
index 5e0299ae..5cafed64 100644
--- a/object/user.go
+++ b/object/user.go
@@ -79,6 +79,7 @@ type User struct {
Wecom string `xorm:"wecom varchar(100)" json:"wecom"`
Lark string `xorm:"lark varchar(100)" json:"lark"`
Gitlab string `xorm:"gitlab varchar(100)" json:"gitlab"`
+ Baidu string `xorm:"baidu varchar(100)" json:"baidu"`
Apple string `xorm:"apple varchar(100)" json:"apple"`
AzureAD string `xorm:"azuread varchar(100)" json:"azuread"`
Slack string `xorm:"slack varchar(100)" json:"slack"`
diff --git a/web/src/Setting.js b/web/src/Setting.js
index 1e17d001..86b21860 100644
--- a/web/src/Setting.js
+++ b/web/src/Setting.js
@@ -398,6 +398,7 @@ export function getProviderTypeOptions(category) {
{id: 'WeCom', name: 'WeCom'},
{id: 'Lark', name: 'Lark'},
{id: 'GitLab', name: 'GitLab'},
+ {id: 'Baidu', name: 'Baidu'},
{id: 'Apple', name: 'Apple'},
{id: 'AzureAD', name: 'AzureAD'},
{id: 'Slack', name: 'Slack'},
diff --git a/web/src/auth/BaiduLoginButton.js b/web/src/auth/BaiduLoginButton.js
new file mode 100644
index 00000000..5aeddc16
--- /dev/null
+++ b/web/src/auth/BaiduLoginButton.js
@@ -0,0 +1,32 @@
+// 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 {createButton} from "react-social-login-buttons";
+import {StaticBaseUrl} from "../Setting";
+
+function Icon({ width = 24, height = 24, color }) {
+ return
;
+}
+
+const config = {
+ text: "Sign in with Baidu",
+ icon: Icon,
+ iconFormat: name => `fa fa-${name}`,
+ style: {background: "#ffffff", color: "#000000"},
+ activeStyle: {background: "#ededee"},
+};
+
+const BaiduLoginButton = createButton(config);
+
+export default BaiduLoginButton;
diff --git a/web/src/auth/LoginPage.js b/web/src/auth/LoginPage.js
index d84fec4b..d7a671c1 100644
--- a/web/src/auth/LoginPage.js
+++ b/web/src/auth/LoginPage.js
@@ -34,6 +34,7 @@ import LinkedInLoginButton from "./LinkedInLoginButton";
import WeComLoginButton from "./WeComLoginButton";
import LarkLoginButton from "./LarkLoginButton";
import GitLabLoginButton from "./GitLabLoginButton";
+import BaiduLoginButton from "./BaiduLoginButton";
import AppleLoginButton from "./AppleLoginButton"
import AzureADLoginButton from "./AzureADLoginButton";
import SlackLoginButton from "./SlackLoginButton";
@@ -183,6 +184,8 @@ class LoginPage extends React.Component {
return
} else if (type === "GitLab") {
return
+ } else if (type === "Baidu") {
+ return
} else if (type === "Apple") {
return
} else if (type === "AzureAD") {
diff --git a/web/src/auth/Provider.js b/web/src/auth/Provider.js
index d300b77f..f5a6f1ee 100644
--- a/web/src/auth/Provider.js
+++ b/web/src/auth/Provider.js
@@ -69,6 +69,10 @@ const authInfo = {
scope: "read_user+profile",
endpoint: "https://gitlab.com/oauth/authorize",
},
+ Baidu: {
+ scope: "basic",
+ endpoint: "http://openapi.baidu.com/oauth/2.0/authorize",
+ },
Apple: {
scope: "name%20email",
endpoint: "https://appleid.apple.com/auth/authorize",
@@ -227,6 +231,8 @@ export function getAuthUrl(application, provider, method) {
return `${endpoint}?app_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}`;
} else if (provider.type === "GitLab") {
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
+ } else if (provider.type === "Baidu") {
+ return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}&display=popup`;
} else if (provider.type === "Apple") {
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}&response_mode=form_post`;
} else if (provider.type === "AzureAD") {