summaryrefslogtreecommitdiffstats
path: root/modules/generate
diff options
context:
space:
mode:
authorDaniel Baumann <daniel@debian.org>2024-10-18 20:33:49 +0200
committerDaniel Baumann <daniel@debian.org>2024-10-18 20:33:49 +0200
commitdd136858f1ea40ad3c94191d647487fa4f31926c (patch)
tree58fec94a7b2a12510c9664b21793f1ed560c6518 /modules/generate
parentInitial commit. (diff)
downloadforgejo-upstream.tar.xz
forgejo-upstream.zip
Adding upstream version 9.0.0.upstream/9.0.0upstreamdebian
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'modules/generate')
-rw-r--r--modules/generate/generate.go75
-rw-r--r--modules/generate/generate_test.go35
2 files changed, 110 insertions, 0 deletions
diff --git a/modules/generate/generate.go b/modules/generate/generate.go
new file mode 100644
index 0000000..41a6aa2
--- /dev/null
+++ b/modules/generate/generate.go
@@ -0,0 +1,75 @@
+// Copyright 2016 The Gogs Authors. All rights reserved.
+// Copyright 2016 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package generate
+
+import (
+ "crypto/rand"
+ "encoding/base64"
+ "fmt"
+ "io"
+ "time"
+
+ "code.gitea.io/gitea/modules/util"
+
+ "github.com/golang-jwt/jwt/v5"
+)
+
+// NewInternalToken generate a new value intended to be used by INTERNAL_TOKEN.
+func NewInternalToken() (string, error) {
+ secretBytes := make([]byte, 32)
+ _, err := io.ReadFull(rand.Reader, secretBytes)
+ if err != nil {
+ return "", err
+ }
+
+ secretKey := base64.RawURLEncoding.EncodeToString(secretBytes)
+
+ now := time.Now()
+
+ var internalToken string
+ internalToken, err = jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
+ "nbf": now.Unix(),
+ }).SignedString([]byte(secretKey))
+ if err != nil {
+ return "", err
+ }
+
+ return internalToken, nil
+}
+
+const defaultJwtSecretLen = 32
+
+// DecodeJwtSecret decodes a base64 encoded jwt secret into bytes, and check its length
+func DecodeJwtSecret(src string) ([]byte, error) {
+ encoding := base64.RawURLEncoding
+ decoded := make([]byte, encoding.DecodedLen(len(src))+3)
+ if n, err := encoding.Decode(decoded, []byte(src)); err != nil {
+ return nil, err
+ } else if n != defaultJwtSecretLen {
+ return nil, fmt.Errorf("invalid base64 decoded length: %d, expects: %d", n, defaultJwtSecretLen)
+ }
+ return decoded[:defaultJwtSecretLen], nil
+}
+
+// NewJwtSecret generates a new base64 encoded value intended to be used for JWT secrets.
+func NewJwtSecret() ([]byte, string, error) {
+ bytes := make([]byte, 32)
+ _, err := rand.Read(bytes)
+ if err != nil {
+ return nil, "", err
+ }
+
+ return bytes, base64.RawURLEncoding.EncodeToString(bytes), nil
+}
+
+// NewSecretKey generate a new value intended to be used by SECRET_KEY.
+func NewSecretKey() (string, error) {
+ secretKey, err := util.CryptoRandomString(64)
+ if err != nil {
+ return "", err
+ }
+
+ return secretKey, nil
+}
diff --git a/modules/generate/generate_test.go b/modules/generate/generate_test.go
new file mode 100644
index 0000000..eb7178a
--- /dev/null
+++ b/modules/generate/generate_test.go
@@ -0,0 +1,35 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package generate
+
+import (
+ "encoding/base64"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestDecodeJwtSecret(t *testing.T) {
+ _, err := DecodeJwtSecret("abcd")
+ require.ErrorContains(t, err, "invalid base64 decoded length")
+ _, err = DecodeJwtSecret(strings.Repeat("a", 64))
+ require.ErrorContains(t, err, "invalid base64 decoded length")
+
+ str32 := strings.Repeat("x", 32)
+ encoded32 := base64.RawURLEncoding.EncodeToString([]byte(str32))
+ decoded32, err := DecodeJwtSecret(encoded32)
+ require.NoError(t, err)
+ assert.Equal(t, str32, string(decoded32))
+}
+
+func TestNewJwtSecret(t *testing.T) {
+ secret, encoded, err := NewJwtSecret()
+ require.NoError(t, err)
+ assert.Len(t, secret, 32)
+ decoded, err := DecodeJwtSecret(encoded)
+ require.NoError(t, err)
+ assert.Equal(t, secret, decoded)
+}