Compare commits

...

4 Commits

Author SHA1 Message Date
4123d47174 feat: callback will jump to blank page when from param start with "http" (#2778) 2024-03-06 01:07:52 +08:00
fbdd5a926d Fix normal user my-account page blank bug 2024-03-06 01:07:28 +08:00
92b6fda0f6 feat: support more objects in init_data JSON (#2776) 2024-03-05 23:41:46 +08:00
6a7ac35e65 fix: fix wechat media account can not bind issue (#2774)
* fix: fix wechat media account can not bind

* fix: improve code format
2024-03-05 18:46:28 +08:00
9 changed files with 217 additions and 61 deletions

View File

@ -469,14 +469,24 @@ func GetMaskedApplication(application *Application, userId string) *Application
application.FailedSigninFrozenTime = DefaultFailedSigninFrozenTime
}
isOrgUser := false
if userId != "" {
if isUserIdGlobalAdmin(userId) {
return application
}
user, _ := GetUser(userId)
if user != nil && user.IsApplicationAdmin(application) {
return application
user, err := GetUser(userId)
if err != nil {
panic(err)
}
if user != nil {
if user.IsApplicationAdmin(application) {
return application
}
if user.Owner == application.Organization {
isOrgUser = true
}
}
}
@ -519,8 +529,11 @@ func GetMaskedApplication(application *Application, userId string) *Application
application.OrganizationObj.InitScore = -1
application.OrganizationObj.EnableSoftDeletion = false
application.OrganizationObj.IsProfilePublic = false
application.OrganizationObj.MfaItems = nil
application.OrganizationObj.AccountItems = nil
if !isOrgUser {
application.OrganizationObj.MfaItems = nil
application.OrganizationObj.AccountItems = nil
}
}
return application

View File

@ -17,29 +17,35 @@ package object
import (
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/util"
"github.com/casvisor/casvisor-go-sdk/casvisorsdk"
)
type InitData struct {
Organizations []*Organization `json:"organizations"`
Applications []*Application `json:"applications"`
Users []*User `json:"users"`
Certs []*Cert `json:"certs"`
Providers []*Provider `json:"providers"`
Ldaps []*Ldap `json:"ldaps"`
Models []*Model `json:"models"`
Permissions []*Permission `json:"permissions"`
Payments []*Payment `json:"payments"`
Products []*Product `json:"products"`
Resources []*Resource `json:"resources"`
Roles []*Role `json:"roles"`
Syncers []*Syncer `json:"syncers"`
Tokens []*Token `json:"tokens"`
Webhooks []*Webhook `json:"webhooks"`
Groups []*Group `json:"groups"`
Adapters []*Adapter `json:"adapters"`
Enforcers []*Enforcer `json:"enforcers"`
Plans []*Plan `json:"plans"`
Pricings []*Pricing `json:"pricings"`
Organizations []*Organization `json:"organizations"`
Applications []*Application `json:"applications"`
Users []*User `json:"users"`
Certs []*Cert `json:"certs"`
Providers []*Provider `json:"providers"`
Ldaps []*Ldap `json:"ldaps"`
Models []*Model `json:"models"`
Permissions []*Permission `json:"permissions"`
Payments []*Payment `json:"payments"`
Products []*Product `json:"products"`
Resources []*Resource `json:"resources"`
Roles []*Role `json:"roles"`
Syncers []*Syncer `json:"syncers"`
Tokens []*Token `json:"tokens"`
Webhooks []*Webhook `json:"webhooks"`
Groups []*Group `json:"groups"`
Adapters []*Adapter `json:"adapters"`
Enforcers []*Enforcer `json:"enforcers"`
Plans []*Plan `json:"plans"`
Pricings []*Pricing `json:"pricings"`
Invitations []*Invitation `json:"invitations"`
Records []*casvisorsdk.Record `json:"records"`
Sessions []*Session `json:"sessions"`
Subscriptions []*Subscription `json:"subscriptions"`
Transactions []*Transaction `json:"transactions"`
}
func InitFromFile() {
@ -114,6 +120,21 @@ func InitFromFile() {
for _, pricing := range initData.Pricings {
initDefinedPricing(pricing)
}
for _, invitation := range initData.Invitations {
initDefinedInvitation(invitation)
}
for _, record := range initData.Records {
initDefinedRecord(record)
}
for _, session := range initData.Sessions {
initDefinedSession(session)
}
for _, subscription := range initData.Subscriptions {
initDefinedSubscription(subscription)
}
for _, transaction := range initData.Transactions {
initDefinedTransaction(transaction)
}
}
}
@ -145,6 +166,11 @@ func readInitDataFromFile(filePath string) (*InitData, error) {
Enforcers: []*Enforcer{},
Plans: []*Plan{},
Pricings: []*Pricing{},
Invitations: []*Invitation{},
Records: []*casvisorsdk.Record{},
Sessions: []*Session{},
Subscriptions: []*Subscription{},
Transactions: []*Transaction{},
}
err := util.JsonToStruct(s, data)
if err != nil {
@ -225,6 +251,11 @@ func readInitDataFromFile(filePath string) (*InitData, error) {
pricing.Plans = []string{}
}
}
for _, session := range data.Sessions {
if session.SessionId == nil {
session.SessionId = []string{}
}
}
return data, nil
}
@ -543,3 +574,61 @@ func initDefinedPricing(pricing *Pricing) {
panic(err)
}
}
func initDefinedInvitation(invitation *Invitation) {
existed, err := getInvitation(invitation.Owner, invitation.Name)
if err != nil {
panic(err)
}
if existed != nil {
return
}
invitation.CreatedTime = util.GetCurrentTime()
_, err = AddInvitation(invitation, "en")
if err != nil {
panic(err)
}
}
func initDefinedRecord(record *casvisorsdk.Record) {
record.CreatedTime = util.GetCurrentTime()
_ = AddRecord(record)
}
func initDefinedSession(session *Session) {
session.CreatedTime = util.GetCurrentTime()
_, err := AddSession(session)
if err != nil {
panic(err)
}
}
func initDefinedSubscription(subscription *Subscription) {
existed, err := getSubscription(subscription.Owner, subscription.Name)
if err != nil {
panic(err)
}
if existed != nil {
return
}
subscription.CreatedTime = util.GetCurrentTime()
_, err = AddSubscription(subscription)
if err != nil {
panic(err)
}
}
func initDefinedTransaction(transaction *Transaction) {
existed, err := getTransaction(transaction.Owner, transaction.Name)
if err != nil {
panic(err)
}
if existed != nil {
return
}
transaction.CreatedTime = util.GetCurrentTime()
_, err = AddTransaction(transaction)
if err != nil {
panic(err)
}
}

