| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | package util | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"crypto/rand" | 
					
						
							|  |  |  | 	"crypto/sha256" | 
					
						
							| 
									
										
										
										
											2015-03-02 16:58:35 +08:00
										 |  |  | 	"encoding/base64" | 
					
						
							| 
									
										
										
										
											2015-01-27 19:05:23 +08:00
										 |  |  | 	"encoding/hex" | 
					
						
							| 
									
										
										
										
											2015-06-30 15:37:52 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2022-03-04 17:58:27 +08:00
										 |  |  | 	"io" | 
					
						
							|  |  |  | 	"mime/quotedprintable" | 
					
						
							| 
									
										
										
										
											2015-06-30 15:37:52 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2020-06-29 20:08:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"golang.org/x/crypto/pbkdf2" | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 22:24:02 +08:00
										 |  |  | const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // GetRandomString generates a random alphanumeric string of the specified length,
 | 
					
						
							|  |  |  | // optionally using only specified characters
 | 
					
						
							| 
									
										
										
										
											2019-10-23 16:40:12 +08:00
										 |  |  | func GetRandomString(n int, alphabets ...byte) (string, error) { | 
					
						
							| 
									
										
										
										
											2023-04-20 22:24:02 +08:00
										 |  |  | 	chars := alphanum | 
					
						
							|  |  |  | 	if len(alphabets) > 0 { | 
					
						
							|  |  |  | 		chars = string(alphabets) | 
					
						
							| 
									
										
										
										
											2019-10-23 16:40:12 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-04-20 22:24:02 +08:00
										 |  |  | 	cnt := len(chars) | 
					
						
							|  |  |  | 	max := 255 / cnt * cnt | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bytes := make([]byte, n) | 
					
						
							| 
									
										
										
										
											2019-10-23 16:40:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 22:24:02 +08:00
										 |  |  | 	randread := n * 5 / 4 | 
					
						
							|  |  |  | 	randbytes := make([]byte, randread) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < n; { | 
					
						
							|  |  |  | 		if _, err := rand.Read(randbytes); err != nil { | 
					
						
							|  |  |  | 			return "", err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for j := 0; i < n && j < randread; j++ { | 
					
						
							|  |  |  | 			b := int(randbytes[j]) | 
					
						
							|  |  |  | 			if b >= max { | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			bytes[i] = chars[b%cnt] | 
					
						
							|  |  |  | 			i++ | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-04-20 22:24:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 16:40:12 +08:00
										 |  |  | 	return string(bytes), nil | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 05:09:40 +08:00
										 |  |  | // EncodePassword encodes a password using PBKDF2.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 16:40:12 +08:00
										 |  |  | func EncodePassword(password string, salt string) (string, error) { | 
					
						
							| 
									
										
										
										
											2019-11-06 16:03:10 +08:00
										 |  |  | 	newPasswd := pbkdf2.Key([]byte(password), []byte(salt), 10000, 50, sha256.New) | 
					
						
							| 
									
										
										
										
											2019-10-23 16:40:12 +08:00
										 |  |  | 	return hex.EncodeToString(newPasswd), nil | 
					
						
							| 
									
										
										
										
											2015-01-27 19:05:23 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 05:09:40 +08:00
										 |  |  | // GetBasicAuthHeader returns a base64 encoded string from user and password.
 | 
					
						
							| 
									
										
										
										
											2015-03-02 16:58:35 +08:00
										 |  |  | func GetBasicAuthHeader(user string, password string) string { | 
					
						
							|  |  |  | 	var userAndPass = user + ":" + password | 
					
						
							|  |  |  | 	return "Basic " + base64.StdEncoding.EncodeToString([]byte(userAndPass)) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-30 15:37:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 05:09:40 +08:00
										 |  |  | // DecodeBasicAuthHeader decodes user and password from a basic auth header.
 | 
					
						
							| 
									
										
										
										
											2015-06-30 15:37:52 +08:00
										 |  |  | func DecodeBasicAuthHeader(header string) (string, string, error) { | 
					
						
							|  |  |  | 	var code string | 
					
						
							|  |  |  | 	parts := strings.SplitN(header, " ", 2) | 
					
						
							|  |  |  | 	if len(parts) == 2 && parts[0] == "Basic" { | 
					
						
							|  |  |  | 		code = parts[1] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	decoded, err := base64.StdEncoding.DecodeString(code) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return "", "", err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	userAndPass := strings.SplitN(string(decoded), ":", 2) | 
					
						
							|  |  |  | 	if len(userAndPass) != 2 { | 
					
						
							| 
									
										
										
										
											2020-11-05 18:29:39 +08:00
										 |  |  | 		return "", "", errors.New("invalid basic auth header") | 
					
						
							| 
									
										
										
										
											2015-06-30 15:37:52 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return userAndPass[0], userAndPass[1], nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-01-15 18:11:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-30 19:39:54 +08:00
										 |  |  | // RandomHex returns a hex encoding of n random bytes.
 | 
					
						
							| 
									
										
										
										
											2019-01-15 18:11:32 +08:00
										 |  |  | func RandomHex(n int) (string, error) { | 
					
						
							|  |  |  | 	bytes := make([]byte, n) | 
					
						
							|  |  |  | 	if _, err := rand.Read(bytes); err != nil { | 
					
						
							|  |  |  | 		return "", err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return hex.EncodeToString(bytes), nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-04 17:58:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // decodeQuotedPrintable decodes quoted-printable UTF-8 string
 | 
					
						
							|  |  |  | func DecodeQuotedPrintable(encodedValue string) string { | 
					
						
							|  |  |  | 	decodedBytes, err := io.ReadAll(quotedprintable.NewReader(strings.NewReader(encodedValue))) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return encodedValue | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return string(decodedBytes) | 
					
						
							|  |  |  | } |