mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +08:00
Add Link API.
This commit is contained in:
parent
6774b0379c
commit
36895801f0
@ -44,6 +44,18 @@ func (c *ApiController) GetApplication() {
|
|||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Title GetDefaultApplication
|
||||||
|
// @Description get the detail of the default application
|
||||||
|
// @Param owner query string true "The owner of the application."
|
||||||
|
// @Success 200 {object} object.Application The Response object
|
||||||
|
// @router /get-default-application [get]
|
||||||
|
func (c *ApiController) GetDefaultApplication() {
|
||||||
|
owner := c.Input().Get("owner")
|
||||||
|
|
||||||
|
c.Data["json"] = object.GetDefaultApplication(owner)
|
||||||
|
c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
// @Title UpdateApplication
|
// @Title UpdateApplication
|
||||||
// @Description update an application
|
// @Description update an application
|
||||||
// @Param id query string true "The id of the application"
|
// @Param id query string true "The id of the application"
|
||||||
|
@ -32,6 +32,18 @@ func (c *ApiController) GetProviders() {
|
|||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Title GetDefaultProviders
|
||||||
|
// @Description get default providers
|
||||||
|
// @Param owner query string true "The owner of providers"
|
||||||
|
// @Success 200 {array} object.Provider The Response object
|
||||||
|
// @router /get-default-providers [get]
|
||||||
|
func (c *ApiController) GetDefaultProviders() {
|
||||||
|
owner := c.Input().Get("owner")
|
||||||
|
|
||||||
|
c.Data["json"] = object.GetDefaultProviders(owner)
|
||||||
|
c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
// @Title GetProvider
|
// @Title GetProvider
|
||||||
// @Description get provider
|
// @Description get provider
|
||||||
// @Param id query string true "The id of the provider"
|
// @Param id query string true "The id of the provider"
|
||||||
|
@ -80,6 +80,22 @@ func getApplication(owner string, name string) *Application {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDefaultApplication(owner string) *Application {
|
||||||
|
name := "app-built-in"
|
||||||
|
application := Application{Owner: owner, Name: name}
|
||||||
|
existed, err := adapter.engine.Get(&application)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if existed {
|
||||||
|
extendApplication(&application)
|
||||||
|
return &application
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getApplicationByClientId(clientId string) *Application {
|
func getApplicationByClientId(clientId string) *Application {
|
||||||
application := Application{}
|
application := Application{}
|
||||||
existed, err := adapter.engine.Where("client_id=?", clientId).Get(&application)
|
existed, err := adapter.engine.Where("client_id=?", clientId).Get(&application)
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
)
|
)
|
||||||
@ -41,6 +43,17 @@ func GetProviders(owner string) []*Provider {
|
|||||||
return providers
|
return providers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDefaultProviders(owner string) []*Provider {
|
||||||
|
providers := GetProviders(owner)
|
||||||
|
res := []*Provider{}
|
||||||
|
for _, provider := range providers {
|
||||||
|
if strings.Contains(provider.Name, "casdoor") {
|
||||||
|
res = append(res, provider)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
func getProvider(owner string, name string) *Provider {
|
func getProvider(owner string, name string) *Provider {
|
||||||
provider := Provider{Owner: owner, Name: name}
|
provider := Provider{Owner: owner, Name: name}
|
||||||
existed, err := adapter.engine.Get(&provider)
|
existed, err := adapter.engine.Get(&provider)
|
||||||
|
@ -61,6 +61,7 @@ func initAPI() {
|
|||||||
beego.Router("/api/upload-avatar", &controllers.ApiController{}, "POST:UploadAvatar")
|
beego.Router("/api/upload-avatar", &controllers.ApiController{}, "POST:UploadAvatar")
|
||||||
|
|
||||||
beego.Router("/api/get-providers", &controllers.ApiController{}, "GET:GetProviders")
|
beego.Router("/api/get-providers", &controllers.ApiController{}, "GET:GetProviders")
|
||||||
|
beego.Router("/api/get-default-providers", &controllers.ApiController{}, "GET:GetDefaultProviders")
|
||||||
beego.Router("/api/get-provider", &controllers.ApiController{}, "GET:GetProvider")
|
beego.Router("/api/get-provider", &controllers.ApiController{}, "GET:GetProvider")
|
||||||
beego.Router("/api/update-provider", &controllers.ApiController{}, "POST:UpdateProvider")
|
beego.Router("/api/update-provider", &controllers.ApiController{}, "POST:UpdateProvider")
|
||||||
beego.Router("/api/add-provider", &controllers.ApiController{}, "POST:AddProvider")
|
beego.Router("/api/add-provider", &controllers.ApiController{}, "POST:AddProvider")
|
||||||
@ -68,6 +69,7 @@ func initAPI() {
|
|||||||
|
|
||||||
beego.Router("/api/get-applications", &controllers.ApiController{}, "GET:GetApplications")
|
beego.Router("/api/get-applications", &controllers.ApiController{}, "GET:GetApplications")
|
||||||
beego.Router("/api/get-application", &controllers.ApiController{}, "GET:GetApplication")
|
beego.Router("/api/get-application", &controllers.ApiController{}, "GET:GetApplication")
|
||||||
|
beego.Router("/api/get-default-application", &controllers.ApiController{}, "GET:GetDefaultApplication")
|
||||||
beego.Router("/api/update-application", &controllers.ApiController{}, "POST:UpdateApplication")
|
beego.Router("/api/update-application", &controllers.ApiController{}, "POST:UpdateApplication")
|
||||||
beego.Router("/api/add-application", &controllers.ApiController{}, "POST:AddApplication")
|
beego.Router("/api/add-application", &controllers.ApiController{}, "POST:AddApplication")
|
||||||
beego.Router("/api/delete-application", &controllers.ApiController{}, "POST:DeleteApplication")
|
beego.Router("/api/delete-application", &controllers.ApiController{}, "POST:DeleteApplication")
|
||||||
|
@ -172,7 +172,8 @@ export function getClickable(text) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getIdpLogo(idp) {
|
export function getProviderLogo(provider) {
|
||||||
|
const idp = provider.type.toLowerCase();
|
||||||
const url = `https://cdn.jsdelivr.net/gh/casbin/static/img/social_${idp}.png`;
|
const url = `https://cdn.jsdelivr.net/gh/casbin/static/img/social_${idp}.png`;
|
||||||
return (
|
return (
|
||||||
<img width={30} height={30} src={url} alt={idp} />
|
<img width={30} height={30} src={url} alt={idp} />
|
||||||
|
@ -21,6 +21,9 @@ import {LinkOutlined} from "@ant-design/icons";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import CropperDiv from "./CropperDiv.js";
|
import CropperDiv from "./CropperDiv.js";
|
||||||
import * as AuthBackend from "./auth/AuthBackend";
|
import * as AuthBackend from "./auth/AuthBackend";
|
||||||
|
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
||||||
|
import * as ProviderBackend from "./backend/ProviderBackend";
|
||||||
|
import * as Provider from "./auth/Provider";
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
@ -32,13 +35,17 @@ class UserEditPage extends React.Component {
|
|||||||
organizationName: props.organizationName !== undefined ? props.organizationName : props.match.params.organizationName,
|
organizationName: props.organizationName !== undefined ? props.organizationName : props.match.params.organizationName,
|
||||||
userName: props.userName !== undefined ? props.userName : props.match.params.userName,
|
userName: props.userName !== undefined ? props.userName : props.match.params.userName,
|
||||||
user: null,
|
user: null,
|
||||||
|
application: null,
|
||||||
organizations: [],
|
organizations: [],
|
||||||
|
providers: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillMount() {
|
UNSAFE_componentWillMount() {
|
||||||
this.getUser();
|
this.getUser();
|
||||||
this.getOrganizations();
|
this.getOrganizations();
|
||||||
|
this.getDefaultApplication();
|
||||||
|
this.getDefaultProviders();
|
||||||
}
|
}
|
||||||
|
|
||||||
getUser() {
|
getUser() {
|
||||||
@ -59,6 +66,24 @@ class UserEditPage extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDefaultApplication() {
|
||||||
|
ApplicationBackend.getDefaultApplication("admin")
|
||||||
|
.then((application) => {
|
||||||
|
this.setState({
|
||||||
|
application: application,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultProviders() {
|
||||||
|
ProviderBackend.getDefaultProviders("admin")
|
||||||
|
.then((res) => {
|
||||||
|
this.setState({
|
||||||
|
providers: res,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
parseUserField(key, value) {
|
parseUserField(key, value) {
|
||||||
// if ([].includes(key)) {
|
// if ([].includes(key)) {
|
||||||
// value = Setting.myParseInt(value);
|
// value = Setting.myParseInt(value);
|
||||||
@ -76,9 +101,6 @@ class UserEditPage extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
linkUser(providerType) {
|
|
||||||
}
|
|
||||||
|
|
||||||
unlinkUser(providerType) {
|
unlinkUser(providerType) {
|
||||||
const body = {
|
const body = {
|
||||||
providerType: providerType,
|
providerType: providerType,
|
||||||
@ -95,48 +117,52 @@ class UserEditPage extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getIdpLink(idp, username) {
|
getProviderLink(provider, linkedValue) {
|
||||||
if (idp === "github") {
|
if (provider.type === "GitHub") {
|
||||||
return `https://github.com/${username}`;
|
return `https://github.com/${linkedValue}`;
|
||||||
} else if (idp === "google") {
|
} else if (provider.type === "Google") {
|
||||||
return "https://mail.google.com";
|
return "https://mail.google.com";
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderIdp(idp) {
|
renderIdp(provider) {
|
||||||
|
const linkedValue = this.state.user[provider.type.toLowerCase()];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row style={{marginTop: '20px'}} >
|
<Row style={{marginTop: '20px'}} >
|
||||||
<Col style={{marginTop: '5px'}} span={2}>
|
<Col style={{marginTop: '5px'}} span={2}>
|
||||||
{
|
{
|
||||||
Setting.getIdpLogo(idp.toLowerCase())
|
Setting.getProviderLogo(provider)
|
||||||
}
|
}
|
||||||
<span style={{marginLeft: '5px'}}>
|
<span style={{marginLeft: '5px'}}>
|
||||||
{
|
{
|
||||||
`${idp}:`
|
`${provider.type}:`
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<span style={{width: '200px', display: "inline-block"}}>
|
<span style={{width: '200px', display: "inline-block"}}>
|
||||||
{
|
{
|
||||||
this.state.user[idp.toLowerCase()] === "" ? (
|
linkedValue === "" ? (
|
||||||
"(empty)"
|
"(empty)"
|
||||||
) : (
|
) : (
|
||||||
<a target="_blank" rel="noreferrer" href={this.getIdpLink(idp.toLowerCase(), this.state.user[idp.toLowerCase()])}>
|
<a target="_blank" rel="noreferrer" href={this.getProviderLink(provider, linkedValue)}>
|
||||||
{
|
{
|
||||||
this.state.user[idp.toLowerCase()]
|
linkedValue
|
||||||
}
|
}
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
{
|
{
|
||||||
this.state.user[idp.toLowerCase()] === "" ? (
|
linkedValue === "" ? (
|
||||||
<Button style={{marginLeft: '20px', width: '80px'}} type="primary" onClick={() => this.linkUser(idp)}>Link</Button>
|
<a key={provider.displayName} href={Provider.getAuthUrl(this.state.application, provider, "link")}>
|
||||||
|
<Button style={{marginLeft: '20px', width: '80px'}} type="primary">Link</Button>
|
||||||
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<Button style={{marginLeft: '20px', width: '80px'}} onClick={() => this.unlinkUser(idp)}>Unlink</Button>
|
<Button style={{marginLeft: '20px', width: '80px'}} onClick={() => this.unlinkUser(provider.type)}>Unlink</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Col>
|
</Col>
|
||||||
@ -286,16 +312,7 @@ class UserEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
{
|
{
|
||||||
this.renderIdp("GitHub")
|
this.state.providers.map((provider, index) => this.renderIdp(provider))
|
||||||
}
|
|
||||||
{
|
|
||||||
this.renderIdp("Google")
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.renderIdp("QQ")
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.renderIdp("WeChat")
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!Setting.isAdminUser(this.props.account) ? null : (
|
!Setting.isAdminUser(this.props.account) ? null : (
|
||||||
|
@ -63,10 +63,3 @@ export function unlink(values) {
|
|||||||
body: JSON.stringify(values),
|
body: JSON.stringify(values),
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getApplication(owner, name) {
|
|
||||||
return fetch(`${authConfig.serverUrl}/api/get-application?id=${owner}/${encodeURIComponent(name)}`, {
|
|
||||||
method: "GET",
|
|
||||||
credentials: "include"
|
|
||||||
}).then(res => res.json());
|
|
||||||
}
|
|
||||||
|
@ -34,7 +34,8 @@ class AuthCallback extends React.Component {
|
|||||||
// realRedirectUrl = "http://localhost:9000"
|
// realRedirectUrl = "http://localhost:9000"
|
||||||
const params = new URLSearchParams(this.props.location.search);
|
const params = new URLSearchParams(this.props.location.search);
|
||||||
const state = params.get("state");
|
const state = params.get("state");
|
||||||
return new URLSearchParams(Util.stateToGetQueryParams(state));
|
const queryString = Util.stateToGetQueryParams(state);
|
||||||
|
return new URLSearchParams(queryString);
|
||||||
}
|
}
|
||||||
|
|
||||||
getResponseType() {
|
getResponseType() {
|
||||||
@ -42,14 +43,21 @@ class AuthCallback extends React.Component {
|
|||||||
const authServerUrl = authConfig.serverUrl;
|
const authServerUrl = authConfig.serverUrl;
|
||||||
|
|
||||||
const innerParams = this.getInnerParams();
|
const innerParams = this.getInnerParams();
|
||||||
const realRedirectUri = innerParams.get("redirect_uri");
|
const method = innerParams.get("method");
|
||||||
const realRedirectUrl = new URL(realRedirectUri).origin;
|
if (method === "signup") {
|
||||||
|
const realRedirectUri = innerParams.get("redirect_uri");
|
||||||
|
const realRedirectUrl = new URL(realRedirectUri).origin;
|
||||||
|
|
||||||
// For Casdoor itself, we use "login" directly
|
// For Casdoor itself, we use "login" directly
|
||||||
if (authServerUrl === realRedirectUrl) {
|
if (authServerUrl === realRedirectUrl) {
|
||||||
return "login";
|
return "login";
|
||||||
|
} else {
|
||||||
|
return "code";
|
||||||
|
}
|
||||||
|
} else if (method === "link") {
|
||||||
|
return "link";
|
||||||
} else {
|
} else {
|
||||||
return "code";
|
return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +73,8 @@ class AuthCallback extends React.Component {
|
|||||||
application: applicationName,
|
application: applicationName,
|
||||||
provider: providerName,
|
provider: providerName,
|
||||||
code: params.get("code"),
|
code: params.get("code"),
|
||||||
state: innerParams.get("state"),
|
// state: innerParams.get("state"),
|
||||||
|
state: innerParams.get("application"),
|
||||||
redirectUri: redirectUri,
|
redirectUri: redirectUri,
|
||||||
method: method,
|
method: method,
|
||||||
};
|
};
|
||||||
@ -81,6 +90,9 @@ class AuthCallback extends React.Component {
|
|||||||
const code = res.data;
|
const code = res.data;
|
||||||
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
|
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
|
||||||
// Util.showMessage("success", `Authorization code: ${res.data}`);
|
// Util.showMessage("success", `Authorization code: ${res.data}`);
|
||||||
|
} else if (responseType === "link") {
|
||||||
|
const from = innerParams.get("from");
|
||||||
|
Setting.goToLinkSoft(this, from);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -17,6 +17,7 @@ import {Link} from "react-router-dom";
|
|||||||
import {Button, Checkbox, Col, Form, Input, Row} from "antd";
|
import {Button, Checkbox, Col, Form, Input, Row} from "antd";
|
||||||
import {LockOutlined, UserOutlined} from "@ant-design/icons";
|
import {LockOutlined, UserOutlined} from "@ant-design/icons";
|
||||||
import * as AuthBackend from "./AuthBackend";
|
import * as AuthBackend from "./AuthBackend";
|
||||||
|
import * as ApplicationBackend from "../backend/ApplicationBackend";
|
||||||
import * as Provider from "./Provider";
|
import * as Provider from "./Provider";
|
||||||
import * as Util from "./Util";
|
import * as Util from "./Util";
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
@ -68,7 +69,7 @@ class LoginPage extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthBackend.getApplication("admin", this.state.applicationName)
|
ApplicationBackend.getApplication("admin", this.state.applicationName)
|
||||||
.then((application) => {
|
.then((application) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
application: application,
|
application: application,
|
||||||
|
@ -43,6 +43,10 @@ export function getAuthLogo(provider) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getAuthUrl(application, provider, method) {
|
export function getAuthUrl(application, provider, method) {
|
||||||
|
if (application === null || provider === null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
const redirectUri = `${window.location.origin}/callback`;
|
const redirectUri = `${window.location.origin}/callback`;
|
||||||
const state = Util.getQueryParamsToState(application.name, provider.name, method);
|
const state = Util.getQueryParamsToState(application.name, provider.name, method);
|
||||||
if (provider.type === "Google") {
|
if (provider.type === "Google") {
|
||||||
|
@ -111,6 +111,9 @@ export function getOAuthGetParameters(params) {
|
|||||||
export function getQueryParamsToState(applicationName, providerName, method) {
|
export function getQueryParamsToState(applicationName, providerName, method) {
|
||||||
let query = window.location.search;
|
let query = window.location.search;
|
||||||
query = `${query}&application=${applicationName}&provider=${providerName}&method=${method}`;
|
query = `${query}&application=${applicationName}&provider=${providerName}&method=${method}`;
|
||||||
|
if (method === "link") {
|
||||||
|
query = `${query}&from=${window.location.pathname}`;
|
||||||
|
}
|
||||||
return btoa(query);
|
return btoa(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,13 @@ export function getApplication(owner, name) {
|
|||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getDefaultApplication(owner) {
|
||||||
|
return fetch(`${Setting.ServerUrl}/api/get-default-application?owner=${owner}`, {
|
||||||
|
method: "GET",
|
||||||
|
credentials: "include"
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
export function updateApplication(owner, name, application) {
|
export function updateApplication(owner, name, application) {
|
||||||
let newApplication = Setting.deepCopy(application);
|
let newApplication = Setting.deepCopy(application);
|
||||||
return fetch(`${Setting.ServerUrl}/api/update-application?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/update-application?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
|
@ -21,6 +21,13 @@ export function getProviders(owner) {
|
|||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getDefaultProviders(owner) {
|
||||||
|
return fetch(`${Setting.ServerUrl}/api/get-default-providers?owner=${owner}`, {
|
||||||
|
method: "GET",
|
||||||
|
credentials: "include"
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
export function getProvider(owner, name) {
|
export function getProvider(owner, name) {
|
||||||
return fetch(`${Setting.ServerUrl}/api/get-provider?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-provider?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user