mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-14 17:39:12 +02:00
Add limited dashboard view (#1738)
This commit is contained in:
@@ -76,6 +76,7 @@ func (h *AccountsHandler) UpdateAccount(w http.ResponseWriter, r *http.Request)
|
||||
settings := &server.Settings{
|
||||
PeerLoginExpirationEnabled: req.Settings.PeerLoginExpirationEnabled,
|
||||
PeerLoginExpiration: time.Duration(float64(time.Second.Nanoseconds()) * float64(req.Settings.PeerLoginExpiration)),
|
||||
RegularUsersViewBlocked: req.Settings.RegularUsersViewBlocked,
|
||||
}
|
||||
|
||||
if req.Settings.Extra != nil {
|
||||
@@ -143,6 +144,7 @@ func toAccountResponse(account *server.Account) *api.Account {
|
||||
JwtGroupsEnabled: &account.Settings.JWTGroupsEnabled,
|
||||
JwtGroupsClaimName: &account.Settings.JWTGroupsClaimName,
|
||||
JwtAllowGroups: &jwtAllowGroups,
|
||||
RegularUsersViewBlocked: account.Settings.RegularUsersViewBlocked,
|
||||
}
|
||||
|
||||
if account.Settings.Extra != nil {
|
||||
|
||||
@@ -69,6 +69,7 @@ func TestAccounts_AccountsHandler(t *testing.T) {
|
||||
Settings: &server.Settings{
|
||||
PeerLoginExpirationEnabled: false,
|
||||
PeerLoginExpiration: time.Hour,
|
||||
RegularUsersViewBlocked: true,
|
||||
},
|
||||
}, adminUser)
|
||||
|
||||
@@ -96,6 +97,7 @@ func TestAccounts_AccountsHandler(t *testing.T) {
|
||||
JwtGroupsClaimName: sr(""),
|
||||
JwtGroupsEnabled: br(false),
|
||||
JwtAllowGroups: &[]string{},
|
||||
RegularUsersViewBlocked: true,
|
||||
},
|
||||
expectedArray: true,
|
||||
expectedID: accountID,
|
||||
@@ -114,6 +116,7 @@ func TestAccounts_AccountsHandler(t *testing.T) {
|
||||
JwtGroupsClaimName: sr(""),
|
||||
JwtGroupsEnabled: br(false),
|
||||
JwtAllowGroups: &[]string{},
|
||||
RegularUsersViewBlocked: false,
|
||||
},
|
||||
expectedArray: false,
|
||||
expectedID: accountID,
|
||||
@@ -123,7 +126,7 @@ func TestAccounts_AccountsHandler(t *testing.T) {
|
||||
expectedBody: true,
|
||||
requestType: http.MethodPut,
|
||||
requestPath: "/api/accounts/" + accountID,
|
||||
requestBody: bytes.NewBufferString("{\"settings\": {\"peer_login_expiration\": 15552000,\"peer_login_expiration_enabled\": false,\"jwt_groups_enabled\":true,\"jwt_groups_claim_name\":\"roles\",\"jwt_allow_groups\":[\"test\"]}}"),
|
||||
requestBody: bytes.NewBufferString("{\"settings\": {\"peer_login_expiration\": 15552000,\"peer_login_expiration_enabled\": false,\"jwt_groups_enabled\":true,\"jwt_groups_claim_name\":\"roles\",\"jwt_allow_groups\":[\"test\"],\"regular_users_view_blocked\":true}}"),
|
||||
expectedStatus: http.StatusOK,
|
||||
expectedSettings: api.AccountSettings{
|
||||
PeerLoginExpiration: 15552000,
|
||||
@@ -132,6 +135,7 @@ func TestAccounts_AccountsHandler(t *testing.T) {
|
||||
JwtGroupsClaimName: sr("roles"),
|
||||
JwtGroupsEnabled: br(true),
|
||||
JwtAllowGroups: &[]string{"test"},
|
||||
RegularUsersViewBlocked: true,
|
||||
},
|
||||
expectedArray: false,
|
||||
expectedID: accountID,
|
||||
@@ -141,7 +145,7 @@ func TestAccounts_AccountsHandler(t *testing.T) {
|
||||
expectedBody: true,
|
||||
requestType: http.MethodPut,
|
||||
requestPath: "/api/accounts/" + accountID,
|
||||
requestBody: bytes.NewBufferString("{\"settings\": {\"peer_login_expiration\": 554400,\"peer_login_expiration_enabled\": true,\"jwt_groups_enabled\":true,\"jwt_groups_claim_name\":\"groups\",\"groups_propagation_enabled\":true}}"),
|
||||
requestBody: bytes.NewBufferString("{\"settings\": {\"peer_login_expiration\": 554400,\"peer_login_expiration_enabled\": true,\"jwt_groups_enabled\":true,\"jwt_groups_claim_name\":\"groups\",\"groups_propagation_enabled\":true,\"regular_users_view_blocked\":true}}"),
|
||||
expectedStatus: http.StatusOK,
|
||||
expectedSettings: api.AccountSettings{
|
||||
PeerLoginExpiration: 554400,
|
||||
@@ -150,6 +154,7 @@ func TestAccounts_AccountsHandler(t *testing.T) {
|
||||
JwtGroupsClaimName: sr("groups"),
|
||||
JwtGroupsEnabled: br(true),
|
||||
JwtAllowGroups: &[]string{},
|
||||
RegularUsersViewBlocked: true,
|
||||
},
|
||||
expectedArray: false,
|
||||
expectedID: accountID,
|
||||
|
||||
@@ -54,6 +54,10 @@ components:
|
||||
description: Period of time after which peer login expires (seconds).
|
||||
type: integer
|
||||
example: 43200
|
||||
regular_users_view_blocked:
|
||||
description: Allows blocking regular users from viewing parts of the system.
|
||||
type: boolean
|
||||
example: true
|
||||
groups_propagation_enabled:
|
||||
description: Allows propagate the new user auto groups to peers that belongs to the user
|
||||
type: boolean
|
||||
@@ -77,6 +81,7 @@ components:
|
||||
required:
|
||||
- peer_login_expiration_enabled
|
||||
- peer_login_expiration
|
||||
- regular_users_view_blocked
|
||||
AccountExtraSettings:
|
||||
type: object
|
||||
properties:
|
||||
@@ -144,6 +149,8 @@ components:
|
||||
description: How user was issued by API or Integration
|
||||
type: string
|
||||
example: api
|
||||
permissions:
|
||||
$ref: '#/components/schemas/UserPermissions'
|
||||
required:
|
||||
- id
|
||||
- email
|
||||
@@ -152,6 +159,14 @@ components:
|
||||
- auto_groups
|
||||
- status
|
||||
- is_blocked
|
||||
UserPermissions:
|
||||
type: object
|
||||
properties:
|
||||
dashboard_view:
|
||||
description: User's permission to view the dashboard
|
||||
type: string
|
||||
enum: [ "limited", "blocked", "full" ]
|
||||
example: limited
|
||||
UserRequest:
|
||||
type: object
|
||||
properties:
|
||||
@@ -589,8 +604,6 @@ components:
|
||||
type: string
|
||||
enum: ["api", "integration", "jwt"]
|
||||
example: api
|
||||
type: string
|
||||
example: api
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
|
||||
@@ -69,6 +69,20 @@ const (
|
||||
GeoLocationCheckActionDeny GeoLocationCheckAction = "deny"
|
||||
)
|
||||
|
||||
// Defines values for GroupIssued.
|
||||
const (
|
||||
GroupIssuedApi GroupIssued = "api"
|
||||
GroupIssuedIntegration GroupIssued = "integration"
|
||||
GroupIssuedJwt GroupIssued = "jwt"
|
||||
)
|
||||
|
||||
// Defines values for GroupMinimumIssued.
|
||||
const (
|
||||
GroupMinimumIssuedApi GroupMinimumIssued = "api"
|
||||
GroupMinimumIssuedIntegration GroupMinimumIssued = "integration"
|
||||
GroupMinimumIssuedJwt GroupMinimumIssued = "jwt"
|
||||
)
|
||||
|
||||
// Defines values for NameserverNsType.
|
||||
const (
|
||||
NameserverNsTypeUdp NameserverNsType = "udp"
|
||||
@@ -129,6 +143,13 @@ const (
|
||||
UserStatusInvited UserStatus = "invited"
|
||||
)
|
||||
|
||||
// Defines values for UserPermissionsDashboardView.
|
||||
const (
|
||||
UserPermissionsDashboardViewBlocked UserPermissionsDashboardView = "blocked"
|
||||
UserPermissionsDashboardViewFull UserPermissionsDashboardView = "full"
|
||||
UserPermissionsDashboardViewLimited UserPermissionsDashboardView = "limited"
|
||||
)
|
||||
|
||||
// AccessiblePeer defines model for AccessiblePeer.
|
||||
type AccessiblePeer struct {
|
||||
// DnsLabel Peer's DNS label is the parsed peer name for domain resolution. It is used to form an FQDN by appending the account's domain to the peer label. e.g. peer-dns-label.netbird.cloud
|
||||
@@ -186,6 +207,9 @@ type AccountSettings struct {
|
||||
|
||||
// PeerLoginExpirationEnabled Enables or disables peer login expiration globally. After peer's login has expired the user has to log in (authenticate). Applies only to peers that were added by a user (interactive SSO login).
|
||||
PeerLoginExpirationEnabled bool `json:"peer_login_expiration_enabled"`
|
||||
|
||||
// RegularUsersViewBlocked Allows blocking regular users from viewing parts of the system.
|
||||
RegularUsersViewBlocked bool `json:"regular_users_view_blocked"`
|
||||
}
|
||||
|
||||
// Checks List of objects that perform the actual checks
|
||||
@@ -283,8 +307,8 @@ type Group struct {
|
||||
// Id Group ID
|
||||
Id string `json:"id"`
|
||||
|
||||
// Issued How group was issued by API or from JWT token
|
||||
Issued *string `json:"issued,omitempty"`
|
||||
// Issued How the group was issued (api, integration, jwt)
|
||||
Issued *GroupIssued `json:"issued,omitempty"`
|
||||
|
||||
// Name Group Name identifier
|
||||
Name string `json:"name"`
|
||||
@@ -296,13 +320,16 @@ type Group struct {
|
||||
PeersCount int `json:"peers_count"`
|
||||
}
|
||||
|
||||
// GroupIssued How the group was issued (api, integration, jwt)
|
||||
type GroupIssued string
|
||||
|
||||
// GroupMinimum defines model for GroupMinimum.
|
||||
type GroupMinimum struct {
|
||||
// Id Group ID
|
||||
Id string `json:"id"`
|
||||
|
||||
// Issued How group was issued by API or from JWT token
|
||||
Issued *string `json:"issued,omitempty"`
|
||||
// Issued How the group was issued (api, integration, jwt)
|
||||
Issued *GroupMinimumIssued `json:"issued,omitempty"`
|
||||
|
||||
// Name Group Name identifier
|
||||
Name string `json:"name"`
|
||||
@@ -311,6 +338,9 @@ type GroupMinimum struct {
|
||||
PeersCount int `json:"peers_count"`
|
||||
}
|
||||
|
||||
// GroupMinimumIssued How the group was issued (api, integration, jwt)
|
||||
type GroupMinimumIssued string
|
||||
|
||||
// GroupRequest defines model for GroupRequest.
|
||||
type GroupRequest struct {
|
||||
// Name Group name identifier
|
||||
@@ -1072,7 +1102,8 @@ type User struct {
|
||||
LastLogin *time.Time `json:"last_login,omitempty"`
|
||||
|
||||
// Name User's name from idp provider
|
||||
Name string `json:"name"`
|
||||
Name string `json:"name"`
|
||||
Permissions *UserPermissions `json:"permissions,omitempty"`
|
||||
|
||||
// Role User's NetBird account role
|
||||
Role string `json:"role"`
|
||||
@@ -1102,6 +1133,15 @@ type UserCreateRequest struct {
|
||||
Role string `json:"role"`
|
||||
}
|
||||
|
||||
// UserPermissions defines model for UserPermissions.
|
||||
type UserPermissions struct {
|
||||
// DashboardView User's permission to view the dashboard
|
||||
DashboardView *UserPermissionsDashboardView `json:"dashboard_view,omitempty"`
|
||||
}
|
||||
|
||||
// UserPermissionsDashboardView User's permission to view the dashboard
|
||||
type UserPermissionsDashboardView string
|
||||
|
||||
// UserRequest defines model for UserRequest.
|
||||
type UserRequest struct {
|
||||
// AutoGroups Group IDs to auto-assign to peers registered by this user
|
||||
|
||||
@@ -35,19 +35,25 @@ func NewGroupsHandler(accountManager server.AccountManager, authCfg AuthCfg) *Gr
|
||||
// GetAllGroups list for the account
|
||||
func (h *GroupsHandler) GetAllGroups(w http.ResponseWriter, r *http.Request) {
|
||||
claims := h.claimsExtractor.FromRequestContext(r)
|
||||
account, _, err := h.accountManager.GetAccountFromToken(claims)
|
||||
account, user, err := h.accountManager.GetAccountFromToken(claims)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
http.Redirect(w, r, "/", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var groups []*api.Group
|
||||
for _, g := range account.Groups {
|
||||
groups = append(groups, toGroupResponse(account, g))
|
||||
groups, err := h.accountManager.GetAllGroups(account.Id, user.Id)
|
||||
if err != nil {
|
||||
util.WriteError(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
util.WriteJSONObject(w, groups)
|
||||
groupsResponse := make([]*api.Group, 0, len(groups))
|
||||
for _, group := range groups {
|
||||
groupsResponse = append(groupsResponse, toGroupResponse(account, group))
|
||||
}
|
||||
|
||||
util.WriteJSONObject(w, groupsResponse)
|
||||
}
|
||||
|
||||
// UpdateGroup handles update to a group identified by a given ID
|
||||
@@ -207,7 +213,7 @@ func (h *GroupsHandler) DeleteGroup(w http.ResponseWriter, r *http.Request) {
|
||||
// GetGroup returns a group
|
||||
func (h *GroupsHandler) GetGroup(w http.ResponseWriter, r *http.Request) {
|
||||
claims := h.claimsExtractor.FromRequestContext(r)
|
||||
account, _, err := h.accountManager.GetAccountFromToken(claims)
|
||||
account, user, err := h.accountManager.GetAccountFromToken(claims)
|
||||
if err != nil {
|
||||
util.WriteError(err, w)
|
||||
return
|
||||
@@ -221,7 +227,7 @@ func (h *GroupsHandler) GetGroup(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
group, err := h.accountManager.GetGroup(account.Id, groupID)
|
||||
group, err := h.accountManager.GetGroup(account.Id, groupID, user.Id)
|
||||
if err != nil {
|
||||
util.WriteError(err, w)
|
||||
return
|
||||
@@ -239,7 +245,7 @@ func toGroupResponse(account *server.Account, group *server.Group) *api.Group {
|
||||
gr := api.Group{
|
||||
Id: group.ID,
|
||||
Name: group.Name,
|
||||
Issued: &group.Issued,
|
||||
Issued: (*api.GroupIssued)(&group.Issued),
|
||||
}
|
||||
|
||||
for _, pid := range group.Peers {
|
||||
|
||||
@@ -37,7 +37,7 @@ func initGroupTestData(user *server.User, groups ...*server.Group) *GroupsHandle
|
||||
}
|
||||
return nil
|
||||
},
|
||||
GetGroupFunc: func(_, groupID string) (*server.Group, error) {
|
||||
GetGroupFunc: func(_, groupID, _ string) (*server.Group, error) {
|
||||
if groupID != "idofthegroup" {
|
||||
return nil, status.Errorf(status.NotFound, "not found")
|
||||
}
|
||||
@@ -187,7 +187,7 @@ func TestWriteGroup(t *testing.T) {
|
||||
expectedGroup: &api.Group{
|
||||
Id: "id-was-set",
|
||||
Name: "Default POSTed Group",
|
||||
Issued: &groupIssuedAPI,
|
||||
Issued: (*api.GroupIssued)(&groupIssuedAPI),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -209,7 +209,7 @@ func TestWriteGroup(t *testing.T) {
|
||||
expectedGroup: &api.Group{
|
||||
Id: "id-existed",
|
||||
Name: "Default POSTed Group",
|
||||
Issued: &groupIssuedAPI,
|
||||
Issued: (*api.GroupIssued)(&groupIssuedAPI),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -240,7 +240,7 @@ func TestWriteGroup(t *testing.T) {
|
||||
expectedGroup: &api.Group{
|
||||
Id: "id-jwt-group",
|
||||
Name: "changed",
|
||||
Issued: &groupIssuedJWT,
|
||||
Issued: (*api.GroupIssued)(&groupIssuedJWT),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -288,5 +288,8 @@ func toUserResponse(user *server.UserInfo, currenUserID string) *api.User {
|
||||
IsBlocked: user.IsBlocked,
|
||||
LastLogin: &user.LastLogin,
|
||||
Issued: &user.Issued,
|
||||
Permissions: &api.UserPermissions{
|
||||
DashboardView: (*api.UserPermissionsDashboardView)(&user.Permissions.DashboardView),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ func initUsersTestData() *UsersHandler {
|
||||
return nil, status.Errorf(status.NotFound, "user with ID %s does not exists", userID)
|
||||
}
|
||||
|
||||
info, err := update.Copy().ToUserInfo(nil)
|
||||
info, err := update.Copy().ToUserInfo(nil, &server.Settings{RegularUsersViewBlocked: false})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user