mirror of
https://github.com/netbirdio/netbird.git
synced 2025-02-16 18:21:24 +01:00
add generating token (only frame for now, actual token is only dummy)
This commit is contained in:
parent
1bda8fd563
commit
69be2a8071
1
go.mod
1
go.mod
@ -28,6 +28,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
codeberg.org/ac/base62 v0.0.0-20210305150220-e793b546833a
|
||||||
fyne.io/fyne/v2 v2.1.4
|
fyne.io/fyne/v2 v2.1.4
|
||||||
github.com/c-robinson/iplib v1.0.3
|
github.com/c-robinson/iplib v1.0.3
|
||||||
github.com/coreos/go-iptables v0.6.0
|
github.com/coreos/go-iptables v0.6.0
|
||||||
|
2
go.sum
2
go.sum
@ -30,6 +30,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
|||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
|
codeberg.org/ac/base62 v0.0.0-20210305150220-e793b546833a h1:U6cY/g6VSiy59vuvnBU6J/eSir0qVg4BeTnCDLaX+20=
|
||||||
|
codeberg.org/ac/base62 v0.0.0-20210305150220-e793b546833a/go.mod h1:ykEpkLT4JtH3I4Rb4gwkDsNLfgUg803qRDeIX88t3e8=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
fyne.io/fyne/v2 v2.1.4 h1:bt1+28++kAzRzPB0GM2EuSV4cnl8rXNX4cjfd8G06Rc=
|
fyne.io/fyne/v2 v2.1.4 h1:bt1+28++kAzRzPB0GM2EuSV4cnl8rXNX4cjfd8G06Rc=
|
||||||
fyne.io/fyne/v2 v2.1.4/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ=
|
fyne.io/fyne/v2 v2.1.4/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ=
|
||||||
|
70
management/server/personal_access_token.go
Normal file
70
management/server/personal_access_token.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
|
"hash/crc32"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"codeberg.org/ac/base62"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PersonalAccessToken struct {
|
||||||
|
Description string
|
||||||
|
HashedToken [32]byte
|
||||||
|
ExpirationDate time.Time
|
||||||
|
// scope could be added in future
|
||||||
|
CreatedBy User // should we add that?
|
||||||
|
CreatedAt time.Time
|
||||||
|
LastUsed time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// IEEE is by far and away the most common CRC-32 polynomial.
|
||||||
|
// Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, ...
|
||||||
|
IEEE = 0xedb88320
|
||||||
|
// Castagnoli polynomial, used in iSCSI.
|
||||||
|
// Has better error detection characteristics than IEEE.
|
||||||
|
// https://dx.doi.org/10.1109/26.231911
|
||||||
|
Castagnoli = 0x82f63b78
|
||||||
|
// Koopman polynomial.
|
||||||
|
// Also has better error detection characteristics than IEEE.
|
||||||
|
// https://dx.doi.org/10.1109/DSN.2002.1028931
|
||||||
|
Koopman = 0xeb31d82e
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateNewPAT(description string, expirationInDays int, createdBy User) (*PersonalAccessToken, string) {
|
||||||
|
hashedToken, plainToken := generateNewToken()
|
||||||
|
currentTime := time.Now().UTC()
|
||||||
|
return &PersonalAccessToken{
|
||||||
|
Description: description,
|
||||||
|
HashedToken: hashedToken,
|
||||||
|
ExpirationDate: currentTime.AddDate(0, 0, expirationInDays),
|
||||||
|
CreatedBy: createdBy,
|
||||||
|
CreatedAt: currentTime,
|
||||||
|
LastUsed: currentTime, // using creation time as nil not possible
|
||||||
|
}, plainToken
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateNewToken() ([32]byte, string) {
|
||||||
|
token := randStringRunes(30)
|
||||||
|
|
||||||
|
crc32q := crc32.MakeTable(IEEE)
|
||||||
|
checksum := crc32.Checksum([]byte(token), crc32q)
|
||||||
|
encodedChecksum := base62.Encode(checksum)
|
||||||
|
paddedChecksum := fmt.Sprintf("%06s", encodedChecksum)
|
||||||
|
plainToken := "nbp_" + token + paddedChecksum
|
||||||
|
hashedToken := sha256.Sum256([]byte(plainToken))
|
||||||
|
return hashedToken, plainToken
|
||||||
|
}
|
||||||
|
|
||||||
|
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||||
|
|
||||||
|
func randStringRunes(n int) string {
|
||||||
|
b := make([]rune, n)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = letterRunes[rand.Intn(len(letterRunes))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
41
management/server/personal_access_token_test.go
Normal file
41
management/server/personal_access_token_test.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"hash/crc32"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"codeberg.org/ac/base62"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPAT_GenerateToken_Hashing(t *testing.T) {
|
||||||
|
hashedToken, plainToken := generateNewToken()
|
||||||
|
|
||||||
|
assert.Equal(t, hashedToken, sha256.Sum256([]byte(plainToken)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPAT_GenerateToken_Prefix(t *testing.T) {
|
||||||
|
_, plainToken := generateNewToken()
|
||||||
|
fourLetterPrefix := plainToken[:4] // should be 3
|
||||||
|
assert.Equal(t, "nbp_", fourLetterPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPAT_GenerateToken_Checksum(t *testing.T) {
|
||||||
|
_, plainToken := generateNewToken()
|
||||||
|
tokenWithoutPrefix := strings.Split(plainToken, "_")[1]
|
||||||
|
if len(tokenWithoutPrefix) != 36 {
|
||||||
|
t.Fatal("Token has wrong length")
|
||||||
|
}
|
||||||
|
token := tokenWithoutPrefix[:len(tokenWithoutPrefix)-6]
|
||||||
|
tokenCheckSum := tokenWithoutPrefix[len(tokenWithoutPrefix)-6:]
|
||||||
|
|
||||||
|
crc32q := crc32.MakeTable(IEEE)
|
||||||
|
expectedChecksum := crc32.Checksum([]byte(token), crc32q)
|
||||||
|
actualChecksum, err := base62.Decode(tokenCheckSum)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, expectedChecksum, actualChecksum)
|
||||||
|
}
|
@ -2,12 +2,14 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/management/server/activity"
|
"github.com/netbirdio/netbird/management/server/activity"
|
||||||
"github.com/netbirdio/netbird/management/server/idp"
|
"github.com/netbirdio/netbird/management/server/idp"
|
||||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||||
"github.com/netbirdio/netbird/management/server/status"
|
"github.com/netbirdio/netbird/management/server/status"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -44,6 +46,7 @@ type User struct {
|
|||||||
Role UserRole
|
Role UserRole
|
||||||
// AutoGroups is a list of Group IDs to auto-assign to peers registered by this user
|
// AutoGroups is a list of Group IDs to auto-assign to peers registered by this user
|
||||||
AutoGroups []string
|
AutoGroups []string
|
||||||
|
PATs []PersonalAccessToken
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAdmin returns true if user is an admin, false otherwise
|
// IsAdmin returns true if user is an admin, false otherwise
|
||||||
|
Loading…
Reference in New Issue
Block a user