mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-19 08:20:33 +08:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ece060d03d | ||
![]() |
1276da4daa | ||
![]() |
616629ef99 | ||
![]() |
b633ecdcf2 | ||
![]() |
a12ba7fb85 | ||
![]() |
08a0092974 | ||
![]() |
bb04b10e8b | ||
![]() |
ea1414dfd0 | ||
![]() |
32a8a028d5 | ||
![]() |
0fe34c2f53 |
@@ -90,14 +90,24 @@ func (c *ApiController) GetApplication() {
|
||||
return
|
||||
}
|
||||
|
||||
if c.Input().Get("withKey") != "" && application.Cert != "" {
|
||||
if c.Input().Get("withKey") != "" && application != nil && application.Cert != "" {
|
||||
cert, err := object.GetCert(util.GetId(application.Owner, application.Cert))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
application.CertPublicKey = cert.Certificate
|
||||
if cert == nil {
|
||||
cert, err = object.GetCert(util.GetId(application.Organization, application.Cert))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if cert != nil {
|
||||
application.CertPublicKey = cert.Certificate
|
||||
}
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetMaskedApplication(application, userId))
|
||||
|
@@ -59,7 +59,7 @@ func tokenToResponse(token *object.Token) *Response {
|
||||
func (c *ApiController) HandleLoggedIn(application *object.Application, user *object.User, form *form.AuthForm) (resp *Response) {
|
||||
userId := user.GetId()
|
||||
|
||||
allowed, err := object.CheckAccessPermission(userId, application)
|
||||
allowed, err := object.CheckLoginPermission(userId, application)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error(), nil)
|
||||
return
|
||||
|
@@ -179,7 +179,7 @@ func (c *ApiController) NotifyPayment() {
|
||||
|
||||
body := c.Ctx.Input.RequestBody
|
||||
|
||||
payment, err := object.NotifyPayment(c.Ctx.Request, body, owner, paymentName)
|
||||
payment, err := object.NotifyPayment(body, owner, paymentName)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
|
@@ -156,7 +156,7 @@ func (c *ApiController) DeleteToken() {
|
||||
// @Success 200 {object} object.TokenWrapper The Response object
|
||||
// @Success 400 {object} object.TokenError The Response object
|
||||
// @Success 401 {object} object.TokenError The Response object
|
||||
// @router /login/oauth/access_token [post]
|
||||
// @router api/login/oauth/access_token [post]
|
||||
func (c *ApiController) GetOAuthToken() {
|
||||
grantType := c.Input().Get("grant_type")
|
||||
refreshToken := c.Input().Get("refresh_token")
|
||||
|
@@ -457,7 +457,16 @@ func (c *ApiController) SetPassword() {
|
||||
return
|
||||
}
|
||||
|
||||
if oldPassword != "" {
|
||||
isAdmin := c.IsAdmin()
|
||||
if isAdmin {
|
||||
if oldPassword != "" {
|
||||
msg := object.CheckPassword(targetUser, oldPassword, c.GetAcceptLanguage())
|
||||
if msg != "" {
|
||||
c.ResponseError(msg)
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msg := object.CheckPassword(targetUser, oldPassword, c.GetAcceptLanguage())
|
||||
if msg != "" {
|
||||
c.ResponseError(msg)
|
||||
|
@@ -33,10 +33,8 @@ type Cert struct {
|
||||
BitSize int `json:"bitSize"`
|
||||
ExpireInYears int `json:"expireInYears"`
|
||||
|
||||
Certificate string `xorm:"mediumtext" json:"certificate"`
|
||||
PrivateKey string `xorm:"mediumtext" json:"privateKey"`
|
||||
AuthorityPublicKey string `xorm:"mediumtext" json:"authorityPublicKey"`
|
||||
AuthorityRootPublicKey string `xorm:"mediumtext" json:"authorityRootPublicKey"`
|
||||
Certificate string `xorm:"mediumtext" json:"certificate"`
|
||||
PrivateKey string `xorm:"mediumtext" json:"privateKey"`
|
||||
}
|
||||
|
||||
func GetMaskedCert(cert *Cert) *Cert {
|
||||
|
BIN
object/cert.go~
Normal file
BIN
object/cert.go~
Normal file
Binary file not shown.
@@ -350,7 +350,7 @@ func CheckUserPermission(requestUserId, userId string, strict bool, lang string)
|
||||
return hasPermission, fmt.Errorf(i18n.Translate(lang, "auth:Unauthorized operation"))
|
||||
}
|
||||
|
||||
func CheckAccessPermission(userId string, application *Application) (bool, error) {
|
||||
func CheckLoginPermission(userId string, application *Application) (bool, error) {
|
||||
var err error
|
||||
if userId == "built-in/admin" {
|
||||
return true, nil
|
||||
@@ -361,32 +361,40 @@ func CheckAccessPermission(userId string, application *Application) (bool, error
|
||||
return false, err
|
||||
}
|
||||
|
||||
allowed := true
|
||||
allowCount := 0
|
||||
denyCount := 0
|
||||
for _, permission := range permissions {
|
||||
if !permission.IsEnabled {
|
||||
if !permission.IsEnabled || permission.ResourceType != "Application" || !permission.isResourceHit(application.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
isHit := false
|
||||
for _, resource := range permission.Resources {
|
||||
if application.Name == resource {
|
||||
isHit = true
|
||||
break
|
||||
}
|
||||
if permission.isUserHit(userId) {
|
||||
allowCount += 1
|
||||
}
|
||||
|
||||
if isHit {
|
||||
containsAsterisk := ContainsAsterisk(userId, permission.Users)
|
||||
if containsAsterisk {
|
||||
return true, err
|
||||
enforcer := getPermissionEnforcer(permission)
|
||||
|
||||
var isAllowed bool
|
||||
isAllowed, err = enforcer.Enforce(userId, application.Name, "Read")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if isAllowed {
|
||||
if permission.Effect == "Allow" {
|
||||
allowCount += 1
|
||||
}
|
||||
enforcer := getPermissionEnforcer(permission)
|
||||
if allowed, err = enforcer.Enforce(userId, application.Name, "read"); allowed {
|
||||
return allowed, err
|
||||
} else {
|
||||
if permission.Effect == "Deny" {
|
||||
denyCount += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return allowed, err
|
||||
|
||||
if denyCount > 0 {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func CheckUsername(username string, lang string) string {
|
||||
|
@@ -19,7 +19,6 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego"
|
||||
"github.com/beego/beego/context"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pquerna/otp"
|
||||
@@ -39,10 +38,11 @@ type TotpMfa struct {
|
||||
}
|
||||
|
||||
func (mfa *TotpMfa) Initiate(ctx *context.Context, userId string) (*MfaProps, error) {
|
||||
issuer := beego.AppConfig.String("appname")
|
||||
if issuer == "" {
|
||||
issuer = "casdoor"
|
||||
}
|
||||
//issuer := beego.AppConfig.String("appname")
|
||||
//if issuer == "" {
|
||||
// issuer = "casdoor"
|
||||
//}
|
||||
issuer := "casdoor"
|
||||
|
||||
key, err := totp.Generate(totp.GenerateOpts{
|
||||
Issuer: issuer,
|
||||
|
@@ -16,7 +16,6 @@ package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/casdoor/casdoor/pp"
|
||||
|
||||
@@ -153,7 +152,7 @@ func DeletePayment(payment *Payment) (bool, error) {
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func notifyPayment(request *http.Request, body []byte, owner string, paymentName string) (*Payment, *pp.NotifyResult, error) {
|
||||
func notifyPayment(body []byte, owner string, paymentName string) (*Payment, *pp.NotifyResult, error) {
|
||||
payment, err := getPayment(owner, paymentName)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -167,7 +166,7 @@ func notifyPayment(request *http.Request, body []byte, owner string, paymentName
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
pProvider, cert, err := provider.getPaymentProvider()
|
||||
pProvider, err := GetPaymentProvider(provider)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -181,7 +180,7 @@ func notifyPayment(request *http.Request, body []byte, owner string, paymentName
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
notifyResult, err := pProvider.Notify(request, body, cert.AuthorityPublicKey, payment.OutOrderId)
|
||||
notifyResult, err := pProvider.Notify(body, payment.OutOrderId)
|
||||
if err != nil {
|
||||
return payment, nil, err
|
||||
}
|
||||
@@ -202,8 +201,8 @@ func notifyPayment(request *http.Request, body []byte, owner string, paymentName
|
||||
return payment, notifyResult, nil
|
||||
}
|
||||
|
||||
func NotifyPayment(request *http.Request, body []byte, owner string, paymentName string) (*Payment, error) {
|
||||
payment, notifyResult, err := notifyPayment(request, body, owner, paymentName)
|
||||
func NotifyPayment(body []byte, owner string, paymentName string) (*Payment, error) {
|
||||
payment, notifyResult, err := notifyPayment(body, owner, paymentName)
|
||||
if payment != nil {
|
||||
if err != nil {
|
||||
payment.State = pp.PaymentStateError
|
||||
@@ -231,7 +230,7 @@ func invoicePayment(payment *Payment) (string, error) {
|
||||
return "", fmt.Errorf("the payment provider: %s does not exist", payment.Provider)
|
||||
}
|
||||
|
||||
pProvider, _, err := provider.getPaymentProvider()
|
||||
pProvider, err := GetPaymentProvider(provider)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@@ -61,10 +61,6 @@ type PermissionRule struct {
|
||||
|
||||
const builtInAvailableField = 5 // Casdoor built-in adapter, use V5 to filter permission, so has 5 available field
|
||||
|
||||
func (p *Permission) GetId() string {
|
||||
return util.GetId(p.Owner, p.Name)
|
||||
}
|
||||
|
||||
func GetPermissionCount(owner, field, value string) (int64, error) {
|
||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||
return session.Count(&Permission{})
|
||||
@@ -346,20 +342,6 @@ func GetPermissionsByModel(owner string, model string) ([]*Permission, error) {
|
||||
return permissions, nil
|
||||
}
|
||||
|
||||
func ContainsAsterisk(userId string, users []string) bool {
|
||||
containsAsterisk := false
|
||||
group, _ := util.GetOwnerAndNameFromId(userId)
|
||||
for _, user := range users {
|
||||
permissionGroup, permissionUserName := util.GetOwnerAndNameFromId(user)
|
||||
if permissionGroup == group && permissionUserName == "*" {
|
||||
containsAsterisk = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return containsAsterisk
|
||||
}
|
||||
|
||||
func GetMaskedPermissions(permissions []*Permission) []*Permission {
|
||||
for _, permission := range permissions {
|
||||
permission.Users = nil
|
||||
@@ -389,3 +371,27 @@ func GroupPermissionsByModelAdapter(permissions []*Permission) map[string][]stri
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (p *Permission) GetId() string {
|
||||
return util.GetId(p.Owner, p.Name)
|
||||
}
|
||||
|
||||
func (p *Permission) isUserHit(name string) bool {
|
||||
targetOrg, _ := util.GetOwnerAndNameFromId(name)
|
||||
for _, user := range p.Users {
|
||||
userOrg, userName := util.GetOwnerAndNameFromId(user)
|
||||
if userOrg == targetOrg && userName == "*" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Permission) isResourceHit(name string) bool {
|
||||
for _, resource := range p.Resources {
|
||||
if name == resource {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@@ -172,7 +172,7 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pProvider, _, err := provider.getPaymentProvider()
|
||||
pProvider, err := GetPaymentProvider(provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -17,31 +17,24 @@
|
||||
|
||||
package object
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/casdoor/casdoor/pp"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
func TestProduct(t *testing.T) {
|
||||
InitConfig()
|
||||
|
||||
product, _ := GetProduct("admin/product_123")
|
||||
provider, _ := getProvider(product.Owner, "provider_pay_alipay")
|
||||
cert, _ := getCert(product.Owner, "cert-pay-alipay")
|
||||
pProvider, err := pp.GetPaymentProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.Host, cert.Certificate, cert.PrivateKey, cert.AuthorityPublicKey, cert.AuthorityRootPublicKey, provider.ClientId2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
paymentName := util.GenerateTimeId()
|
||||
returnUrl := ""
|
||||
notifyUrl := ""
|
||||
payUrl, _, err := pProvider.Pay(provider.Name, product.Name, "alice", paymentName, product.DisplayName, product.Price, product.Currency, returnUrl, notifyUrl)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
println(payUrl)
|
||||
}
|
||||
//func TestProduct(t *testing.T) {
|
||||
// InitConfig()
|
||||
//
|
||||
// product, _ := GetProduct("admin/product_123")
|
||||
// provider, _ := getProvider(product.Owner, "provider_pay_alipay")
|
||||
// cert, _ := getCert(product.Owner, "cert-pay-alipay")
|
||||
// pProvider, err := pp.GetPaymentProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.Host, cert.Certificate, cert.PrivateKey, cert.AuthorityPublicKey, cert.AuthorityRootPublicKey, provider.ClientId2)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// paymentName := util.GenerateTimeId()
|
||||
// returnUrl := ""
|
||||
// notifyUrl := ""
|
||||
// payUrl, _, err := pProvider.Pay(provider.Name, product.Name, "alice", paymentName, product.DisplayName, product.Price, product.Currency, returnUrl, notifyUrl)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// println(payUrl)
|
||||
//}
|
||||
|
@@ -251,30 +251,69 @@ func DeleteProvider(provider *Provider) (bool, error) {
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func (p *Provider) getPaymentProvider() (pp.PaymentProvider, *Cert, error) {
|
||||
func GetPaymentProvider(p *Provider) (pp.PaymentProvider, error) {
|
||||
cert := &Cert{}
|
||||
if p.Cert != "" {
|
||||
var err error
|
||||
cert, err = getCert(p.Owner, p.Cert)
|
||||
cert, err = GetCert(util.GetId(p.Owner, p.Cert))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cert == nil {
|
||||
return nil, nil, fmt.Errorf("the cert: %s does not exist", p.Cert)
|
||||
return nil, fmt.Errorf("the cert: %s does not exist", p.Cert)
|
||||
}
|
||||
}
|
||||
|
||||
pProvider, err := pp.GetPaymentProvider(p.Type, p.ClientId, p.ClientSecret, p.Host, cert.Certificate, cert.PrivateKey, cert.AuthorityPublicKey, cert.AuthorityRootPublicKey, p.ClientId2)
|
||||
if err != nil {
|
||||
return nil, cert, err
|
||||
typ := p.Type
|
||||
if typ == "Dummy" {
|
||||
pp, err := pp.NewDummyPaymentProvider()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pp, nil
|
||||
} else if typ == "Alipay" {
|
||||
if p.Metadata != "" {
|
||||
// alipay provider store rootCert's name in metadata
|
||||
rootCert, err := GetCert(util.GetId(p.Owner, p.Metadata))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rootCert == nil {
|
||||
return nil, fmt.Errorf("the cert: %s does not exist", p.Metadata)
|
||||
}
|
||||
pp, err := pp.NewAlipayPaymentProvider(p.ClientId, cert.Certificate, cert.PrivateKey, rootCert.Certificate, rootCert.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pp, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("the metadata of alipay provider is empty")
|
||||
}
|
||||
} else if typ == "GC" {
|
||||
return pp.NewGcPaymentProvider(p.ClientId, p.ClientSecret, p.Host), nil
|
||||
} else if typ == "WeChat Pay" {
|
||||
pp, err := pp.NewWechatPaymentProvider(p.ClientId, p.ClientSecret, p.ClientId2, cert.Certificate, cert.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pp, nil
|
||||
} else if typ == "PayPal" {
|
||||
pp, err := pp.NewPaypalPaymentProvider(p.ClientId, p.ClientSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pp, nil
|
||||
} else if typ == "Stripe" {
|
||||
pp, err := pp.NewStripePaymentProvider(p.ClientId, p.ClientSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pp, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("the payment provider type: %s is not supported", p.Type)
|
||||
}
|
||||
|
||||
if pProvider == nil {
|
||||
return nil, cert, fmt.Errorf("the payment provider type: %s is not supported", p.Type)
|
||||
}
|
||||
|
||||
return pProvider, cert, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (p *Provider) GetId() string {
|
||||
|
@@ -15,6 +15,7 @@
|
||||
package object
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -31,7 +32,7 @@ type Credential struct {
|
||||
}
|
||||
|
||||
func (syncer *Syncer) getOriginalUsers() ([]*OriginalUser, error) {
|
||||
var results []map[string]string
|
||||
var results []map[string]sql.NullString
|
||||
err := syncer.Ormer.Engine.Table(syncer.getTable()).Find(&results)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@@ -15,6 +15,7 @@
|
||||
package object
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@@ -196,7 +197,7 @@ func (syncer *Syncer) getUserValue(user *User, key string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func (syncer *Syncer) getOriginalUsersFromMap(results []map[string]string) []*OriginalUser {
|
||||
func (syncer *Syncer) getOriginalUsersFromMap(results []map[string]sql.NullString) []*OriginalUser {
|
||||
users := []*OriginalUser{}
|
||||
for _, result := range results {
|
||||
originalUser := &OriginalUser{
|
||||
@@ -216,11 +217,11 @@ func (syncer *Syncer) getOriginalUsersFromMap(results []map[string]string) []*Or
|
||||
names := strings.Split(tableColumnName, "+")
|
||||
var values []string
|
||||
for _, name := range names {
|
||||
values = append(values, result[strings.Trim(name, " ")])
|
||||
values = append(values, result[strings.Trim(name, " ")].String)
|
||||
}
|
||||
value = strings.Join(values, " ")
|
||||
} else {
|
||||
value = result[tableColumnName]
|
||||
value = result[tableColumnName].String
|
||||
}
|
||||
syncer.setUserByKeyValue(originalUser, tableColumn.CasdoorName, value)
|
||||
}
|
||||
@@ -249,9 +250,9 @@ func (syncer *Syncer) getOriginalUsersFromMap(results []map[string]string) []*Or
|
||||
// enable
|
||||
value, ok := result["ENABLED"]
|
||||
if ok {
|
||||
originalUser.IsForbidden = !util.ParseBool(value)
|
||||
originalUser.IsForbidden = !util.ParseBool(value.String)
|
||||
} else {
|
||||
originalUser.IsForbidden = !util.ParseBool(result["enabled"])
|
||||
originalUser.IsForbidden = !util.ParseBool(result["enabled"].String)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -209,7 +209,7 @@ func GenerateCasToken(userId string, service string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
tmp := map[string]string{}
|
||||
tmp := map[string]interface{}{}
|
||||
err = json.Unmarshal(data, &tmp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -219,7 +219,7 @@ func GenerateCasToken(userId string, service string) (string, error) {
|
||||
if v != "" {
|
||||
authenticationSuccess.Attributes.UserAttributes.Attributes = append(authenticationSuccess.Attributes.UserAttributes.Attributes, &CasNamedAttribute{
|
||||
Name: k,
|
||||
Value: v,
|
||||
Value: fmt.Sprintf("%v", v),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
75
pp/alipay.go
75
pp/alipay.go
@@ -16,9 +16,9 @@ package pp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/go-pay/gopay"
|
||||
"github.com/go-pay/gopay/alipay"
|
||||
)
|
||||
@@ -28,6 +28,11 @@ type AlipayPaymentProvider struct {
|
||||
}
|
||||
|
||||
func NewAlipayPaymentProvider(appId string, appCertificate string, appPrivateKey string, authorityPublicKey string, authorityRootPublicKey string) (*AlipayPaymentProvider, error) {
|
||||
// clientId => appId
|
||||
// cert.Certificate => appCertificate
|
||||
// cert.PrivateKey => appPrivateKey
|
||||
// rootCert.Certificate => authorityPublicKey
|
||||
// rootCert.PrivateKey => authorityRootPublicKey
|
||||
pp := &AlipayPaymentProvider{}
|
||||
|
||||
client, err := alipay.NewClient(appId, appPrivateKey, true)
|
||||
@@ -46,54 +51,60 @@ func NewAlipayPaymentProvider(appId string, appCertificate string, appPrivateKey
|
||||
|
||||
func (pp *AlipayPaymentProvider) Pay(providerName string, productName string, payerName string, paymentName string, productDisplayName string, price float64, currency string, returnUrl string, notifyUrl string) (string, string, error) {
|
||||
// pp.Client.DebugSwitch = gopay.DebugOn
|
||||
|
||||
bm := gopay.BodyMap{}
|
||||
|
||||
bm.Set("providerName", providerName)
|
||||
bm.Set("productName", productName)
|
||||
|
||||
bm.Set("return_url", returnUrl)
|
||||
bm.Set("notify_url", notifyUrl)
|
||||
|
||||
bm.Set("subject", productDisplayName)
|
||||
pp.Client.SetReturnUrl(returnUrl)
|
||||
pp.Client.SetNotifyUrl(notifyUrl)
|
||||
bm.Set("subject", joinAttachString([]string{productName, productDisplayName, providerName}))
|
||||
bm.Set("out_trade_no", paymentName)
|
||||
bm.Set("total_amount", getPriceString(price))
|
||||
bm.Set("total_amount", priceFloat64ToString(price))
|
||||
|
||||
payUrl, err := pp.Client.TradePagePay(context.Background(), bm)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return payUrl, "", nil
|
||||
return payUrl, paymentName, nil
|
||||
}
|
||||
|
||||
func (pp *AlipayPaymentProvider) Notify(request *http.Request, body []byte, authorityPublicKey string, orderId string) (*NotifyResult, error) {
|
||||
bm, err := alipay.ParseNotifyToBodyMap(request)
|
||||
func (pp *AlipayPaymentProvider) Notify(body []byte, orderId string) (*NotifyResult, error) {
|
||||
bm := gopay.BodyMap{}
|
||||
bm.Set("out_trade_no", orderId)
|
||||
aliRsp, err := pp.Client.TradeQuery(context.Background(), bm)
|
||||
notifyResult := &NotifyResult{}
|
||||
if err != nil {
|
||||
errRsp := &alipay.ErrorResponse{}
|
||||
unmarshalErr := json.Unmarshal([]byte(err.Error()), errRsp)
|
||||
if unmarshalErr != nil {
|
||||
return nil, err
|
||||
}
|
||||
if errRsp.SubCode == "ACQ.TRADE_NOT_EXIST" {
|
||||
notifyResult.PaymentStatus = PaymentStateCanceled
|
||||
return notifyResult, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
providerName := bm.Get("providerName")
|
||||
productName := bm.Get("productName")
|
||||
|
||||
productDisplayName := bm.Get("subject")
|
||||
paymentName := bm.Get("out_trade_no")
|
||||
price := util.ParseFloat(bm.Get("total_amount"))
|
||||
|
||||
ok, err := alipay.VerifySignWithCert(authorityPublicKey, bm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
switch aliRsp.Response.TradeStatus {
|
||||
case "WAIT_BUYER_PAY":
|
||||
notifyResult.PaymentStatus = PaymentStateCreated
|
||||
return notifyResult, nil
|
||||
case "TRADE_CLOSED":
|
||||
notifyResult.PaymentStatus = PaymentStateTimeout
|
||||
return notifyResult, nil
|
||||
case "TRADE_SUCCESS":
|
||||
// skip
|
||||
default:
|
||||
notifyResult.PaymentStatus = PaymentStateError
|
||||
notifyResult.NotifyMessage = fmt.Sprintf("unexpected alipay trade state: %v", aliRsp.Response.TradeStatus)
|
||||
return notifyResult, nil
|
||||
}
|
||||
if !ok {
|
||||
return nil, err
|
||||
}
|
||||
notifyResult := &NotifyResult{
|
||||
productDisplayName, productName, providerName, _ := parseAttachString(aliRsp.Response.Subject)
|
||||
notifyResult = &NotifyResult{
|
||||
ProductName: productName,
|
||||
ProductDisplayName: productDisplayName,
|
||||
ProviderName: providerName,
|
||||
OrderId: orderId,
|
||||
PaymentStatus: PaymentStatePaid,
|
||||
Price: price,
|
||||
PaymentName: paymentName,
|
||||
Price: priceStringToFloat64(aliRsp.Response.TotalAmount),
|
||||
PaymentName: orderId,
|
||||
}
|
||||
return notifyResult, nil
|
||||
}
|
||||
|
@@ -14,8 +14,6 @@
|
||||
|
||||
package pp
|
||||
|
||||
import "net/http"
|
||||
|
||||
type DummyPaymentProvider struct{}
|
||||
|
||||
func NewDummyPaymentProvider() (*DummyPaymentProvider, error) {
|
||||
@@ -27,7 +25,7 @@ func (pp *DummyPaymentProvider) Pay(providerName string, productName string, pay
|
||||
return returnUrl, "", nil
|
||||
}
|
||||
|
||||
func (pp *DummyPaymentProvider) Notify(request *http.Request, body []byte, authorityPublicKey string, orderId string) (*NotifyResult, error) {
|
||||
func (pp *DummyPaymentProvider) Notify(body []byte, orderId string) (*NotifyResult, error) {
|
||||
return &NotifyResult{
|
||||
PaymentStatus: PaymentStatePaid,
|
||||
}, nil
|
||||
|
2
pp/gc.go
2
pp/gc.go
@@ -216,7 +216,7 @@ func (pp *GcPaymentProvider) Pay(providerName string, productName string, payerN
|
||||
return payRespInfo.PayUrl, "", nil
|
||||
}
|
||||
|
||||
func (pp *GcPaymentProvider) Notify(request *http.Request, body []byte, authorityPublicKey string, orderId string) (*NotifyResult, error) {
|
||||
func (pp *GcPaymentProvider) Notify(body []byte, orderId string) (*NotifyResult, error) {
|
||||
reqBody := GcRequestBody{}
|
||||
m, err := url.ParseQuery(string(body))
|
||||
if err != nil {
|
||||
|
@@ -18,7 +18,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
@@ -88,7 +87,7 @@ func (pp *PaypalPaymentProvider) Pay(providerName string, productName string, pa
|
||||
return ppRsp.Response.Links[1].Href, ppRsp.Response.Id, nil
|
||||
}
|
||||
|
||||
func (pp *PaypalPaymentProvider) Notify(request *http.Request, body []byte, authorityPublicKey string, orderId string) (*NotifyResult, error) {
|
||||
func (pp *PaypalPaymentProvider) Notify(body []byte, orderId string) (*NotifyResult, error) {
|
||||
notifyResult := &NotifyResult{}
|
||||
captureRsp, err := pp.Client.OrderCapture(context.Background(), orderId, nil)
|
||||
if err != nil {
|
||||
|
@@ -14,8 +14,6 @@
|
||||
|
||||
package pp
|
||||
|
||||
import "net/http"
|
||||
|
||||
type PaymentState string
|
||||
|
||||
const (
|
||||
@@ -42,45 +40,7 @@ type NotifyResult struct {
|
||||
|
||||
type PaymentProvider interface {
|
||||
Pay(providerName string, productName string, payerName string, paymentName string, productDisplayName string, price float64, currency string, returnUrl string, notifyUrl string) (string, string, error)
|
||||
Notify(request *http.Request, body []byte, authorityPublicKey string, orderId string) (*NotifyResult, error)
|
||||
Notify(body []byte, orderId string) (*NotifyResult, error)
|
||||
GetInvoice(paymentName string, personName string, personIdCard string, personEmail string, personPhone string, invoiceType string, invoiceTitle string, invoiceTaxId string) (string, error)
|
||||
GetResponseError(err error) string
|
||||
}
|
||||
|
||||
func GetPaymentProvider(typ string, clientId string, clientSecret string, host string, appCertificate string, appPrivateKey string, authorityPublicKey string, authorityRootPublicKey string, clientId2 string) (PaymentProvider, error) {
|
||||
if typ == "Dummy" {
|
||||
pp, err := NewDummyPaymentProvider()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pp, nil
|
||||
} else if typ == "Alipay" {
|
||||
pp, err := NewAlipayPaymentProvider(clientId, appCertificate, appPrivateKey, authorityPublicKey, authorityRootPublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pp, nil
|
||||
} else if typ == "GC" {
|
||||
return NewGcPaymentProvider(clientId, clientSecret, host), nil
|
||||
} else if typ == "WeChat Pay" {
|
||||
pp, err := NewWechatPaymentProvider(clientId, clientSecret, clientId2, appCertificate, appPrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pp, nil
|
||||
} else if typ == "PayPal" {
|
||||
pp, err := NewPaypalPaymentProvider(clientId, clientSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pp, nil
|
||||
} else if typ == "Stripe" {
|
||||
pp, err := NewStripePaymentProvider(clientId, clientSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pp, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
@@ -16,7 +16,6 @@ package pp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
@@ -94,7 +93,7 @@ func (pp *StripePaymentProvider) Pay(providerName string, productName string, pa
|
||||
return sCheckout.URL, sCheckout.ID, nil
|
||||
}
|
||||
|
||||
func (pp *StripePaymentProvider) Notify(request *http.Request, body []byte, authorityPublicKey string, orderId string) (*NotifyResult, error) {
|
||||
func (pp *StripePaymentProvider) Notify(body []byte, orderId string) (*NotifyResult, error) {
|
||||
notifyResult := &NotifyResult{}
|
||||
sCheckout, err := stripeCheckout.Get(orderId, nil)
|
||||
if err != nil {
|
||||
|
@@ -49,3 +49,11 @@ func priceFloat64ToInt64(price float64) int64 {
|
||||
func priceFloat64ToString(price float64) string {
|
||||
return strconv.FormatFloat(price, 'f', 2, 64)
|
||||
}
|
||||
|
||||
func priceStringToFloat64(price string) float64 {
|
||||
f, err := strconv.ParseFloat(price, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/go-pay/gopay"
|
||||
@@ -87,7 +86,7 @@ func (pp *WechatPaymentProvider) Pay(providerName string, productName string, pa
|
||||
return nativeRsp.Response.CodeUrl, paymentName, nil // Wechat can use paymentName as the OutTradeNo to query order status
|
||||
}
|
||||
|
||||
func (pp *WechatPaymentProvider) Notify(request *http.Request, body []byte, authorityPublicKey string, orderId string) (*NotifyResult, error) {
|
||||
func (pp *WechatPaymentProvider) Notify(body []byte, orderId string) (*NotifyResult, error) {
|
||||
notifyResult := &NotifyResult{}
|
||||
queryRsp, err := pp.Client.V3TransactionQueryOrder(context.Background(), wechat.OutTradeNo, orderId)
|
||||
if err != nil {
|
||||
|
@@ -40,6 +40,13 @@ func CorsFilter(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.Request.RequestURI == "/api/userinfo" {
|
||||
ctx.Output.Header(headerAllowOrigin, origin)
|
||||
ctx.Output.Header(headerAllowMethods, "POST, GET, OPTIONS, DELETE")
|
||||
ctx.Output.Header(headerAllowHeaders, "Content-Type, Authorization")
|
||||
return
|
||||
}
|
||||
|
||||
if origin != "" && originConf != "" && origin != originConf {
|
||||
ok, err := object.IsOriginAllowed(origin)
|
||||
if err != nil {
|
||||
|
@@ -247,10 +247,10 @@ func initAPI() {
|
||||
beego.Router("/api/send-sms", &controllers.ApiController{}, "POST:SendSms")
|
||||
beego.Router("/api/send-notification", &controllers.ApiController{}, "POST:SendNotification")
|
||||
|
||||
beego.Router("/api/webauthn/signup/begin", &controllers.ApiController{}, "Get:WebAuthnSignupBegin")
|
||||
beego.Router("/api/webauthn/signup/finish", &controllers.ApiController{}, "Post:WebAuthnSignupFinish")
|
||||
beego.Router("/api/webauthn/signin/begin", &controllers.ApiController{}, "Get:WebAuthnSigninBegin")
|
||||
beego.Router("/api/webauthn/signin/finish", &controllers.ApiController{}, "Post:WebAuthnSigninFinish")
|
||||
beego.Router("/api/webauthn/signup/begin", &controllers.ApiController{}, "GET:WebAuthnSignupBegin")
|
||||
beego.Router("/api/webauthn/signup/finish", &controllers.ApiController{}, "POST:WebAuthnSignupFinish")
|
||||
beego.Router("/api/webauthn/signin/begin", &controllers.ApiController{}, "GET:WebAuthnSigninBegin")
|
||||
beego.Router("/api/webauthn/signin/finish", &controllers.ApiController{}, "POST:WebAuthnSigninFinish")
|
||||
|
||||
beego.Router("/api/mfa/setup/initiate", &controllers.ApiController{}, "POST:MfaSetupInitiate")
|
||||
beego.Router("/api/mfa/setup/verify", &controllers.ApiController{}, "POST:MfaSetupVerify")
|
||||
|
@@ -101,7 +101,7 @@ class PaymentResultPage extends React.Component {
|
||||
payment: payment,
|
||||
});
|
||||
if (payment.state === "Created") {
|
||||
if (["PayPal", "Stripe"].includes(payment.type)) {
|
||||
if (["PayPal", "Stripe", "Alipay"].includes(payment.type)) {
|
||||
this.setState({
|
||||
timeout: setTimeout(async() => {
|
||||
await PaymentBackend.notifyPayment(this.state.owner, this.state.paymentName);
|
||||
|
@@ -1111,6 +1111,22 @@ class ProviderEditPage extends React.Component {
|
||||
</Row>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
(this.state.provider.type === "Alipay") ? (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Root Cert"), i18next.t("general:Root Cert - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.provider.metadata} onChange={(value => {this.updateProviderField("metadata", value);})}>
|
||||
{
|
||||
this.state.certs.map((cert, index) => <Option key={index} value={cert.name}>{cert.name}</Option>)
|
||||
}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
this.state.provider.type === "Web3Onboard" ? (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
|
Reference in New Issue
Block a user