NET-2000: Api access tokens (#3418)

* feat: api access tokens

* revoke all user tokens

* redefine access token api routes, add auto egress option to enrollment keys

* fix revoked tokens to be unauthorized

* remove unused functions

* convert access token to sql schema

* switch access token to sql schema

* revoke token generated by an user

* add user token creation restriction by user role

* add forbidden check for access token creation

* revoke user token when group or role is changed

* add default group to admin users on update

* fix token removal on user update

* fix token removal on user update
This commit is contained in:
Abhishek K
2025-04-23 20:21:42 +04:00
committed by GitHub
parent d5bdc723fc
commit ca95954fb5
28 changed files with 507 additions and 200 deletions
+5 -64
View File
@@ -1,18 +1,12 @@
package database
import (
"crypto/rand"
"encoding/json"
"errors"
"sync"
"time"
"github.com/google/uuid"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg"
"golang.org/x/crypto/nacl/box"
)
const (
@@ -25,6 +19,8 @@ const (
DELETED_NODES_TABLE_NAME = "deletednodes"
// USERS_TABLE_NAME - users table
USERS_TABLE_NAME = "users"
// ACCESS_TOKENS_TABLE_NAME - access tokens table
ACCESS_TOKENS_TABLE_NAME = "user_access_tokens"
// USER_PERMISSIONS_TABLE_NAME - user permissions table
USER_PERMISSIONS_TABLE_NAME = "user_permissions"
// CERTS_TABLE_NAME - certificates table
@@ -129,6 +125,7 @@ var Tables = []string{
TAG_TABLE_NAME,
ACLS_TABLE_NAME,
PEER_ACK_TABLE,
// ACCESS_TOKENS_TABLE_NAME,
}
func getCurrentDB() map[string]interface{} {
@@ -160,7 +157,7 @@ func InitializeDatabase() error {
time.Sleep(2 * time.Second)
}
createTables()
return initializeUUID()
return nil
}
func createTables() {
@@ -173,35 +170,17 @@ func CreateTable(tableName string) error {
return getCurrentDB()[CREATE_TABLE].(func(string) error)(tableName)
}
// IsJSONString - checks if valid json
func IsJSONString(value string) bool {
var jsonInt interface{}
var nodeInt models.Node
return json.Unmarshal([]byte(value), &jsonInt) == nil || json.Unmarshal([]byte(value), &nodeInt) == nil
}
// Insert - inserts object into db
func Insert(key string, value string, tableName string) error {
dbMutex.Lock()
defer dbMutex.Unlock()
if key != "" && value != "" && IsJSONString(value) {
if key != "" && value != "" {
return getCurrentDB()[INSERT].(func(string, string, string) error)(key, value, tableName)
} else {
return errors.New("invalid insert " + key + " : " + value)
}
}
// InsertPeer - inserts peer into db
func InsertPeer(key string, value string) error {
dbMutex.Lock()
defer dbMutex.Unlock()
if key != "" && value != "" && IsJSONString(value) {
return getCurrentDB()[INSERT_PEER].(func(string, string) error)(key, value)
} else {
return errors.New("invalid peer insert " + key + " : " + value)
}
}
// DeleteRecord - deletes a record from db
func DeleteRecord(tableName string, key string) error {
dbMutex.Lock()
@@ -243,44 +222,6 @@ func FetchRecords(tableName string) (map[string]string, error) {
return getCurrentDB()[FETCH_ALL].(func(string) (map[string]string, error))(tableName)
}
// initializeUUID - create a UUID record for server if none exists
func initializeUUID() error {
records, err := FetchRecords(SERVER_UUID_TABLE_NAME)
if err != nil {
if !IsEmptyRecord(err) {
return err
}
} else if len(records) > 0 {
return nil
}
// setup encryption keys
var trafficPubKey, trafficPrivKey, errT = box.GenerateKey(rand.Reader) // generate traffic keys
if errT != nil {
return errT
}
tPriv, err := ncutils.ConvertKeyToBytes(trafficPrivKey)
if err != nil {
return err
}
tPub, err := ncutils.ConvertKeyToBytes(trafficPubKey)
if err != nil {
return err
}
telemetry := models.Telemetry{
UUID: uuid.NewString(),
TrafficKeyPriv: tPriv,
TrafficKeyPub: tPub,
}
telJSON, err := json.Marshal(&telemetry)
if err != nil {
return err
}
return Insert(SERVER_UUID_RECORD_KEY, string(telJSON), SERVER_UUID_TABLE_NAME)
}
// CloseDB - closes a database gracefully
func CloseDB() {
getCurrentDB()[CLOSE_DB].(func())()