mirror of
https://github.com/netbirdio/netbird.git
synced 2025-02-16 10:20:09 +01:00
Hide setup key from non-admin users (#539)
This commit is contained in:
parent
2e0bf61e9a
commit
6aa7a2c5e1
@ -214,8 +214,9 @@ func isBuiltinModule(name string) (bool, error) {
|
||||
}
|
||||
|
||||
// /proc/modules
|
||||
// name | memory size | reference count | references | state: <Live|Loading|Unloading>
|
||||
// macvlan 28672 1 macvtap, Live 0x0000000000000000
|
||||
//
|
||||
// name | memory size | reference count | references | state: <Live|Loading|Unloading>
|
||||
// macvlan 28672 1 macvtap, Live 0x0000000000000000
|
||||
func moduleStatus(name string) (status, error) {
|
||||
state := unknown
|
||||
f, err := os.Open("/proc/modules")
|
||||
|
@ -23,7 +23,7 @@ func APIHandler(accountManager s.AccountManager, authIssuer string, authAudience
|
||||
|
||||
corsMiddleware := cors.AllowAll()
|
||||
|
||||
acMiddleware := middleware.NewAccessControll(
|
||||
acMiddleware := middleware.NewAccessControl(
|
||||
authAudience,
|
||||
accountManager.IsUserAdmin)
|
||||
|
||||
|
@ -1,32 +1,38 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||
)
|
||||
|
||||
const (
|
||||
IsUserAdminProperty = "isAdminUser"
|
||||
)
|
||||
|
||||
type IsUserAdminFunc func(claims jwtclaims.AuthorizationClaims) (bool, error)
|
||||
|
||||
// AccessControll middleware to restrict to make POST/PUT/DELETE requests by admin only
|
||||
type AccessControll struct {
|
||||
// AccessControl middleware to restrict to make POST/PUT/DELETE requests by admin only
|
||||
type AccessControl struct {
|
||||
jwtExtractor jwtclaims.ClaimsExtractor
|
||||
isUserAdmin IsUserAdminFunc
|
||||
audience string
|
||||
}
|
||||
|
||||
// NewAccessControll instance constructor
|
||||
func NewAccessControll(audience string, isUserAdmin IsUserAdminFunc) *AccessControll {
|
||||
return &AccessControll{
|
||||
// NewAccessControl instance constructor
|
||||
func NewAccessControl(audience string, isUserAdmin IsUserAdminFunc) *AccessControl {
|
||||
return &AccessControl{
|
||||
isUserAdmin: isUserAdmin,
|
||||
audience: audience,
|
||||
jwtExtractor: *jwtclaims.NewClaimsExtractor(nil),
|
||||
}
|
||||
}
|
||||
|
||||
// Handler method of the middleware which forbinneds all modify requests for non admin users
|
||||
func (a *AccessControll) Handler(h http.Handler) http.Handler {
|
||||
// Handler method of the middleware which forbids all modify requests for non admin users
|
||||
// It also adds
|
||||
func (a *AccessControl) Handler(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
jwtClaims := a.jwtExtractor.ExtractClaimsFromRequestContext(r, a.audience)
|
||||
|
||||
@ -34,7 +40,6 @@ func (a *AccessControll) Handler(h http.Handler) http.Handler {
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("error get user from JWT: %v", err), http.StatusUnauthorized)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
if !ok {
|
||||
@ -45,6 +50,10 @@ func (a *AccessControll) Handler(h http.Handler) http.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
newRequest := r.Clone(context.WithValue(r.Context(), IsUserAdminProperty, ok)) //nolint
|
||||
// Update the current request with the new context information.
|
||||
*r = *newRequest
|
||||
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
@ -6,12 +6,15 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/netbirdio/netbird/management/server"
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/middleware"
|
||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// SetupKeys is a handler that returns a list of setup keys of the account
|
||||
@ -107,6 +110,11 @@ func (h *SetupKeys) GetSetupKeyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
isUserAdmin, ok := r.Context().Value(middleware.IsUserAdminProperty).(bool)
|
||||
if !ok || !isUserAdmin {
|
||||
key = hideKey(key)
|
||||
}
|
||||
|
||||
writeSuccess(w, key)
|
||||
}
|
||||
|
||||
@ -175,6 +183,11 @@ func (h *SetupKeys) GetAllSetupKeysHandler(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
isUserAdmin, ok := r.Context().Value(middleware.IsUserAdminProperty).(bool)
|
||||
if !ok {
|
||||
isUserAdmin = false
|
||||
}
|
||||
|
||||
setupKeys, err := h.accountManager.ListSetupKeys(account.Id)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
@ -183,12 +196,23 @@ func (h *SetupKeys) GetAllSetupKeysHandler(w http.ResponseWriter, r *http.Reques
|
||||
}
|
||||
apiSetupKeys := make([]*api.SetupKey, 0)
|
||||
for _, key := range setupKeys {
|
||||
apiSetupKeys = append(apiSetupKeys, toResponseBody(key))
|
||||
k := key.Copy()
|
||||
if !isUserAdmin {
|
||||
k = hideKey(key)
|
||||
}
|
||||
apiSetupKeys = append(apiSetupKeys, toResponseBody(k))
|
||||
}
|
||||
|
||||
writeJSONObject(w, apiSetupKeys)
|
||||
}
|
||||
|
||||
func hideKey(key *server.SetupKey) *server.SetupKey {
|
||||
k := key.Copy()
|
||||
prefix := k.Key[0:5]
|
||||
k.Key = prefix + strings.Repeat("*", utf8.RuneCountInString(key.Key)-len(prefix))
|
||||
return k
|
||||
}
|
||||
|
||||
func writeSuccess(w http.ResponseWriter, key *server.SetupKey) {
|
||||
w.WriteHeader(200)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
@ -2,6 +2,7 @@ package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
@ -159,6 +160,7 @@ func TestSetupKeysHandlers(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
recorder := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(tc.requestType, tc.requestPath, tc.requestBody)
|
||||
req = req.Clone(context.WithValue(context.TODO(), "isAdminUser", true)) //nolint
|
||||
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/api/setup-keys", handler.GetAllSetupKeysHandler).Methods("GET", "OPTIONS")
|
||||
|
Loading…
Reference in New Issue
Block a user