mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'develop' into panel-title-menu-ux
This commit is contained in:
95
pkg/models/dashboard_acl.go
Normal file
95
pkg/models/dashboard_acl.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PermissionType int
|
||||
|
||||
const (
|
||||
PERMISSION_VIEW PermissionType = 1 << iota
|
||||
PERMISSION_EDIT
|
||||
PERMISSION_ADMIN
|
||||
)
|
||||
|
||||
func (p PermissionType) String() string {
|
||||
names := map[int]string{
|
||||
int(PERMISSION_VIEW): "View",
|
||||
int(PERMISSION_EDIT): "Edit",
|
||||
int(PERMISSION_ADMIN): "Admin",
|
||||
}
|
||||
return names[int(p)]
|
||||
}
|
||||
|
||||
// Typed errors
|
||||
var (
|
||||
ErrDashboardAclInfoMissing = errors.New("User id and user group id cannot both be empty for a dashboard permission.")
|
||||
ErrDashboardPermissionDashboardEmpty = errors.New("Dashboard Id must be greater than zero for a dashboard permission.")
|
||||
)
|
||||
|
||||
// Dashboard ACL model
|
||||
type DashboardAcl struct {
|
||||
Id int64
|
||||
OrgId int64
|
||||
DashboardId int64
|
||||
|
||||
UserId int64
|
||||
UserGroupId int64
|
||||
Role *RoleType // pointer to be nullable
|
||||
Permission PermissionType
|
||||
|
||||
Created time.Time
|
||||
Updated time.Time
|
||||
}
|
||||
|
||||
type DashboardAclInfoDTO struct {
|
||||
Id int64 `json:"id"`
|
||||
OrgId int64 `json:"-"`
|
||||
DashboardId int64 `json:"dashboardId"`
|
||||
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
|
||||
UserId int64 `json:"userId"`
|
||||
UserLogin string `json:"userLogin"`
|
||||
UserEmail string `json:"userEmail"`
|
||||
UserGroupId int64 `json:"userGroupId"`
|
||||
UserGroup string `json:"userGroup"`
|
||||
Role *RoleType `json:"role,omitempty"`
|
||||
Permission PermissionType `json:"permission"`
|
||||
PermissionName string `json:"permissionName"`
|
||||
}
|
||||
|
||||
//
|
||||
// COMMANDS
|
||||
//
|
||||
|
||||
type UpdateDashboardAclCommand struct {
|
||||
DashboardId int64
|
||||
Items []*DashboardAcl
|
||||
}
|
||||
|
||||
type SetDashboardAclCommand struct {
|
||||
DashboardId int64
|
||||
OrgId int64
|
||||
UserId int64
|
||||
UserGroupId int64
|
||||
Permission PermissionType
|
||||
|
||||
Result DashboardAcl
|
||||
}
|
||||
|
||||
type RemoveDashboardAclCommand struct {
|
||||
AclId int64
|
||||
OrgId int64
|
||||
}
|
||||
|
||||
//
|
||||
// QUERIES
|
||||
//
|
||||
type GetDashboardAclInfoListQuery struct {
|
||||
DashboardId int64
|
||||
OrgId int64
|
||||
Result []*DashboardAclInfoDTO
|
||||
}
|
||||
21
pkg/models/dashboard_acl_test.go
Normal file
21
pkg/models/dashboard_acl_test.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"fmt"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDashboardAclModel(t *testing.T) {
|
||||
|
||||
Convey("When printing a PermissionType", t, func() {
|
||||
view := PERMISSION_VIEW
|
||||
printed := fmt.Sprint(view)
|
||||
|
||||
Convey("Should output a friendly name", func() {
|
||||
So(printed, ShouldEqual, "View")
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -11,11 +11,12 @@ import (
|
||||
|
||||
// Typed errors
|
||||
var (
|
||||
ErrDashboardNotFound = errors.New("Dashboard not found")
|
||||
ErrDashboardSnapshotNotFound = errors.New("Dashboard snapshot not found")
|
||||
ErrDashboardWithSameNameExists = errors.New("A dashboard with the same name already exists")
|
||||
ErrDashboardVersionMismatch = errors.New("The dashboard has been changed by someone else")
|
||||
ErrDashboardTitleEmpty = errors.New("Dashboard title cannot be empty")
|
||||
ErrDashboardNotFound = errors.New("Dashboard not found")
|
||||
ErrDashboardSnapshotNotFound = errors.New("Dashboard snapshot not found")
|
||||
ErrDashboardWithSameNameExists = errors.New("A dashboard with the same name already exists")
|
||||
ErrDashboardVersionMismatch = errors.New("The dashboard has been changed by someone else")
|
||||
ErrDashboardTitleEmpty = errors.New("Dashboard title cannot be empty")
|
||||
ErrDashboardFolderCannotHaveParent = errors.New("A Dashboard Folder cannot be added to another folder")
|
||||
)
|
||||
|
||||
type UpdatePluginDashboardError struct {
|
||||
@@ -47,6 +48,9 @@ type Dashboard struct {
|
||||
|
||||
UpdatedBy int64
|
||||
CreatedBy int64
|
||||
FolderId int64
|
||||
IsFolder bool
|
||||
HasAcl bool
|
||||
|
||||
Title string
|
||||
Data *simplejson.Json
|
||||
@@ -111,6 +115,8 @@ func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
|
||||
dash.UpdatedBy = userId
|
||||
dash.OrgId = cmd.OrgId
|
||||
dash.PluginId = cmd.PluginId
|
||||
dash.IsFolder = cmd.IsFolder
|
||||
dash.FolderId = cmd.FolderId
|
||||
dash.UpdateSlug()
|
||||
return dash
|
||||
}
|
||||
@@ -138,12 +144,14 @@ type SaveDashboardCommand struct {
|
||||
OrgId int64 `json:"-"`
|
||||
RestoredFrom int `json:"-"`
|
||||
PluginId string `json:"-"`
|
||||
FolderId int64 `json:"folderId"`
|
||||
IsFolder bool `json:"isFolder"`
|
||||
|
||||
Result *Dashboard
|
||||
}
|
||||
|
||||
type DeleteDashboardCommand struct {
|
||||
Slug string
|
||||
Id int64
|
||||
OrgId int64
|
||||
}
|
||||
|
||||
|
||||
@@ -28,4 +28,27 @@ func TestDashboardModel(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Given a new dashboard folder", t, func() {
|
||||
json := simplejson.New()
|
||||
json.Set("title", "test dash")
|
||||
|
||||
cmd := &SaveDashboardCommand{Dashboard: json, IsFolder: true}
|
||||
dash := cmd.GetDashboardModel()
|
||||
|
||||
Convey("Should set IsFolder to true", func() {
|
||||
So(dash.IsFolder, ShouldBeTrue)
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Given a child dashboard", t, func() {
|
||||
json := simplejson.New()
|
||||
json.Set("title", "test dash")
|
||||
|
||||
cmd := &SaveDashboardCommand{Dashboard: json, FolderId: 1}
|
||||
dash := cmd.GetDashboardModel()
|
||||
|
||||
Convey("Should set FolderId", func() {
|
||||
So(dash.FolderId, ShouldEqual, 1)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -32,11 +32,20 @@ func (r RoleType) Includes(other RoleType) bool {
|
||||
if r == ROLE_ADMIN {
|
||||
return true
|
||||
}
|
||||
if r == ROLE_EDITOR || r == ROLE_READ_ONLY_EDITOR {
|
||||
return other != ROLE_ADMIN
|
||||
|
||||
if other == ROLE_READ_ONLY_EDITOR {
|
||||
return r == ROLE_EDITOR || r == ROLE_READ_ONLY_EDITOR
|
||||
}
|
||||
|
||||
return r == other
|
||||
if other == ROLE_EDITOR {
|
||||
return r == ROLE_EDITOR
|
||||
}
|
||||
|
||||
if other == ROLE_VIEWER {
|
||||
return r == ROLE_READ_ONLY_EDITOR || r == ROLE_EDITOR || r == ROLE_VIEWER
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *RoleType) UnmarshalJSON(data []byte) error {
|
||||
|
||||
@@ -162,6 +162,14 @@ type SignedInUser struct {
|
||||
HelpFlags1 HelpFlags1
|
||||
}
|
||||
|
||||
func (user *SignedInUser) HasRole(role RoleType) bool {
|
||||
if user.IsGrafanaAdmin {
|
||||
return true
|
||||
}
|
||||
|
||||
return user.OrgRole.Includes(role)
|
||||
}
|
||||
|
||||
type UserProfileDTO struct {
|
||||
Id int64 `json:"id"`
|
||||
Email string `json:"email"`
|
||||
|
||||
68
pkg/models/user_group.go
Normal file
68
pkg/models/user_group.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Typed errors
|
||||
var (
|
||||
ErrUserGroupNotFound = errors.New("User Group not found")
|
||||
ErrUserGroupNameTaken = errors.New("User Group name is taken")
|
||||
)
|
||||
|
||||
// UserGroup model
|
||||
type UserGroup struct {
|
||||
Id int64 `json:"id"`
|
||||
OrgId int64 `json:"orgId"`
|
||||
Name string `json:"name"`
|
||||
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
// COMMANDS
|
||||
|
||||
type CreateUserGroupCommand struct {
|
||||
Name string `json:"name" binding:"Required"`
|
||||
OrgId int64 `json:"-"`
|
||||
|
||||
Result UserGroup `json:"-"`
|
||||
}
|
||||
|
||||
type UpdateUserGroupCommand struct {
|
||||
Id int64
|
||||
Name string
|
||||
}
|
||||
|
||||
type DeleteUserGroupCommand struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
type GetUserGroupByIdQuery struct {
|
||||
Id int64
|
||||
Result *UserGroup
|
||||
}
|
||||
|
||||
type GetUserGroupsByUserQuery struct {
|
||||
UserId int64 `json:"userId"`
|
||||
Result []*UserGroup `json:"userGroups"`
|
||||
}
|
||||
|
||||
type SearchUserGroupsQuery struct {
|
||||
Query string
|
||||
Name string
|
||||
Limit int
|
||||
Page int
|
||||
OrgId int64
|
||||
|
||||
Result SearchUserGroupQueryResult
|
||||
}
|
||||
|
||||
type SearchUserGroupQueryResult struct {
|
||||
TotalCount int64 `json:"totalCount"`
|
||||
UserGroups []*UserGroup `json:"userGroups"`
|
||||
Page int `json:"page"`
|
||||
PerPage int `json:"perPage"`
|
||||
}
|
||||
55
pkg/models/user_group_member.go
Normal file
55
pkg/models/user_group_member.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Typed errors
|
||||
var (
|
||||
ErrUserGroupMemberAlreadyAdded = errors.New("User is already added to this user group")
|
||||
)
|
||||
|
||||
// UserGroupMember model
|
||||
type UserGroupMember struct {
|
||||
Id int64
|
||||
OrgId int64
|
||||
UserGroupId int64
|
||||
UserId int64
|
||||
|
||||
Created time.Time
|
||||
Updated time.Time
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
// COMMANDS
|
||||
|
||||
type AddUserGroupMemberCommand struct {
|
||||
UserId int64 `json:"userId" binding:"Required"`
|
||||
OrgId int64 `json:"-"`
|
||||
UserGroupId int64 `json:"-"`
|
||||
}
|
||||
|
||||
type RemoveUserGroupMemberCommand struct {
|
||||
UserId int64
|
||||
UserGroupId int64
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
// QUERIES
|
||||
|
||||
type GetUserGroupMembersQuery struct {
|
||||
UserGroupId int64
|
||||
Result []*UserGroupMemberDTO
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
// Projections and DTOs
|
||||
|
||||
type UserGroupMemberDTO struct {
|
||||
OrgId int64 `json:"orgId"`
|
||||
UserGroupId int64 `json:"userGroupId"`
|
||||
UserId int64 `json:"userId"`
|
||||
Email string `json:"email"`
|
||||
Login string `json:"login"`
|
||||
}
|
||||
Reference in New Issue
Block a user