mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-21 19:40:41 +08:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4ea482223d | ||
![]() |
d55ae7d1d2 | ||
![]() |
d72e00605f | ||
![]() |
be74cb621f | ||
![]() |
13404d6035 | ||
![]() |
afa9c530ad | ||
![]() |
1600615aca |
82
captcha/geetest.go
Normal file
82
captcha/geetest.go
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright 2022 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
const GEETESTCaptchaVerifyUrl = "http://gcaptcha4.geetest.com/validate"
|
||||
|
||||
type GEETESTCaptchaProvider struct {
|
||||
}
|
||||
|
||||
func NewGEETESTCaptchaProvider() *GEETESTCaptchaProvider {
|
||||
captcha := &GEETESTCaptchaProvider{}
|
||||
return captcha
|
||||
}
|
||||
|
||||
func (captcha *GEETESTCaptchaProvider) VerifyCaptcha(token, clientSecret string) (bool, error) {
|
||||
pathData, err := url.ParseQuery(token)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
signToken := util.GetHmacSha256(clientSecret, pathData["lot_number"][0])
|
||||
|
||||
formData := make(url.Values)
|
||||
formData["lot_number"] = []string{pathData["lot_number"][0]}
|
||||
formData["captcha_output"] = []string{pathData["captcha_output"][0]}
|
||||
formData["pass_token"] = []string{pathData["pass_token"][0]}
|
||||
formData["gen_time"] = []string{pathData["gen_time"][0]}
|
||||
formData["sign_token"] = []string{signToken}
|
||||
captchaId := pathData["captcha_id"][0]
|
||||
|
||||
cli := http.Client{Timeout: time.Second * 5}
|
||||
resp, err := cli.PostForm(fmt.Sprintf("%s?captcha_id=%s", GEETESTCaptchaVerifyUrl, captchaId), formData)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
return false, err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
type captchaResponse struct {
|
||||
Result string `json:"result"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
captchaResp := &captchaResponse{}
|
||||
err = json.Unmarshal(body, captchaResp)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if captchaResp.Result == "success" {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, errors.New(captchaResp.Reason)
|
||||
}
|
@@ -27,6 +27,8 @@ func GetCaptchaProvider(captchaType string) CaptchaProvider {
|
||||
return NewHCaptchaProvider()
|
||||
} else if captchaType == "Aliyun Captcha" {
|
||||
return NewAliyunCaptchaProvider()
|
||||
} else if captchaType == "GEETEST" {
|
||||
return NewGEETESTCaptchaProvider()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -119,10 +119,12 @@ func (c *ApiController) GetUser() {
|
||||
user = object.GetUser(id)
|
||||
}
|
||||
|
||||
roles := object.GetRolesByUser(user.GetId())
|
||||
user.Roles = roles
|
||||
permissions := object.GetPermissionsByUser(user.GetId())
|
||||
user.Permissions = permissions
|
||||
if user != nil {
|
||||
roles := object.GetRolesByUser(user.GetId())
|
||||
user.Roles = roles
|
||||
permissions := object.GetPermissionsByUser(user.GetId())
|
||||
user.Permissions = permissions
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedUser(user)
|
||||
c.ServeJSON()
|
||||
|
2
go.mod
2
go.mod
@@ -14,6 +14,7 @@ require (
|
||||
github.com/casdoor/goth v1.69.0-FIX2
|
||||
github.com/casdoor/oss v1.2.0
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc
|
||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b
|
||||
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
|
||||
github.com/go-ldap/ldap/v3 v3.3.0
|
||||
@@ -23,6 +24,7 @@ require (
|
||||
github.com/google/uuid v1.2.0
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
github.com/lestrrat-go/jwx v0.9.0
|
||||
github.com/lib/pq v1.8.0
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
|
||||
github.com/qiangmzsx/string-adapter/v2 v2.1.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
|
2
go.sum
2
go.sum
@@ -125,6 +125,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f h1:q/DpyjJjZs94bziQ7YkBmIlpqbVP7yw179rnzoNVX1M=
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f/go.mod h1:QGrK8vMWWHQYQ3QU9bw9Y9OPNfxccGzfb41qjvVeXtY=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b h1:L63RATZFZuFMXy6ixnKmv3eNAXwYQF6HW1vd4IYsQqQ=
|
||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b/go.mod h1:EYSpSkwoEcryMmQGfhol2IiB3IMN9IIIaNd/wcAQMGQ=
|
||||
@@ -173,6 +174,7 @@ github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptG
|
||||
github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
|
@@ -21,9 +21,10 @@ import (
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
//_ "github.com/denisenkom/go-mssqldb" // db = mssql
|
||||
_ "github.com/go-sql-driver/mysql" // db = mysql
|
||||
//_ "github.com/lib/pq" // db = postgres
|
||||
_ "github.com/denisenkom/go-mssqldb" // db = mssql
|
||||
_ "github.com/go-sql-driver/mysql" // db = mysql
|
||||
_ "github.com/lib/pq" // db = postgres
|
||||
//_ "github.com/mattn/go-sqlite3" // db = sqlite3
|
||||
"xorm.io/core"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
@@ -17,7 +17,9 @@ package util
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
func GetHmacSha1(keyStr, value string) string {
|
||||
@@ -28,3 +30,10 @@ func GetHmacSha1(keyStr, value string) string {
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func GetHmacSha256(key string, data string) string {
|
||||
mac := hmac.New(sha256.New, []byte(key))
|
||||
mac.Write([]byte(data))
|
||||
|
||||
return hex.EncodeToString(mac.Sum(nil))
|
||||
}
|
||||
|
@@ -208,6 +208,8 @@ class ProviderEditPage extends React.Component {
|
||||
this.updateProviderField("domain", Setting.getFullServerUrl());
|
||||
} else if (value === "SAML") {
|
||||
this.updateProviderField("type", "Aliyun IDaaS");
|
||||
} else if (value === "Payment") {
|
||||
this.updateProviderField("type", "Alipay");
|
||||
} else if (value === "Captcha") {
|
||||
this.updateProviderField("type", "Default");
|
||||
}
|
||||
|
@@ -122,6 +122,10 @@ export const OtherProviderInfo = {
|
||||
"Aliyun Captcha": {
|
||||
logo: `${StaticBaseUrl}/img/social_aliyun.png`,
|
||||
url: "https://help.aliyun.com/product/28308.html",
|
||||
},
|
||||
"GEETEST": {
|
||||
logo: `${StaticBaseUrl}/img/social_geetest.png`,
|
||||
url: "https://www.geetest.com",
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -615,6 +619,7 @@ export function getProviderTypeOptions(category) {
|
||||
{id: "reCAPTCHA", name: "reCAPTCHA"},
|
||||
{id: "hCaptcha", name: "hCaptcha"},
|
||||
{id: "Aliyun Captcha", name: "Aliyun Captcha"},
|
||||
{id: "GEETEST", name: "GEETEST"},
|
||||
]);
|
||||
} else {
|
||||
return [];
|
||||
|
@@ -117,7 +117,7 @@ class PromptPage extends React.Component {
|
||||
<div>
|
||||
{
|
||||
(application === null || this.state.user === null) ? null : (
|
||||
application?.providers.filter(providerItem => Setting.isProviderPrompted(providerItem)).map((providerItem, index) => <OAuthWidget key={providerItem.name} labelSpan={6} user={this.state.user} application={application} providerItem={providerItem} onUnlinked={() => {return this.unlinked();}} />)
|
||||
application?.providers.filter(providerItem => Setting.isProviderPrompted(providerItem)).map((providerItem, index) => <OAuthWidget key={providerItem.name} labelSpan={6} user={this.state.user} application={application} providerItem={providerItem} account={this.props.account} onUnlinked={() => {return this.unlinked();}} />)
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
@@ -25,7 +25,7 @@ export const CaptchaWidget = ({captchaType, subType, siteKey, clientSecret, onCh
|
||||
|
||||
useEffect(() => {
|
||||
switch (captchaType) {
|
||||
case "reCAPTCHA":
|
||||
case "reCAPTCHA": {
|
||||
const reTimer = setInterval(() => {
|
||||
if (!window.grecaptcha) {
|
||||
loadScript("https://recaptcha.net/recaptcha/api.js");
|
||||
@@ -39,7 +39,8 @@ export const CaptchaWidget = ({captchaType, subType, siteKey, clientSecret, onCh
|
||||
}
|
||||
}, 300);
|
||||
break;
|
||||
case "hCaptcha":
|
||||
}
|
||||
case "hCaptcha": {
|
||||
const hTimer = setInterval(() => {
|
||||
if (!window.hcaptcha) {
|
||||
loadScript("https://js.hcaptcha.com/1/api.js");
|
||||
@@ -53,7 +54,8 @@ export const CaptchaWidget = ({captchaType, subType, siteKey, clientSecret, onCh
|
||||
}
|
||||
}, 300);
|
||||
break;
|
||||
case "Aliyun Captcha":
|
||||
}
|
||||
case "Aliyun Captcha": {
|
||||
const AWSCTimer = setInterval(() => {
|
||||
if (!window.AWSC) {
|
||||
loadScript("https://g.alicdn.com/AWSC/AWSC/awsc.js");
|
||||
@@ -76,6 +78,33 @@ export const CaptchaWidget = ({captchaType, subType, siteKey, clientSecret, onCh
|
||||
}
|
||||
}, 300);
|
||||
break;
|
||||
}
|
||||
case "GEETEST": {
|
||||
let getLock = false;
|
||||
const gTimer = setInterval(() => {
|
||||
if (!window.initGeetest4) {
|
||||
loadScript("https://static.geetest.com/v4/gt4.js");
|
||||
}
|
||||
if (window.initGeetest4 && siteKey && !getLock) {
|
||||
const captchaId = String(siteKey);
|
||||
window.initGeetest4({
|
||||
captchaId,
|
||||
product: "float",
|
||||
}, function(captchaObj) {
|
||||
if (!getLock) {
|
||||
captchaObj.appendTo("#captcha");
|
||||
getLock = true;
|
||||
}
|
||||
captchaObj.onSuccess(function() {
|
||||
const result = captchaObj.getValidate();
|
||||
onChange(`lot_number=${result.lot_number}&captcha_output=${result.captcha_output}&pass_token=${result.pass_token}&gen_time=${result.gen_time}&captcha_id=${siteKey}`);
|
||||
});
|
||||
});
|
||||
clearInterval(gTimer);
|
||||
}
|
||||
}, 500);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user