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()
|
||||
}
|
||||
|
||||
// @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
|
||||
// @Description update an application
|
||||
// @Param id query string true "The id of the application"
|
||||
|
@ -32,6 +32,18 @@ func (c *ApiController) GetProviders() {
|
||||
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
|
||||
// @Description get 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 {
|
||||
application := Application{}
|
||||
existed, err := adapter.engine.Where("client_id=?", clientId).Get(&application)
|
||||
|
@ -15,6 +15,8 @@
|
||||
package object
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"xorm.io/core"
|
||||
)
|
||||
@ -41,6 +43,17 @@ func GetProviders(owner string) []*Provider {
|
||||
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 {
|
||||
provider := Provider{Owner: owner, Name: name}
|
||||
existed, err := adapter.engine.Get(&provider)
|
||||
|
@ -61,6 +61,7 @@ func initAPI() {
|
||||
beego.Router("/api/upload-avatar", &controllers.ApiController{}, "POST:UploadAvatar")
|
||||
|
||||
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/update-provider", &controllers.ApiController{}, "POST:UpdateProvider")
|
||||
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-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/add-application", &controllers.ApiController{}, "POST:AddApplication")
|
||||
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`;
|
||||
return (
|
||||
<img width={30} height={30} src={url} alt={idp} />
|
||||
|
@ -21,6 +21,9 @@ import {LinkOutlined} from "@ant-design/icons";
|
||||
import i18next from "i18next";
|
||||
import CropperDiv from "./CropperDiv.js";
|
||||
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;
|
||||
|
||||
@ -32,13 +35,17 @@ class UserEditPage extends React.Component {
|
||||
organizationName: props.organizationName !== undefined ? props.organizationName : props.match.params.organizationName,
|
||||
userName: props.userName !== undefined ? props.userName : props.match.params.userName,
|
||||
user: null,
|
||||
application: null,
|
||||
organizations: [],
|
||||
providers: [],
|
||||
};
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
this.getUser();
|
||||
this.getOrganizations();
|
||||
this.getDefaultApplication();
|
||||
this.getDefaultProviders();
|
||||
}
|
||||
|
||||
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) {
|
||||
// if ([].includes(key)) {
|
||||
// value = Setting.myParseInt(value);
|
||||
@ -76,9 +101,6 @@ class UserEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
linkUser(providerType) {
|
||||
}
|
||||
|
||||
unlinkUser(providerType) {
|
||||
const body = {
|
||||
providerType: providerType,
|
||||
@ -95,48 +117,52 @@ class UserEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getIdpLink(idp, username) {
|
||||
if (idp === "github") {
|
||||
return `https://github.com/${username}`;
|
||||
} else if (idp === "google") {
|
||||
getProviderLink(provider, linkedValue) {
|
||||
if (provider.type === "GitHub") {
|
||||
return `https://github.com/${linkedValue}`;
|
||||
} else if (provider.type === "Google") {
|
||||
return "https://mail.google.com";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
renderIdp(idp) {
|
||||
renderIdp(provider) {
|
||||
const linkedValue = this.state.user[provider.type.toLowerCase()];
|
||||
|
||||
return (
|
||||
<Row style={{marginTop: '20px'}} >
|
||||
<Col style={{marginTop: '5px'}} span={2}>
|
||||
{
|
||||
Setting.getIdpLogo(idp.toLowerCase())
|
||||
Setting.getProviderLogo(provider)
|
||||
}
|
||||
<span style={{marginLeft: '5px'}}>
|
||||
{
|
||||
`${idp}:`
|
||||
`${provider.type}:`
|
||||
}
|
||||
</span>
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<span style={{width: '200px', display: "inline-block"}}>
|
||||
{
|
||||
this.state.user[idp.toLowerCase()] === "" ? (
|
||||
linkedValue === "" ? (
|
||||
"(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>
|
||||
)
|
||||
}
|
||||
</span>
|
||||
{
|
||||
this.state.user[idp.toLowerCase()] === "" ? (
|
||||
<Button style={{marginLeft: '20px', width: '80px'}} type="primary" onClick={() => this.linkUser(idp)}>Link</Button>
|
||||
linkedValue === "" ? (
|
||||
<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>
|
||||
@ -286,16 +312,7 @@ class UserEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
{
|
||||
this.renderIdp("GitHub")
|
||||
}
|
||||
{
|
||||
this.renderIdp("Google")
|
||||
}
|
||||
{
|
||||
this.renderIdp("QQ")
|
||||
}
|
||||
{
|
||||
this.renderIdp("WeChat")
|
||||
this.state.providers.map((provider, index) => this.renderIdp(provider))
|
||||
}
|
||||
{
|
||||
!Setting.isAdminUser(this.props.account) ? null : (
|
||||
|
@ -63,10 +63,3 @@ export function unlink(values) {
|
||||
body: JSON.stringify(values),
|
||||
}).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"
|
||||
const params = new URLSearchParams(this.props.location.search);
|
||||
const state = params.get("state");
|
||||
return new URLSearchParams(Util.stateToGetQueryParams(state));
|
||||
const queryString = Util.stateToGetQueryParams(state);
|
||||
return new URLSearchParams(queryString);
|
||||
}
|
||||
|
||||
getResponseType() {
|
||||
@ -42,6 +43,8 @@ class AuthCallback extends React.Component {
|
||||
const authServerUrl = authConfig.serverUrl;
|
||||
|
||||
const innerParams = this.getInnerParams();
|
||||
const method = innerParams.get("method");
|
||||
if (method === "signup") {
|
||||
const realRedirectUri = innerParams.get("redirect_uri");
|
||||
const realRedirectUrl = new URL(realRedirectUri).origin;
|
||||
|
||||
@ -51,6 +54,11 @@ class AuthCallback extends React.Component {
|
||||
} else {
|
||||
return "code";
|
||||
}
|
||||
} else if (method === "link") {
|
||||
return "link";
|
||||
} else {
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
@ -65,7 +73,8 @@ class AuthCallback extends React.Component {
|
||||
application: applicationName,
|
||||
provider: providerName,
|
||||
code: params.get("code"),
|
||||
state: innerParams.get("state"),
|
||||
// state: innerParams.get("state"),
|
||||
state: innerParams.get("application"),
|
||||
redirectUri: redirectUri,
|
||||
method: method,
|
||||
};
|
||||
@ -81,6 +90,9 @@ class AuthCallback extends React.Component {
|
||||
const code = res.data;
|
||||
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
|
||||
// Util.showMessage("success", `Authorization code: ${res.data}`);
|
||||
} else if (responseType === "link") {
|
||||
const from = innerParams.get("from");
|
||||
Setting.goToLinkSoft(this, from);
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
|
@ -17,6 +17,7 @@ import {Link} from "react-router-dom";
|
||||
import {Button, Checkbox, Col, Form, Input, Row} from "antd";
|
||||
import {LockOutlined, UserOutlined} from "@ant-design/icons";
|
||||
import * as AuthBackend from "./AuthBackend";
|
||||
import * as ApplicationBackend from "../backend/ApplicationBackend";
|
||||
import * as Provider from "./Provider";
|
||||
import * as Util from "./Util";
|
||||
import * as Setting from "../Setting";
|
||||
@ -68,7 +69,7 @@ class LoginPage extends React.Component {
|
||||
return;
|
||||
}
|
||||
|
||||
AuthBackend.getApplication("admin", this.state.applicationName)
|
||||
ApplicationBackend.getApplication("admin", this.state.applicationName)
|
||||
.then((application) => {
|
||||
this.setState({
|
||||
application: application,
|
||||
|
@ -43,6 +43,10 @@ export function getAuthLogo(provider) {
|
||||
}
|
||||
|
||||
export function getAuthUrl(application, provider, method) {
|
||||
if (application === null || provider === null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const redirectUri = `${window.location.origin}/callback`;
|
||||
const state = Util.getQueryParamsToState(application.name, provider.name, method);
|
||||
if (provider.type === "Google") {
|
||||
|
@ -111,6 +111,9 @@ export function getOAuthGetParameters(params) {
|
||||
export function getQueryParamsToState(applicationName, providerName, method) {
|
||||
let query = window.location.search;
|
||||
query = `${query}&application=${applicationName}&provider=${providerName}&method=${method}`;
|
||||
if (method === "link") {
|
||||
query = `${query}&from=${window.location.pathname}`;
|
||||
}
|
||||
return btoa(query);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,13 @@ export function getApplication(owner, name) {
|
||||
}).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) {
|
||||
let newApplication = Setting.deepCopy(application);
|
||||
return fetch(`${Setting.ServerUrl}/api/update-application?id=${owner}/${encodeURIComponent(name)}`, {
|
||||
|
@ -21,6 +21,13 @@ export function getProviders(owner) {
|
||||
}).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) {
|
||||
return fetch(`${Setting.ServerUrl}/api/get-provider?id=${owner}/${encodeURIComponent(name)}`, {
|
||||
method: "GET",
|
||||
|
Loading…
x
Reference in New Issue
Block a user