fix: improve random handling

This commit is contained in:
Yang Luo
2026-04-05 09:42:52 +08:00
parent f6a3fb9455
commit 1e7a2d8dad
11 changed files with 88 additions and 89 deletions

View File

@@ -37,7 +37,6 @@ import (
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/proxy"
"github.com/casdoor/casdoor/util"
"github.com/google/uuid"
"golang.org/x/oauth2"
)
@@ -938,14 +937,7 @@ func (c *ApiController) Login() {
}
if tmpUser != nil {
var uid uuid.UUID
uid, err = uuid.NewRandom()
if err != nil {
c.ResponseError(err.Error())
return
}
uidStr := strings.Split(uid.String(), "-")
uidStr := strings.Split(util.GenerateUUID(), "-")
userInfo.Username = fmt.Sprintf("%s_%s", userInfo.Username, uidStr[1])
}

View File

@@ -19,7 +19,6 @@ import (
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/util"
"github.com/google/uuid"
)
// MfaSetupInitiate
@@ -77,7 +76,7 @@ func (c *ApiController) MfaSetupInitiate() {
return
}
recoveryCode := uuid.NewString()
recoveryCode := util.GenerateUUID()
mfaProps.RecoveryCodes = []string{recoveryCode}
mfaProps.MfaRememberInHours = organization.MfaRememberInHours

View File

