forked from casdoor/casdoor
fix: improve random handling
This commit is contained in:
@@ -37,7 +37,6 @@ import (
|
|||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/proxy"
|
"github.com/casdoor/casdoor/proxy"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/google/uuid"
|
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -938,14 +937,7 @@ func (c *ApiController) Login() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tmpUser != nil {
|
if tmpUser != nil {
|
||||||
var uid uuid.UUID
|
uidStr := strings.Split(util.GenerateUUID(), "-")
|
||||||
uid, err = uuid.NewRandom()
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
uidStr := strings.Split(uid.String(), "-")
|
|
||||||
userInfo.Username = fmt.Sprintf("%s_%s", userInfo.Username, uidStr[1])
|
userInfo.Username = fmt.Sprintf("%s_%s", userInfo.Username, uidStr[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import (
|
|||||||
|
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MfaSetupInitiate
|
// MfaSetupInitiate
|
||||||
@@ -77,7 +76,7 @@ func (c *ApiController) MfaSetupInitiate() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
recoveryCode := uuid.NewString()
|
recoveryCode := util.GenerateUUID()
|
||||||
mfaProps.RecoveryCodes = []string{recoveryCode}
|
mfaProps.RecoveryCodes = []string{recoveryCode}
|
||||||
mfaProps.MfaRememberInHours = organization.MfaRememberInHours
|
mfaProps.MfaRememberInHours = organization.MfaRememberInHours
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/casdoor/casdoor/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -141,7 +141,7 @@ func (a *AzureACSEmailProvider) Send(fromAddress string, fromName string, toAddr
|
|||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
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))
|
req.Header.Set("repeatability-first-sent", time.Now().UTC().Format(http.TimeFormat))
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/notification"
|
"github.com/casdoor/casdoor/notification"
|
||||||
"github.com/google/uuid"
|
"github.com/casdoor/casdoor/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PushMfa struct {
|
type PushMfa struct {
|
||||||
@@ -111,7 +111,7 @@ func (mfa *PushMfa) sendPushNotification(title string, message string) error {
|
|||||||
// Generate a unique challenge ID for this notification
|
// Generate a unique challenge ID for this notification
|
||||||
// Note: In a full implementation, this would be stored in a cache/database
|
// Note: In a full implementation, this would be stored in a cache/database
|
||||||
// to validate callbacks from the mobile app
|
// 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
|
mfa.challengeExp = time.Now().Add(5 * time.Minute) // Challenge expires in 5 minutes
|
||||||
|
|
||||||
// Get the notification provider
|
// Get the notification provider
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/beevik/etree"
|
"github.com/beevik/etree"
|
||||||
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
"github.com/google/uuid"
|
|
||||||
saml "github.com/russellhaering/gosaml2"
|
saml "github.com/russellhaering/gosaml2"
|
||||||
dsig "github.com/russellhaering/goxmldsig"
|
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:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
|
||||||
samlResponse.CreateAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
|
samlResponse.CreateAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
|
||||||
samlResponse.CreateAttr("xmlns:xs", "http://www.w3.org/2001/XMLSchema")
|
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("ID", fmt.Sprintf("_%s", arId))
|
||||||
samlResponse.CreateAttr("Version", "2.0")
|
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:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
|
||||||
assertion.CreateAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
|
assertion.CreateAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
|
||||||
assertion.CreateAttr("xmlns:xs", "http://www.w3.org/2001/XMLSchema")
|
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("Version", "2.0")
|
||||||
assertion.CreateAttr("IssueInstant", now)
|
assertion.CreateAttr("IssueInstant", now)
|
||||||
assertion.CreateElement("saml:Issuer").SetText(host)
|
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 := assertion.CreateElement("saml:AuthnStatement")
|
||||||
authnStatement.CreateAttr("AuthnInstant", now)
|
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.CreateAttr("SessionNotOnOrAfter", expireTime)
|
||||||
authnStatement.CreateElement("saml:AuthnContext").CreateElement("saml:AuthnContextClassRef").SetText("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport")
|
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("MajorVersion", "1")
|
||||||
samlResponse.CreateAttr("MinorVersion", "1")
|
samlResponse.CreateAttr("MinorVersion", "1")
|
||||||
|
|
||||||
responseID := uuid.New()
|
responseID := util.GenerateUUID()
|
||||||
samlResponse.CreateAttr("ResponseID", fmt.Sprintf("_%s", responseID))
|
samlResponse.CreateAttr("ResponseID", fmt.Sprintf("_%s", responseID))
|
||||||
samlResponse.CreateAttr("InResponseTo", requestID)
|
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("xmlns:saml", "urn:oasis:names:tc:SAML:1.0:assertion")
|
||||||
assertion.CreateAttr("MajorVersion", "1")
|
assertion.CreateAttr("MajorVersion", "1")
|
||||||
assertion.CreateAttr("MinorVersion", "1")
|
assertion.CreateAttr("MinorVersion", "1")
|
||||||
assertion.CreateAttr("AssertionID", uuid.New().String())
|
assertion.CreateAttr("AssertionID", util.GenerateUUID())
|
||||||
assertion.CreateAttr("Issuer", host)
|
assertion.CreateAttr("Issuer", host)
|
||||||
assertion.CreateAttr("IssueInstant", now)
|
assertion.CreateAttr("IssueInstant", now)
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ package object
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/xorm-io/core"
|
"github.com/xorm-io/core"
|
||||||
@@ -234,8 +232,7 @@ func (site *Site) GetChallengeMap() map[string]string {
|
|||||||
|
|
||||||
func (site *Site) GetHost() string {
|
func (site *Site) GetHost() string {
|
||||||
if len(site.Hosts) != 0 {
|
if len(site.Hosts) != 0 {
|
||||||
rand.Seed(time.Now().UnixNano())
|
return site.Hosts[util.RandomIntn(len(site.Hosts))]
|
||||||
return site.Hosts[rand.Intn(len(site.Hosts))]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if site.Host != "" {
|
if site.Host != "" {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import (
|
|||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"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{
|
stToServiceResponse.Store(st, &CasAuthenticationSuccessWrapper{
|
||||||
AuthenticationSuccess: &authenticationSuccess,
|
AuthenticationSuccess: &authenticationSuccess,
|
||||||
Service: service,
|
Service: service,
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import (
|
|||||||
"github.com/casdoor/casdoor/i18n"
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/idp"
|
"github.com/casdoor/casdoor/idp"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/xorm-io/core"
|
"github.com/xorm-io/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -742,12 +741,7 @@ func createGuestUserToken(application *Application, clientSecret string, verifie
|
|||||||
|
|
||||||
// generateGuestUsername generates a unique username for guest users
|
// generateGuestUsername generates a unique username for guest users
|
||||||
func generateGuestUsername() string {
|
func generateGuestUsername() string {
|
||||||
uid, err := uuid.NewRandom()
|
return fmt.Sprintf("guest_%s", util.GenerateUUID())
|
||||||
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())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAuthorizationCodeToken
|
// GetAuthorizationCodeToken
|
||||||
|
|||||||
@@ -15,10 +15,11 @@
|
|||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/rand"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/big"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -476,10 +477,13 @@ func GetVerifyType(username string) (verificationCodeType string) {
|
|||||||
var stdNums = []byte("0123456789")
|
var stdNums = []byte("0123456789")
|
||||||
|
|
||||||
func getRandomCode(length int) string {
|
func getRandomCode(length int) string {
|
||||||
var result []byte
|
result := make([]byte, length)
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
||||||
for i := 0; i < length; i++ {
|
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)
|
return string(result)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,13 @@
|
|||||||
|
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import "github.com/thanhpk/randstr"
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/thanhpk/randstr"
|
||||||
|
)
|
||||||
|
|
||||||
func GenerateClientId() string {
|
func GenerateClientId() string {
|
||||||
return randstr.Hex(10)
|
return randstr.Hex(10)
|
||||||
@@ -27,3 +33,57 @@ func GenerateClientSecret() string {
|
|||||||
func GeneratePasswordSalt() string {
|
func GeneratePasswordSalt() string {
|
||||||
return randstr.Hex(10)
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"math/rand"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -30,7 +28,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/nyaruka/phonenumbers"
|
"github.com/nyaruka/phonenumbers"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -167,7 +164,7 @@ func GetSharedOrgFromApp(rawName string) (name string, organization string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GenerateId() string {
|
func GenerateId() string {
|
||||||
return uuid.NewString()
|
return GenerateUUID()
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateTimeId() string {
|
func GenerateTimeId() string {
|
||||||
@@ -175,7 +172,7 @@ func GenerateTimeId() string {
|
|||||||
tm := time.Unix(timestamp, 0)
|
tm := time.Unix(timestamp, 0)
|
||||||
t := tm.Format("20060102_150405")
|
t := tm.Format("20060102_150405")
|
||||||
|
|
||||||
random := uuid.NewString()[0:7]
|
random := GenerateUUID()[0:7]
|
||||||
|
|
||||||
res := fmt.Sprintf("%s_%s", t, random)
|
res := fmt.Sprintf("%s_%s", t, random)
|
||||||
return res
|
return res
|
||||||
@@ -189,16 +186,6 @@ func GenerateSimpleTimeId() string {
|
|||||||
return t
|
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 {
|
func GetId(owner, name string) string {
|
||||||
return fmt.Sprintf("%s/%s", owner, name)
|
return fmt.Sprintf("%s/%s", owner, name)
|
||||||
}
|
}
|
||||||
@@ -355,7 +342,7 @@ func GetValueFromDataSourceName(key string, dataSourceName string) string {
|
|||||||
func GetUsernameFromEmail(email string) string {
|
func GetUsernameFromEmail(email string) string {
|
||||||
tokens := strings.Split(email, "@")
|
tokens := strings.Split(email, "@")
|
||||||
if len(tokens) == 0 {
|
if len(tokens) == 0 {
|
||||||
return uuid.NewString()
|
return GenerateUUID()
|
||||||
} else {
|
} else {
|
||||||
return tokens[0]
|
return tokens[0]
|
||||||
}
|
}
|
||||||
@@ -394,37 +381,3 @@ func StringToInterfaceArray2d(arrays [][]string) [][]interface{} {
|
|||||||
}
|
}
|
||||||
return interfaceArrays
|
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
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user