View File

@ -121,6 +121,31 @@ func writeInitDataToFile(filePath string) error {
return err
}
invitations, err := GetInvitations("")
if err != nil {
return err
}
records, err := GetRecords()
if err != nil {
return err
}
sessions, err := GetSessions("")
if err != nil {
return err
}
subscriptions, err := GetSubscriptions("")
if err != nil {
return err
}
transactions, err := GetTransactions("")
if err != nil {
return err
}
data := &InitData{
Organizations: organizations,
Applications: applications,
@ -142,6 +167,11 @@ func writeInitDataToFile(filePath string) error {
Enforcers: enforcers,
Plans: plans,
Pricings: pricings,
Invitations: invitations,
Records: records,
Sessions: sessions,
Subscriptions: subscriptions,
Transactions: transactions,
}
text := util.StructToJsonFormatted(data)

View File

@ -707,6 +707,15 @@ export function goToLinkSoft(ths, link) {
ths.props.history.push(link);
}
export function goToLinkSoftOrJumpSelf(ths, link) {
if (link.startsWith("http")) {
goToLink(link);
return;
}
ths.props.history.push(link);
}
export function showMessage(type, text) {
if (type === "success") {
message.success(text);

View File

@ -64,7 +64,9 @@ class UserEditPage extends React.Component {
UNSAFE_componentWillMount() {
this.getUser();
this.getOrganizations();
if (Setting.isLocalAdminUser(this.props.account)) {
this.getOrganizations();
}
this.getApplicationsByOrganization(this.state.organizationName);
this.getUserApplication();
this.setReturnUrl();
@ -1001,7 +1003,7 @@ class UserEditPage extends React.Component {
<div style={{verticalAlign: "middle", marginBottom: 10}}>{`(${i18next.t("general:empty")})`}</div>
</Col>
}
<CropperDivModal disabled={disabled} tag={tag} setTitle={set} buttonText={`${title}...`} title={title} user={this.state.user} organization={this.state.organizations.find(organization => organization.name === this.state.organizationName)} />
<CropperDivModal disabled={disabled} tag={tag} setTitle={set} buttonText={`${title}...`} title={title} user={this.state.user} organization={this.getUserOrganization()} />
</Col>
);
}

View File

@ -172,7 +172,7 @@ class AuthCallback extends React.Component {
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`);
} else if (responseType === "link") {
const from = innerParams.get("from");
Setting.goToLinkSoft(this, from);
Setting.goToLinkSoftOrJumpSelf(this, from);
} else if (responseType === "saml") {
if (res.data2.method === "POST") {
this.setState({

View File

@ -42,9 +42,7 @@ import OktaLoginButton from "./OktaLoginButton";
import DouyinLoginButton from "./DouyinLoginButton";
import LoginButton from "./LoginButton";
import * as AuthBackend from "./AuthBackend";
import * as Setting from "../Setting";
import {getEvent} from "./Util";
import {Modal} from "antd";
import {WechatOfficialAccountModal} from "./Util";
function getSigninButton(provider) {
const text = i18next.t("login:Sign in with {type}").replace("{type}", provider.displayName !== "" ? provider.displayName : provider.type);
@ -141,32 +139,11 @@ export function renderProviderLogo(provider, application, width, margin, size, l
if (size === "small") {
if (provider.category === "OAuth") {
if (provider.type === "WeChat" && provider.clientId2 !== "" && provider.clientSecret2 !== "" && provider.disableSsl === true && !navigator.userAgent.includes("MicroMessenger")) {
const info = async() => {
AuthBackend.getWechatQRCode(`${provider.owner}/${provider.name}`).then(
async res => {
if (res.status !== "ok") {
Setting.showMessage("error", res?.msg);
return;
}
const t1 = setInterval(await getEvent, 1000, application, provider, res.data2);
{Modal.info({
title: i18next.t("provider:Please use WeChat to scan the QR code and follow the official account for sign in"),
content: (
<div style={{marginRight: "34px"}}>
<img src = {"data:image/png;base64," + res.data} alt="Wechat QR code" style={{width: "100%"}} />
</div>
),
onOk() {
window.clearInterval(t1);
},
});}
}
);
};
return (
<a key={provider.displayName} >
<img width={width} height={width} src={getProviderLogoURL(provider)} alt={provider.displayName} className="provider-img" style={{margin: margin}} onClick={info} />
<img width={width} height={width} src={getProviderLogoURL(provider)} alt={provider.displayName} className="provider-img" style={{margin: margin}} onClick={() => {
WechatOfficialAccountModal(application, provider, "signup");
}} />
</a>
);
} else {

View File

@ -13,11 +13,12 @@
// limitations under the License.
import React from "react";
import {Alert, Button, Result} from "antd";
import {Alert, Button, Modal, Result} from "antd";
import i18next from "i18next";
import {getWechatMessageEvent} from "./AuthBackend";
import * as Setting from "../Setting";
import * as Provider from "./Provider";
import * as AuthBackend from "./AuthBackend";
export function renderMessage(msg) {
if (msg !== null) {
@ -188,12 +189,36 @@ export function getQueryParamsFromState(state) {
}
}
export function getEvent(application, provider, ticket) {
export function getEvent(application, provider, ticket, method) {
getWechatMessageEvent(ticket)
.then(res => {
if (res.data === "SCAN" || res.data === "subscribe") {
const code = res?.data2;
Setting.goToLink(Provider.getAuthUrl(application, provider, "signup", code));
Setting.goToLink(Provider.getAuthUrl(application, provider, method ?? "signup", code));
}
});
}
export async function WechatOfficialAccountModal(application, provider, method) {
AuthBackend.getWechatQRCode(`${provider.owner}/${provider.name}`).then(
async res => {
if (res.status !== "ok") {
Setting.showMessage("error", res?.msg);
return;
}
const t1 = setInterval(await getEvent, 1000, application, provider, res.data2, method);
{Modal.info({
title: i18next.t("provider:Please use WeChat to scan the QR code and follow the official account for sign in"),
content: (
<div style={{marginRight: "34px"}}>
<img src = {"data:image/png;base64," + res.data} alt="Wechat QR code" style={{width: "100%"}} />
</div>
),
onOk() {
window.clearInterval(t1);
},
});}
}
);
}

View File

@ -21,6 +21,7 @@ import * as Provider from "../auth/Provider";
import * as AuthBackend from "../auth/AuthBackend";
import {goToWeb3Url} from "../auth/ProviderButton";
import AccountAvatar from "../account/AccountAvatar";
import {WechatOfficialAccountModal} from "../auth/Util";
class OAuthWidget extends React.Component {
constructor(props) {
@ -197,9 +198,19 @@ class OAuthWidget extends React.Component {
provider.category === "Web3" ? (
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id} onClick={() => goToWeb3Url(application, provider, "link")}>{i18next.t("user:Link")}</Button>
) : (
<a key={provider.displayName} href={user.id !== account.id ? null : Provider.getAuthUrl(application, provider, "link")}>
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id}>{i18next.t("user:Link")}</Button>
</a>
provider.type === "WeChat" && provider.clientId2 !== "" && provider.clientSecret2 !== "" && provider.disableSsl === true && !navigator.userAgent.includes("MicroMessenger") ? (
<a key={provider.displayName}>
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id} onClick={
() => {
WechatOfficialAccountModal(application, provider, "link");
}
}>{i18next.t("user:Link")}</Button>
</a>
) : (
<a key={provider.displayName} href={user.id !== account.id ? null : Provider.getAuthUrl(application, provider, "link")}>
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id}>{i18next.t("user:Link")}</Button>
</a>
)
)
) : (
<Button disabled={!providerItem.canUnlink && !Setting.isAdminUser(account)} style={{marginLeft: "20px", width: linkButtonWidth}} onClick={() => this.unlinkUser(provider.type, linkedValue)}>{i18next.t("user:Unlink")}</Button>