@@ -26,7 +26,7 @@ import (
"strings"
"time"
"github.com/google/uuid"
"github.com/casdoor/casdoor/util"
)
const (
@@ -141,7 +141,7 @@ func (a *AzureACSEmailProvider) Send(fromAddress string, fromName string, toAddr
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("repeatability-request-id", uuid.New().String())
req.Header.Set("repeatability-request-id", util.GenerateUUID())
req.Header.Set("repeatability-first-sent", time.Now().UTC().Format(http.TimeFormat))
client := &http.Client{}

View File

@@ -21,7 +21,7 @@ import (
"time"
"github.com/casdoor/casdoor/notification"
"github.com/google/uuid"
"github.com/casdoor/casdoor/util"
)
type PushMfa struct {
@@ -111,7 +111,7 @@ func (mfa *PushMfa) sendPushNotification(title string, message string) error {
// Generate a unique challenge ID for this notification
// Note: In a full implementation, this would be stored in a cache/database
// to validate callbacks from the mobile app
mfa.challengeId = uuid.NewString()
mfa.challengeId = util.GenerateUUID()
mfa.challengeExp = time.Now().Add(5 * time.Minute) // Challenge expires in 5 minutes
// Get the notification provider

View File

@@ -31,8 +31,8 @@ import (
"time"
"github.com/beevik/etree"
"github.com/casdoor/casdoor/util"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
saml "github.com/russellhaering/gosaml2"
dsig "github.com/russellhaering/goxmldsig"
)
@@ -50,7 +50,7 @@ func NewSamlResponse(application *Application, user *User, host string, certific
samlResponse.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
samlResponse.CreateAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
samlResponse.CreateAttr("xmlns:xs", "http://www.w3.org/2001/XMLSchema")
arId := uuid.New()
arId := util.GenerateUUID()
samlResponse.CreateAttr("ID", fmt.Sprintf("_%s", arId))
samlResponse.CreateAttr("Version", "2.0")
@@ -65,7 +65,7 @@ func NewSamlResponse(application *Application, user *User, host string, certific
assertion.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
assertion.CreateAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
assertion.CreateAttr("xmlns:xs", "http://www.w3.org/2001/XMLSchema")
assertion.CreateAttr("ID", fmt.Sprintf("_%s", uuid.New()))
assertion.CreateAttr("ID", fmt.Sprintf("_%s", util.GenerateUUID()))
assertion.CreateAttr("Version", "2.0")
assertion.CreateAttr("IssueInstant", now)
assertion.CreateElement("saml:Issuer").SetText(host)
@@ -100,7 +100,7 @@ func NewSamlResponse(application *Application, user *User, host string, certific
}
authnStatement := assertion.CreateElement("saml:AuthnStatement")
authnStatement.CreateAttr("AuthnInstant", now)
authnStatement.CreateAttr("SessionIndex", fmt.Sprintf("_%s", uuid.New()))
authnStatement.CreateAttr("SessionIndex", fmt.Sprintf("_%s", util.GenerateUUID()))
authnStatement.CreateAttr("SessionNotOnOrAfter", expireTime)
authnStatement.CreateElement("saml:AuthnContext").CreateElement("saml:AuthnContextClassRef").SetText("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport")
@@ -460,7 +460,7 @@ func NewSamlResponse11(application *Application, user *User, requestID string, h
samlResponse.CreateAttr("MajorVersion", "1")
samlResponse.CreateAttr("MinorVersion", "1")
responseID := uuid.New()
responseID := util.GenerateUUID()
samlResponse.CreateAttr("ResponseID", fmt.Sprintf("_%s", responseID))
samlResponse.CreateAttr("InResponseTo", requestID)
@@ -476,7 +476,7 @@ func NewSamlResponse11(application *Application, user *User, requestID string, h
assertion.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:1.0:assertion")
assertion.CreateAttr("MajorVersion", "1")
assertion.CreateAttr("MinorVersion", "1")
assertion.CreateAttr("AssertionID", uuid.New().String())
assertion.CreateAttr("AssertionID", util.GenerateUUID())
assertion.CreateAttr("Issuer", host)
assertion.CreateAttr("IssueInstant", now)

View File

@@ -16,9 +16,7 @@ package object
import (
"fmt"
"math/rand"
"strings"
"time"
"github.com/casdoor/casdoor/util"
"github.com/xorm-io/core"
@@ -234,8 +232,7 @@ func (site *Site) GetChallengeMap() map[string]string {
func (site *Site) GetHost() string {
if len(site.Hosts) != 0 {
rand.Seed(time.Now().UnixNano())
return site.Hosts[rand.Intn(len(site.Hosts))]
return site.Hosts[util.RandomIntn(len(site.Hosts))]
}
if site.Host != "" {

View File

@@ -21,7 +21,7 @@ import (
"encoding/pem"
"encoding/xml"
"fmt"
"math/rand"
"math"
"strings"
"sync"
"time"
@@ -273,7 +273,7 @@ func GenerateCasToken(userId string, service string) (string, error) {
}
}
st := fmt.Sprintf("ST-%d", rand.Int())
st := fmt.Sprintf("ST-%d", util.RandomIntn(math.MaxInt))
stToServiceResponse.Store(st, &CasAuthenticationSuccessWrapper{
AuthenticationSuccess: &authenticationSuccess,
Service: service,

View File

@@ -28,7 +28,6 @@ import (
"github.com/casdoor/casdoor/i18n"
"github.com/casdoor/casdoor/idp"
"github.com/casdoor/casdoor/util"
"github.com/google/uuid"
"github.com/xorm-io/core"
)
@@ -742,12 +741,7 @@ func createGuestUserToken(application *Application, clientSecret string, verifie
// generateGuestUsername generates a unique username for guest users
func generateGuestUsername() string {
uid, err := uuid.NewRandom()
if err != nil {
// Fallback to a timestamp-based unique ID if UUID generation fails
return fmt.Sprintf("guest_%d", time.Now().UnixNano())
}
return fmt.Sprintf("guest_%s", uid.String())
return fmt.Sprintf("guest_%s", util.GenerateUUID())
}
// GetAuthorizationCodeToken

View File

@@ -15,10 +15,11 @@
package object
import (
"crypto/rand"
"errors"
"fmt"
"math"
"math/rand"
"math/big"
"net/url"
"regexp"
"strconv"
@@ -476,10 +477,13 @@ func GetVerifyType(username string) (verificationCodeType string) {
var stdNums = []byte("0123456789")
func getRandomCode(length int) string {
var result []byte
r := rand.New(rand.NewSource(time.Now().UnixNano()))
result := make([]byte, length)
for i := 0; i < length; i++ {
result = append(result, stdNums[r.Intn(len(stdNums))])
n, err := rand.Int(rand.Reader, big.NewInt(int64(len(stdNums))))
if err != nil {
panic(err)
}
result[i] = stdNums[n.Int64()]
}
return string(result)
}

View File

@@ -14,7 +14,13 @@
package util
import "github.com/thanhpk/randstr"
import (
"crypto/rand"
"math/big"
"github.com/google/uuid"
"github.com/thanhpk/randstr"
)
func GenerateClientId() string {
return randstr.Hex(10)
@@ -27,3 +33,57 @@ func GenerateClientSecret() string {
func GeneratePasswordSalt() string {
return randstr.Hex(10)
}
// RandomIntn returns a cryptographically secure random int in [0, n).
func RandomIntn(n int) int {
val, err := rand.Int(rand.Reader, big.NewInt(int64(n)))
if err != nil {
panic(err)
}
return int(val.Int64())
}
// GenerateUUID returns a random UUID v4 string.
func GenerateUUID() string {
return uuid.NewString()
}
// RandomStringFromCharset returns a cryptographically secure random string
// of the given length drawn from charset.
func RandomStringFromCharset(charset string, length int) string {
result := make([]byte, length)
for i := range result {
result[i] = charset[RandomIntn(len(charset))]
}
return string(result)
}
func GetRandomName() string {
return RandomStringFromCharset("0123456789abcdefghijklmnopqrstuvwxyz", 6)
}
func generateRandomString(length int) (string, error) {
return RandomStringFromCharset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", length), nil
}
func GenerateTwoUniqueRandomStrings() (string, string, error) {
len1 := 16 + int(big.NewInt(17).Int64())
len2 := 16 + int(big.NewInt(17).Int64())
str1, err := generateRandomString(len1)
if err != nil {
return "", "", err
}
str2, err := generateRandomString(len2)
if err != nil {
return "", "", err
}
for str1 == str2 {
str2, err = generateRandomString(len2)
if err != nil {
return "", "", err
}
}
return str1, str2, nil
}

View File

@@ -20,8 +20,6 @@ import (
"encoding/hex"
"errors"
"fmt"
"math/big"
"math/rand"
"os"
"path/filepath"
"regexp"
@@ -30,7 +28,6 @@ import (
"time"
"unicode"
"github.com/google/uuid"
"github.com/nyaruka/phonenumbers"
)
@@ -167,7 +164,7 @@ func GetSharedOrgFromApp(rawName string) (name string, organization string) {
}
func GenerateId() string {
return uuid.NewString()
return GenerateUUID()
}
func GenerateTimeId() string {
@@ -175,7 +172,7 @@ func GenerateTimeId() string {
tm := time.Unix(timestamp, 0)
t := tm.Format("20060102_150405")
random := uuid.NewString()[0:7]
random := GenerateUUID()[0:7]
res := fmt.Sprintf("%s_%s", t, random)
return res
@@ -189,16 +186,6 @@ func GenerateSimpleTimeId() string {
return t
}
func GetRandomName() string {
rand.Seed(time.Now().UnixNano())
const charset = "0123456789abcdefghijklmnopqrstuvwxyz"
result := make([]byte, 6)
for i := range result {
result[i] = charset[rand.Intn(len(charset))]
}
return string(result)
}
func GetId(owner, name string) string {
return fmt.Sprintf("%s/%s", owner, name)
}
@@ -355,7 +342,7 @@ func GetValueFromDataSourceName(key string, dataSourceName string) string {
func GetUsernameFromEmail(email string) string {
tokens := strings.Split(email, "@")
if len(tokens) == 0 {
return uuid.NewString()
return GenerateUUID()
} else {
return tokens[0]
}
@@ -394,37 +381,3 @@ func StringToInterfaceArray2d(arrays [][]string) [][]interface{} {
}
return interfaceArrays
}
func generateRandomString(length int) (string, error) {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b := make([]byte, length)
for i := range b {
var c byte
index := rand.Intn(len(charset))
c = charset[index]
b[i] = c
}
return string(b), nil
}
func GenerateTwoUniqueRandomStrings() (string, string, error) {
len1 := 16 + int(big.NewInt(17).Int64())
len2 := 16 + int(big.NewInt(17).Int64())
str1, err := generateRandomString(len1)
if err != nil {
return "", "", err
}
str2, err := generateRandomString(len2)
if err != nil {
return "", "", err
}
for str1 == str2 {
str2, err = generateRandomString(len2)
if err != nil {
return "", "", err
}
}
return str1, str2, nil
}