mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-30 11:00:23 +08:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c184dc7f3a | ||
![]() |
2fa0890c11 | ||
![]() |
a0e2be7ba8 | ||
![]() |
09b389b1f7 |
11
idp/lark.go
11
idp/lark.go
@@ -135,6 +135,7 @@ func (idp *LarkIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
"open_id": "ou-caecc734c2e3328a62489fe0648c4b98779515d3",
|
||||
"union_id": "on-d89jhsdhjsajkda7828enjdj328ydhhw3u43yjhdj",
|
||||
"email": "zhangsan@feishu.cn",
|
||||
"enterprise_email": "zhangsan@company.com",
|
||||
"user_id": "5d9bdxxx",
|
||||
"mobile": "+86130002883xx",
|
||||
"tenant_key": "736588c92lxf175d",
|
||||
@@ -160,6 +161,7 @@ type LarkUserInfo struct {
|
||||
OpenId string `json:"open_id"`
|
||||
UnionId string `json:"union_id"`
|
||||
Email string `json:"email"`
|
||||
EnterpriseEmail string `json:"enterprise_email"`
|
||||
UserId string `json:"user_id"`
|
||||
Mobile string `json:"mobile"`
|
||||
TenantKey string `json:"tenant_key"`
|
||||
@@ -168,7 +170,6 @@ type LarkUserInfo struct {
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
// GetUserInfo use LarkAccessToken gotten before return LinkedInUserInf
|
||||
// GetUserInfo use LarkAccessToken gotten before return LinkedInUserInfo
|
||||
// get more detail via: https://docs.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin?context=linkedin/consumer/context
|
||||
func (idp *LarkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
@@ -207,6 +208,12 @@ func (idp *LarkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Use enterprise_email as fallback when email is empty
|
||||
email := larkUserInfo.Data.Email
|
||||
if email == "" {
|
||||
email = larkUserInfo.Data.EnterpriseEmail
|
||||
}
|
||||
|
||||
var phoneNumber string
|
||||
var countryCode string
|
||||
if len(larkUserInfo.Data.Mobile) != 0 {
|
||||
@@ -222,7 +229,7 @@ func (idp *LarkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
Id: larkUserInfo.Data.OpenId,
|
||||
DisplayName: larkUserInfo.Data.Name,
|
||||
Username: larkUserInfo.Data.UserId,
|
||||
Email: larkUserInfo.Data.Email,
|
||||
Email: email,
|
||||
AvatarUrl: larkUserInfo.Data.AvatarUrl,
|
||||
Phone: phoneNumber,
|
||||
CountryCode: countryCode,
|
||||
|
@@ -70,7 +70,9 @@ func NewSamlResponse(application *Application, user *User, host string, certific
|
||||
if application.UseEmailAsSamlNameId {
|
||||
nameIDValue = user.Email
|
||||
}
|
||||
subject.CreateElement("saml:NameID").SetText(nameIDValue)
|
||||
nameId := subject.CreateElement("saml:NameID")
|
||||
nameId.CreateAttr("Format", "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent")
|
||||
nameId.SetText(nameIDValue)
|
||||
subjectConfirmation := subject.CreateElement("saml:SubjectConfirmation")
|
||||
subjectConfirmation.CreateAttr("Method", "urn:oasis:names:tc:SAML:2.0:cm:bearer")
|
||||
subjectConfirmationData := subjectConfirmation.CreateElement("saml:SubjectConfirmationData")
|
||||
@@ -108,20 +110,46 @@ func NewSamlResponse(application *Application, user *User, host string, certific
|
||||
displayName.CreateAttr("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic")
|
||||
displayName.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(user.DisplayName)
|
||||
|
||||
err := ExtendUserWithRolesAndPermissions(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, item := range application.SamlAttributes {
|
||||
role := attributes.CreateElement("saml:Attribute")
|
||||
role.CreateAttr("Name", item.Name)
|
||||
role.CreateAttr("NameFormat", item.NameFormat)
|
||||
role.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(item.Value)
|
||||
|
||||
valueList := []string{item.Value}
|
||||
if strings.Contains(item.Value, "$user.roles") {
|
||||
valueList = replaceSamlAttributeValuesWithList("$user.roles", getUserRoleNames(user), valueList)
|
||||
}
|
||||
|
||||
if strings.Contains(item.Value, "$user.permissions") {
|
||||
valueList = replaceSamlAttributeValuesWithList("$user.permissions", getUserPermissionNames(user), valueList)
|
||||
}
|
||||
|
||||
if strings.Contains(item.Value, "$user.groups") {
|
||||
valueList = replaceSamlAttributeValuesWithList("$user.groups", user.Groups, valueList)
|
||||
}
|
||||
|
||||
valueList = replaceSamlAttributeValues("$user.owner", user.Owner, valueList)
|
||||
valueList = replaceSamlAttributeValues("$user.name", user.Name, valueList)
|
||||
valueList = replaceSamlAttributeValues("$user.email", user.Email, valueList)
|
||||
valueList = replaceSamlAttributeValues("$user.id", user.Id, valueList)
|
||||
valueList = replaceSamlAttributeValues("$user.phone", user.Phone, valueList)
|
||||
|
||||
for _, value := range valueList {
|
||||
av := role.CreateElement("saml:AttributeValue")
|
||||
av.CreateAttr("xmlns:xs", "http://www.w3.org/2001/XMLSchema")
|
||||
av.CreateAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
|
||||
av.CreateAttr("xsi:type", "xs:string").Element().SetText(value)
|
||||
}
|
||||
}
|
||||
|
||||
roles := attributes.CreateElement("saml:Attribute")
|
||||
roles.CreateAttr("Name", "Roles")
|
||||
roles.CreateAttr("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic")
|
||||
err := ExtendUserWithRolesAndPermissions(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, role := range user.Roles {
|
||||
roles.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(role.Name)
|
||||
@@ -130,6 +158,26 @@ func NewSamlResponse(application *Application, user *User, host string, certific
|
||||
return samlResponse, nil
|
||||
}
|
||||
|
||||
func replaceSamlAttributeValues(val string, replaceVal string, values []string) []string {
|
||||
newValues := []string{}
|
||||
for _, value := range values {
|
||||
newValues = append(newValues, strings.ReplaceAll(value, val, replaceVal))
|
||||
}
|
||||
|
||||
return newValues
|
||||
}
|
||||
|
||||
func replaceSamlAttributeValuesWithList(val string, replaceVals []string, values []string) []string {
|
||||
newValues := []string{}
|
||||
for _, value := range values {
|
||||
for _, rVal := range replaceVals {
|
||||
newValues = append(newValues, strings.ReplaceAll(value, val, rVal))
|
||||
}
|
||||
}
|
||||
|
||||
return newValues
|
||||
}
|
||||
|
||||
type X509Key struct {
|
||||
X509Certificate string
|
||||
PrivateKey string
|
||||
|
@@ -342,7 +342,7 @@ func getClaimsCustom(claims Claims, tokenField []string) jwt.MapClaims {
|
||||
res["provider"] = claims.Provider
|
||||
|
||||
for _, field := range tokenField {
|
||||
if strings.HasPrefix(field, "Properties") {
|
||||
if strings.HasPrefix(field, "Properties.") {
|
||||
/*
|
||||
Use selected properties fields as custom claims.
|
||||
Converts `Properties.my_field` to custom claim with name `my_field`.
|
||||
|
@@ -248,6 +248,20 @@ func SetUserOAuthProperties(organization *Organization, user *User, providerType
|
||||
return UpdateUserForAllFields(user.GetId(), user)
|
||||
}
|
||||
|
||||
func getUserRoleNames(user *User) (res []string) {
|
||||
for _, role := range user.Roles {
|
||||
res = append(res, role.Name)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func getUserPermissionNames(user *User) (res []string) {
|
||||
for _, permission := range user.Permissions {
|
||||
res = append(res, permission.Name)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func ClearUserOAuthProperties(user *User, providerType string) (bool, error) {
|
||||
for k := range user.Properties {
|
||||
prefix := fmt.Sprintf("oauth_%s_", providerType)
|
||||
|
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
import {ArrowUpOutlined} from "@ant-design/icons";
|
||||
import {Card, Col, Row, Statistic, Tour} from "antd";
|
||||
import {Card, Col, Row, Spin, Statistic, Tour} from "antd";
|
||||
import * as echarts from "echarts";
|
||||
import i18next from "i18next";
|
||||
import React from "react";
|
||||
@@ -74,6 +74,8 @@ const Dashboard = (props) => {
|
||||
return;
|
||||
}
|
||||
|
||||
setDashboardData(null);
|
||||
|
||||
const organization = getOrganizationName();
|
||||
DashboardBackend.getDashboard(organization).then((res) => {
|
||||
if (res.status === "ok") {
|
||||
@@ -110,11 +112,22 @@ const Dashboard = (props) => {
|
||||
};
|
||||
|
||||
const renderEChart = () => {
|
||||
const chartDom = document.getElementById("echarts-chart");
|
||||
|
||||
if (dashboardData === null) {
|
||||
return;
|
||||
if (chartDom) {
|
||||
const instance = echarts.getInstanceByDom(chartDom);
|
||||
if (instance) {
|
||||
instance.dispose();
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div style={{display: "flex", justifyContent: "center", alignItems: "center"}}>
|
||||
<Spin size="large" tip={i18next.t("login:Loading")} style={{paddingTop: "10%"}} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const chartDom = document.getElementById("echarts-chart");
|
||||
const myChart = echarts.init(chartDom);
|
||||
const currentDate = new Date();
|
||||
const dateArray = [];
|
||||
|
Reference in New Issue
Block a user