Compare commits

..

5 Commits

Author SHA1 Message Date
Tower He
bbf2db2e00 feat: support to use a different db schema for pg (#2281) 2023-09-01 18:02:13 +08:00
Yang Luo
0c7b911ce7 Fix enforcer edit page logic 2023-09-01 01:30:50 +08:00
Yang Luo
2cc55715ac Add app.conf existence check 2023-09-01 01:25:45 +08:00
Yang Luo
c829bf1769 Fix DummyPaymentProvider's return URL 2023-09-01 01:25:15 +08:00
Yang Luo
ec956c12ca Fix Email duplicated issue in update-user 2023-08-31 23:44:40 +08:00
9 changed files with 72 additions and 29 deletions

View File

@@ -151,7 +151,7 @@ func (adapter *Adapter) InitAdapter() error {
if adapter.Adapter == nil {
var dataSourceName string
if adapter.builtInAdapter() {
if adapter.isBuiltIn() {
dataSourceName = conf.GetConfigString("dataSourceName")
if adapter.DatabaseType == "mysql" {
dataSourceName = dataSourceName + adapter.Database
@@ -183,6 +183,14 @@ func (adapter *Adapter) InitAdapter() error {
var err error
engine, err := xorm.NewEngine(adapter.DatabaseType, dataSourceName)
if adapter.isBuiltIn() && adapter.DatabaseType == "postgres" {
schema := util.GetValueFromDataSourceName("search_path", dataSourceName)
if schema != "" {
engine.SetSchema(schema)
}
}
adapter.Adapter, err = xormadapter.NewAdapterByEngineWithTableName(engine, adapter.getTable(), adapter.TableNamePrefix)
if err != nil {
return err
@@ -211,7 +219,7 @@ func adapterChangeTrigger(oldName string, newName string) error {
return session.Commit()
}
func (adapter *Adapter) builtInAdapter() bool {
func (adapter *Adapter) isBuiltIn() bool {
if adapter.Owner != "built-in" {
return false
}

View File

@@ -419,7 +419,7 @@ func CheckUpdateUser(oldUser, user *User, lang string) string {
}
}
if oldUser.Email != user.Email {
if HasUserByField(user.Name, "email", user.Email) {
if HasUserByField(user.Owner, "email", user.Email) {
return i18n.Translate(lang, "check:Email already exists")
}
}

View File

@@ -18,12 +18,14 @@ import (
"database/sql"
"flag"
"fmt"
"os"
"regexp"
"runtime"
"strings"
"github.com/beego/beego"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/util"
xormadapter "github.com/casdoor/xorm-adapter/v3"
_ "github.com/denisenkom/go-mssqldb" // db = mssql
_ "github.com/go-sql-driver/mysql" // db = mysql
@@ -66,6 +68,17 @@ func InitConfig() {
}
func InitAdapter() {
if conf.GetConfigString("driverName") == "" {
if !util.FileExist("conf/app.conf") {
dir, err := os.Getwd()
if err != nil {
panic(err)
}
dir = strings.ReplaceAll(dir, "\\", "/")
panic(fmt.Sprintf("The Casdoor config file: \"app.conf\" was not found, it should be placed at: \"%s/conf/app.conf\"", dir))
}
}
if createDatabase {
err := createDatabaseForPostgres(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName(), conf.GetConfigString("dbName"))
if err != nil {
@@ -142,6 +155,21 @@ func createDatabaseForPostgres(driverName string, dataSourceName string, dbName
return err
}
}
schema := util.GetValueFromDataSourceName("search_path", dataSourceName)
if schema != "" {
db, err = sql.Open(driverName, dataSourceName)
if err != nil {
return err
}
defer db.Close()
_, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s;", schema))
if err != nil {
if !strings.Contains(err.Error(), "already exists") {
return err
}
}
}
return nil
} else {
@@ -174,6 +202,12 @@ func (a *Ormer) open() {
if err != nil {
panic(err)
}
if a.driverName == "postgres" {
schema := util.GetValueFromDataSourceName("search_path", dataSourceName)
if schema != "" {
engine.SetSchema(schema)
}
}
a.Engine = engine
}

View File

@@ -79,9 +79,7 @@ func (p *Permission) setEnforcerAdapter(enforcer *casbin.Enforcer) error {
}
}
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
driverName := conf.GetConfigString("driverName")
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
adapter, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, tableName, tableNamePrefix, true)
adapter, err := xormadapter.NewAdapterByEngineWithTableName(ormer.Engine, tableName, tableNamePrefix)
if err != nil {
return err
}

View File

@@ -14,10 +14,7 @@
package pp
import (
"fmt"
"net/http"
)
import "net/http"
type DummyPaymentProvider struct{}
@@ -27,8 +24,7 @@ func NewDummyPaymentProvider() (*DummyPaymentProvider, error) {
}
func (pp *DummyPaymentProvider) Pay(providerName string, productName string, payerName string, paymentName string, productDisplayName string, price float64, currency string, returnUrl string, notifyUrl string) (string, string, error) {
payUrl := fmt.Sprintf("/payments/%s/result", paymentName)
return payUrl, "", nil
return returnUrl, "", nil
}
func (pp *DummyPaymentProvider) Notify(request *http.Request, body []byte, authorityPublicKey string, orderId string) (*NotifyResult, error) {

View File

@@ -14,9 +14,7 @@
package pp
import (
"net/http"
)
import "net/http"
type PaymentState string

View File

@@ -23,6 +23,7 @@ import (
"math/rand"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
@@ -315,3 +316,13 @@ func ParseIdToString(input interface{}) (string, error) {
return "", fmt.Errorf("unsupported id type: %T", input)
}
}
func GetValueFromDataSourceName(key string, dataSourceName string) string {
reg := regexp.MustCompile(key + "=([^ ]+)")
matches := reg.FindStringSubmatch(dataSourceName)
if len(matches) >= 2 {
return matches[1]
}
return ""
}

View File

@@ -210,15 +210,13 @@ class PlanEditPage extends React.Component {
{Setting.getLabel(i18next.t("plan:Period"), i18next.t("plan:Period - Tooltip"))} :
</Col>
<Col span={22} >
<Select
defaultValue={this.state.plan.period === "" ? "Monthly" : this.state.plan.period}
onChange={value => {
this.updatePlanField("period", value);
}}
options={[
{value: "Monthly", label: "Monthly"},
{value: "Yearly", label: "Yearly"},
]}
<Select virtual={false} style={{width: "100%"}} value={this.state.plan.period} onChange={value => {
this.updatePlanField("period", value);
}}
options={[
{value: "Monthly", label: "Monthly"},
{value: "Yearly", label: "Yearly"},
]}
/>
</Col>
</Row>

View File

@@ -105,7 +105,7 @@ class PolicyTable extends React.Component {
AdapterBackend.getPolicies(this.props.enforcer.owner, this.props.enforcer.name)
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("adapter:Sync policies successfully"));
// Setting.showMessage("success", i18next.t("adapter:Sync policies successfully"));
const policyList = res.data;
policyList.map((policy, index) => {
@@ -175,7 +175,7 @@ class PolicyTable extends React.Component {
render: (text, record, index) => {
const editing = this.isEditing(index);
return (
editing ?
(editing && this.props.modelCfg) ?
<Select size={"small"} style={{width: "60px"}} options={Object.keys(this.props.modelCfg).reverse().map(item => Setting.getOption(item, item))} value={text} onChange={value => {
this.updateField(table, index, "Ptype", value);
}} />
@@ -209,7 +209,7 @@ class PolicyTable extends React.Component {
title: i18next.t("general:Action"),
dataIndex: "",
key: "op",
width: "130px",
width: "150px",
render: (text, record, index) => {
const editable = this.isEditing(index);
return editable ? (
@@ -247,7 +247,7 @@ class PolicyTable extends React.Component {
loading={this.state.loading}
title={() => (
<div>
<Button disabled={this.state.editingIndex !== "" || this.props.enforcer.adapter === "" || Setting.builtInObject(this.props.enforcer)} style={{marginRight: "5px"}} type="primary" size="small" onClick={() => this.addRow(table)}>{i18next.t("general:Add")}</Button>
<Button disabled={this.state.editingIndex !== "" || this.props.enforcer.model === "" || this.props.enforcer.adapter === "" || Setting.builtInObject(this.props.enforcer)} style={{marginRight: "5px"}} type="primary" size="small" onClick={() => this.addRow(table)}>{i18next.t("general:Add")}</Button>
</div>
)}
/>
@@ -257,7 +257,7 @@ class PolicyTable extends React.Component {
render() {
return (
<React.Fragment>
<Button disabled={this.state.editingIndex !== "" || this.props.enforcer.adapter === ""} style={{marginBottom: "10px", width: "150px"}} type="primary" onClick={() => {this.getPolicies();}}>
<Button disabled={this.state.editingIndex !== "" || this.props.enforcer.model === "" || this.props.enforcer.adapter === ""} style={{marginBottom: "10px", width: "150px"}} type="primary" onClick={() => {this.getPolicies();}}>
{i18next.t("general:Sync")}
</Button>
{