2021-11-11 09:10:24 -06:00
package serviceaccounts
2022-02-08 07:31:34 -06:00
import (
"time"
2023-10-24 04:01:04 -05:00
"github.com/grafana/grafana/pkg/models/roletype"
2022-02-08 07:31:34 -06:00
"github.com/grafana/grafana/pkg/services/accesscontrol"
2023-08-10 07:20:58 -05:00
"github.com/grafana/grafana/pkg/services/auth/identity"
2024-03-14 13:11:02 -05:00
"github.com/grafana/grafana/pkg/services/extsvcauth"
2022-08-10 04:56:48 -05:00
"github.com/grafana/grafana/pkg/services/org"
2023-03-01 10:31:20 -06:00
"github.com/grafana/grafana/pkg/util/errutil"
2022-02-08 07:31:34 -06:00
)
2021-11-11 09:10:24 -06:00
var (
ScopeAll = "serviceaccounts:*"
2022-02-07 07:51:54 -06:00
ScopeID = accesscontrol . Scope ( "serviceaccounts" , "id" , accesscontrol . Parameter ( ":serviceAccountId" ) )
2021-11-11 09:10:24 -06:00
)
2023-10-23 07:09:42 -05:00
const (
ServiceAccountPrefix = "sa-"
2023-10-24 04:01:04 -05:00
ExtSvcPrefix = "extsvc-"
2024-03-14 13:11:02 -05:00
ExtSvcLoginPrefix = ServiceAccountPrefix + extsvcauth . TmpOrgIDStr + "-" + ExtSvcPrefix
2023-10-23 07:09:42 -05:00
)
2021-11-11 09:10:24 -06:00
const (
2022-07-08 04:53:18 -05:00
ActionRead = "serviceaccounts:read"
ActionWrite = "serviceaccounts:write"
ActionCreate = "serviceaccounts:create"
ActionDelete = "serviceaccounts:delete"
ActionPermissionsRead = "serviceaccounts.permissions:read"
ActionPermissionsWrite = "serviceaccounts.permissions:write"
2021-11-11 09:10:24 -06:00
)
2021-12-14 07:39:25 -06:00
2023-03-01 10:31:20 -06:00
var (
2023-08-22 05:52:24 -05:00
ErrServiceAccountNotFound = errutil . NotFound ( "serviceaccounts.ErrNotFound" , errutil . WithPublicMessage ( "service account not found" ) )
ErrServiceAccountInvalidRole = errutil . BadRequest ( "serviceaccounts.ErrInvalidRoleSpecified" , errutil . WithPublicMessage ( "invalid role specified" ) )
ErrServiceAccountRolePrivilegeDenied = errutil . Forbidden ( "serviceaccounts.ErrRoleForbidden" , errutil . WithPublicMessage ( "can not assign a role higher than user's role" ) )
ErrServiceAccountInvalidOrgID = errutil . BadRequest ( "serviceaccounts.ErrInvalidOrgId" , errutil . WithPublicMessage ( "invalid org id specified" ) )
ErrServiceAccountInvalidID = errutil . BadRequest ( "serviceaccounts.ErrInvalidId" , errutil . WithPublicMessage ( "invalid service account id specified" ) )
ErrServiceAccountInvalidAPIKeyID = errutil . BadRequest ( "serviceaccounts.ErrInvalidAPIKeyId" , errutil . WithPublicMessage ( "invalid api key id specified" ) )
ErrServiceAccountInvalidTokenID = errutil . BadRequest ( "serviceaccounts.ErrInvalidTokenId" , errutil . WithPublicMessage ( "invalid service account token id specified" ) )
ErrServiceAccountAlreadyExists = errutil . BadRequest ( "serviceaccounts.ErrAlreadyExists" , errutil . WithPublicMessage ( "service account already exists" ) )
ErrServiceAccountTokenNotFound = errutil . NotFound ( "serviceaccounts.ErrTokenNotFound" , errutil . WithPublicMessage ( "service account token not found" ) )
ErrInvalidTokenExpiration = errutil . ValidationFailed ( "serviceaccounts.ErrInvalidInput" , errutil . WithPublicMessage ( "invalid SecondsToLive value" ) )
ErrDuplicateToken = errutil . BadRequest ( "serviceaccounts.ErrTokenAlreadyExists" , errutil . WithPublicMessage ( "service account token with given name already exists in the organization" ) )
2023-03-01 10:31:20 -06:00
)
2023-06-08 03:09:30 -05:00
type MigrationResult struct {
2023-06-08 05:12:26 -05:00
Total int ` json:"total" `
Migrated int ` json:"migrated" `
Failed int ` json:"failed" `
FailedApikeyIDs [ ] int64 ` json:"failedApikeyIDs" `
FailedDetails [ ] string ` json:"failedDetails" `
2023-06-08 03:09:30 -05:00
}
2021-12-14 07:39:25 -06:00
type ServiceAccount struct {
Id int64
}
2022-07-19 04:52:51 -05:00
// swagger:model
2022-06-16 09:02:03 -05:00
type CreateServiceAccountForm struct {
2022-07-19 04:52:51 -05:00
// example: grafana
Name string ` json:"name" binding:"Required" `
// example: Admin
2022-08-10 04:56:48 -05:00
Role * org . RoleType ` json:"role" `
2022-07-19 04:52:51 -05:00
// example: false
IsDisabled * bool ` json:"isDisabled" `
2022-06-16 09:02:03 -05:00
}
2022-07-19 04:52:51 -05:00
// swagger:model
2022-02-17 06:19:58 -06:00
type UpdateServiceAccountForm struct {
2022-12-13 07:56:10 -06:00
Name * string ` json:"name" `
ServiceAccountID int64 ` json:"serviceAccountId" `
Role * org . RoleType ` json:"role" `
IsDisabled * bool ` json:"isDisabled" `
2022-02-17 06:19:58 -06:00
}
2022-07-19 04:52:51 -05:00
// swagger: model
2022-02-08 07:31:34 -06:00
type ServiceAccountDTO struct {
2022-07-19 04:52:51 -05:00
Id int64 ` json:"id" xorm:"user_id" `
// example: grafana
Name string ` json:"name" xorm:"name" `
// example: sa-grafana
Login string ` json:"login" xorm:"login" `
// example: 1
OrgId int64 ` json:"orgId" xorm:"org_id" `
// example: false
IsDisabled bool ` json:"isDisabled" xorm:"is_disabled" `
2023-10-24 08:54:14 -05:00
// example: false
2023-11-09 10:45:46 -06:00
IsExternal bool ` json:"isExternal,omitempty" xorm:"-" `
2022-07-19 04:52:51 -05:00
// example: Viewer
Role string ` json:"role" xorm:"role" `
// example: 0
Tokens int64 ` json:"tokens" `
// example: /avatar/85ec38023d90823d3e5b43ef35646af9
AvatarUrl string ` json:"avatarUrl" `
// example: {"serviceaccounts:delete": true, "serviceaccounts:read": true, "serviceaccounts:write": true}
2022-02-08 13:19:22 -06:00
AccessControl map [ string ] bool ` json:"accessControl,omitempty" `
2022-02-08 07:31:34 -06:00
}
2022-04-13 11:11:03 -05:00
2022-08-18 09:54:39 -05:00
type GetSATokensQuery struct {
OrgID * int64 // optional filtering by org ID
ServiceAccountID * int64 // optional filtering by service account ID
}
2022-04-13 11:11:03 -05:00
type AddServiceAccountTokenCommand struct {
2023-01-31 02:51:55 -06:00
Name string ` json:"name" binding:"Required" `
OrgId int64 ` json:"-" `
Key string ` json:"-" `
SecondsToLive int64 ` json:"secondsToLive" `
2022-04-13 11:11:03 -05:00
}
2022-12-13 07:56:10 -06:00
type SearchOrgServiceAccountsQuery struct {
OrgID int64
Query string
Filter ServiceAccountFilter
Page int
Limit int
2023-10-24 08:54:14 -05:00
CountOnly bool
2023-08-10 07:20:58 -05:00
SignedInUser identity . Requester
2022-12-13 07:56:10 -06:00
}
func ( q * SearchOrgServiceAccountsQuery ) SetDefaults ( ) {
q . Page = 1
q . Limit = 100
}
2022-07-19 04:52:51 -05:00
// swagger: model
2022-12-13 07:56:10 -06:00
type SearchOrgServiceAccountsResult struct {
2022-07-19 04:52:51 -05:00
// It can be used for pagination of the user list
// E.g. if totalCount is equal to 100 users and
// the perpage parameter is set to 10 then there are 10 pages of users.
2022-03-14 12:24:07 -05:00
TotalCount int64 ` json:"totalCount" `
ServiceAccounts [ ] * ServiceAccountDTO ` json:"serviceAccounts" `
Page int ` json:"page" `
PerPage int ` json:"perPage" `
}
2022-02-08 07:31:34 -06:00
2022-07-19 04:52:51 -05:00
// swagger:model
2022-02-08 07:31:34 -06:00
type ServiceAccountProfileDTO struct {
2022-07-19 04:52:51 -05:00
// example: 2
Id int64 ` json:"id" xorm:"user_id" `
// example: test
Name string ` json:"name" xorm:"name" `
// example: sa-grafana
Login string ` json:"login" xorm:"login" `
// example: 1
OrgId int64 ` json:"orgId" xorm:"org_id" `
// example: false
IsDisabled bool ` json:"isDisabled" xorm:"is_disabled" `
// example: 2022-03-21T14:35:33Z
Created time . Time ` json:"createdAt" xorm:"created" `
// example: 2022-03-21T14:35:33Z
Updated time . Time ` json:"updatedAt" xorm:"updated" `
// example: /avatar/8ea890a677d6a223c591a1beea6ea9d2
AvatarUrl string ` json:"avatarUrl" xorm:"-" `
// example: Editor
Role string ` json:"role" xorm:"role" `
// example: []
2023-10-23 07:09:42 -05:00
Teams [ ] string ` json:"teams" xorm:"-" `
// example: false
2023-11-09 10:45:46 -06:00
IsExternal bool ` json:"isExternal,omitempty" xorm:"-" `
2023-11-14 10:52:48 -06:00
// example: grafana-app
RequiredBy string ` json:"requiredBy,omitempty" xorm:"-" `
2023-10-23 07:09:42 -05:00
2022-06-01 02:35:16 -05:00
Tokens int64 ` json:"tokens,omitempty" `
2022-03-01 02:21:55 -06:00
AccessControl map [ string ] bool ` json:"accessControl,omitempty" xorm:"-" `
2022-02-08 07:31:34 -06:00
}
2022-03-18 09:50:34 -05:00
type ServiceAccountFilter string // used for filtering
const (
FilterOnlyExpiredTokens ServiceAccountFilter = "expiredTokens"
2022-06-01 02:35:16 -05:00
FilterOnlyDisabled ServiceAccountFilter = "disabled"
2022-03-18 09:50:34 -05:00
FilterIncludeAll ServiceAccountFilter = "all"
2023-10-24 08:54:14 -05:00
FilterOnlyExternal ServiceAccountFilter = "external"
2022-03-18 09:50:34 -05:00
)
2022-08-23 07:24:55 -05:00
type Stats struct {
2023-08-16 03:56:47 -05:00
ServiceAccounts int64 ` xorm:"serviceaccounts" `
ServiceAccountsWithNoRole int64 ` xorm:"serviceaccounts_with_no_role" `
Tokens int64 ` xorm:"serviceaccount_tokens" `
ForcedExpiryEnabled bool ` xorm:"-" `
2022-08-23 07:24:55 -05:00
}
2022-09-22 15:04:48 -05:00
2023-10-24 04:01:04 -05:00
// ExtSvcAccount represents the service account associated to an external service
type ExtSvcAccount struct {
ID int64
Login string
Name string
OrgID int64
IsDisabled bool
Role roletype . RoleType
}
type ManageExtSvcAccountCmd struct {
ExtSvcSlug string
2023-10-27 07:27:06 -05:00
Enabled bool
2023-10-24 04:01:04 -05:00
OrgID int64
Permissions [ ] accesscontrol . Permission
}
2023-10-27 06:46:25 -05:00
type EnableExtSvcAccountCmd struct {
ExtSvcSlug string
Enabled bool
OrgID int64
}
2022-09-22 15:04:48 -05:00
// AccessEvaluator is used to protect the "Configuration > Service accounts" page access
var AccessEvaluator = accesscontrol . EvalAny (
accesscontrol . EvalPermission ( ActionRead ) ,
accesscontrol . EvalPermission ( ActionCreate ) ,
)