2021-12-27 13:17:15 +01:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
2022-05-25 18:26:50 +02:00
|
|
|
"fmt"
|
2022-05-05 08:58:34 +02:00
|
|
|
"strings"
|
|
|
|
|
2021-12-27 13:17:15 +01:00
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
"google.golang.org/grpc/status"
|
2022-05-25 18:26:50 +02:00
|
|
|
|
|
|
|
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
2021-12-27 13:17:15 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
UserRoleAdmin UserRole = "admin"
|
|
|
|
UserRoleUser UserRole = "user"
|
|
|
|
)
|
|
|
|
|
|
|
|
// UserRole is the role of the User
|
|
|
|
type UserRole string
|
|
|
|
|
|
|
|
// User represents a user of the system
|
|
|
|
type User struct {
|
|
|
|
Id string
|
|
|
|
Role UserRole
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *User) Copy() *User {
|
|
|
|
return &User{
|
|
|
|
Id: u.Id,
|
|
|
|
Role: u.Role,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewUser creates a new user
|
|
|
|
func NewUser(id string, role UserRole) *User {
|
|
|
|
return &User{
|
|
|
|
Id: id,
|
|
|
|
Role: role,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-01 15:22:18 +01:00
|
|
|
// NewRegularUser creates a new user with role UserRoleAdmin
|
|
|
|
func NewRegularUser(id string) *User {
|
|
|
|
return NewUser(id, UserRoleUser)
|
|
|
|
}
|
|
|
|
|
2021-12-27 13:17:15 +01:00
|
|
|
// NewAdminUser creates a new user with role UserRoleAdmin
|
|
|
|
func NewAdminUser(id string) *User {
|
|
|
|
return NewUser(id, UserRoleAdmin)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetOrCreateAccountByUser returns an existing account for a given user id or creates a new one if doesn't exist
|
2022-02-22 11:28:19 +01:00
|
|
|
func (am *DefaultAccountManager) GetOrCreateAccountByUser(userId, domain string) (*Account, error) {
|
2021-12-27 13:17:15 +01:00
|
|
|
am.mux.Lock()
|
|
|
|
defer am.mux.Unlock()
|
|
|
|
|
2022-03-01 15:22:18 +01:00
|
|
|
lowerDomain := strings.ToLower(domain)
|
|
|
|
|
2021-12-27 13:17:15 +01:00
|
|
|
account, err := am.Store.GetUserAccount(userId)
|
|
|
|
if err != nil {
|
|
|
|
if s, ok := status.FromError(err); ok && s.Code() == codes.NotFound {
|
2022-03-01 15:22:18 +01:00
|
|
|
account = NewAccount(userId, lowerDomain)
|
2021-12-27 13:17:15 +01:00
|
|
|
err = am.Store.SaveAccount(account)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.Internal, "failed creating account")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// other error
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-01 15:22:18 +01:00
|
|
|
if account.Domain != lowerDomain {
|
|
|
|
account.Domain = lowerDomain
|
2022-02-11 17:18:18 +01:00
|
|
|
err = am.Store.SaveAccount(account)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.Internal, "failed updating account with domain")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-27 13:17:15 +01:00
|
|
|
return account, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAccountByUser returns an existing account for a given user id, NotFound if account couldn't be found
|
2022-02-22 11:28:19 +01:00
|
|
|
func (am *DefaultAccountManager) GetAccountByUser(userId string) (*Account, error) {
|
2021-12-27 13:17:15 +01:00
|
|
|
am.mux.Lock()
|
|
|
|
defer am.mux.Unlock()
|
|
|
|
|
|
|
|
return am.Store.GetUserAccount(userId)
|
|
|
|
}
|
2022-05-25 18:26:50 +02:00
|
|
|
|
|
|
|
// IsUserAdmin flag for current user authenticated by JWT token
|
|
|
|
func (am *DefaultAccountManager) IsUserAdmin(claims jwtclaims.AuthorizationClaims) (bool, error) {
|
|
|
|
account, err := am.GetAccountWithAuthorizationClaims(claims)
|
|
|
|
if err != nil {
|
|
|
|
return false, fmt.Errorf("get account: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
user, ok := account.Users[claims.UserId]
|
|
|
|
if !ok {
|
|
|
|
return false, fmt.Errorf("no such user")
|
|
|
|
}
|
|
|
|
|
|
|
|
return user.Role == UserRoleAdmin, nil
|
|
|
|
}
|