2015-02-12 15:46:14 +01:00
package api
import (
2021-06-14 17:36:48 +02:00
"context"
"net/http"
2021-01-15 14:43:20 +01:00
"github.com/grafana/grafana/pkg/api/response"
2021-08-24 11:36:28 +02:00
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
2023-01-27 08:50:36 +01:00
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
2023-01-17 14:17:54 +01:00
"github.com/grafana/grafana/pkg/services/stats"
2022-08-10 11:56:48 +02:00
"github.com/grafana/grafana/pkg/services/user"
2021-06-14 17:36:48 +02:00
"github.com/grafana/grafana/pkg/setting"
2015-02-12 15:46:14 +01:00
)
2022-07-27 16:54:37 +03:00
// swagger:route GET /admin/settings admin adminGetSettings
//
// Fetch settings.
//
// If you are running Grafana Enterprise and have Fine-grained access control enabled, you need to have a permission with action `settings:read` and scopes: `settings:*`, `settings:auth.saml:` and `settings:auth.saml:enabled` (property level).
//
// Security:
// - basic:
//
// Responses:
// 200: adminGetSettingsResponse
// 401: unauthorisedError
// 403: forbiddenError
2023-01-27 08:50:36 +01:00
func ( hs * HTTPServer ) AdminGetSettings ( c * contextmodel . ReqContext ) response . Response {
2021-06-14 17:36:48 +02:00
settings , err := hs . getAuthorizedSettings ( c . Req . Context ( ) , c . SignedInUser , hs . SettingsProvider . Current ( ) )
if err != nil {
return response . Error ( http . StatusForbidden , "Failed to authorize settings" , err )
}
return response . JSON ( http . StatusOK , settings )
2015-02-12 15:46:14 +01:00
}
2016-01-24 11:01:33 -08:00
2023-04-20 10:43:28 +02:00
func ( hs * HTTPServer ) AdminGetVerboseSettings ( c * contextmodel . ReqContext ) response . Response {
bag := hs . SettingsProvider . CurrentVerbose ( )
if bag == nil {
return response . JSON ( http . StatusNotImplemented , make ( map [ string ] string ) )
}
verboseSettings , err := hs . getAuthorizedVerboseSettings ( c . Req . Context ( ) , c . SignedInUser , bag )
if err != nil {
return response . Error ( http . StatusForbidden , "Failed to authorize settings" , err )
}
return response . JSON ( http . StatusOK , verboseSettings )
}
2022-07-27 16:54:37 +03:00
// swagger:route GET /admin/stats admin adminGetStats
//
// Fetch Grafana Stats.
//
// Only works with Basic Authentication (username and password). See introduction for an explanation.
// If you are running Grafana Enterprise and have Fine-grained access control enabled, you need to have a permission with action `server:stats:read`.
//
// Responses:
// 200: adminGetStatsResponse
// 401: unauthorisedError
// 403: forbiddenError
// 500: internalServerError
2023-01-27 08:50:36 +01:00
func ( hs * HTTPServer ) AdminGetStats ( c * contextmodel . ReqContext ) response . Response {
2023-03-30 08:08:47 +02:00
adminStats , err := hs . statsService . GetAdminStats ( c . Req . Context ( ) , & stats . GetAdminStatsQuery { } )
if err != nil {
2021-01-15 14:43:20 +01:00
return response . Error ( 500 , "Failed to get admin stats from database" , err )
2016-01-24 21:18:17 -08:00
}
2023-03-30 08:08:47 +02:00
return response . JSON ( http . StatusOK , adminStats )
2016-01-24 11:01:33 -08:00
}
2021-06-14 17:36:48 +02:00
2022-08-10 11:56:48 +02:00
func ( hs * HTTPServer ) getAuthorizedSettings ( ctx context . Context , user * user . SignedInUser , bag setting . SettingsBag ) ( setting . SettingsBag , error ) {
2021-08-24 11:36:28 +02:00
eval := func ( scope string ) ( bool , error ) {
return hs . AccessControl . Evaluate ( ctx , user , ac . EvalPermission ( ac . ActionSettingsRead , scope ) )
2021-06-14 17:36:48 +02:00
}
2021-08-24 11:36:28 +02:00
ok , err := eval ( ac . ScopeSettingsAll )
2021-06-14 17:36:48 +02:00
if err != nil {
return nil , err
}
if ok {
return bag , nil
}
authorizedBag := make ( setting . SettingsBag )
for section , keys := range bag {
2021-08-24 11:36:28 +02:00
ok , err := eval ( ac . Scope ( "settings" , section , "*" ) )
2021-06-14 17:36:48 +02:00
if err != nil {
return nil , err
}
if ok {
authorizedBag [ section ] = keys
continue
}
for key := range keys {
2021-08-24 11:36:28 +02:00
ok , err := eval ( ac . Scope ( "settings" , section , key ) )
2021-06-14 17:36:48 +02:00
if err != nil {
return nil , err
}
if ok {
if _ , exists := authorizedBag [ section ] ; ! exists {
authorizedBag [ section ] = make ( map [ string ] string )
}
authorizedBag [ section ] [ key ] = bag [ section ] [ key ]
}
}
}
return authorizedBag , nil
}
2022-07-27 16:54:37 +03:00
2023-04-20 10:43:28 +02:00
func ( hs * HTTPServer ) getAuthorizedVerboseSettings ( ctx context . Context , user * user . SignedInUser , bag setting . VerboseSettingsBag ) ( setting . VerboseSettingsBag , error ) {
eval := func ( scope string ) ( bool , error ) {
return hs . AccessControl . Evaluate ( ctx , user , ac . EvalPermission ( ac . ActionSettingsRead , scope ) )
}
ok , err := eval ( ac . ScopeSettingsAll )
if err != nil {
return nil , err
}
if ok {
return bag , nil
}
authorizedBag := make ( setting . VerboseSettingsBag )
for section , keys := range bag {
ok , err := eval ( ac . Scope ( "settings" , section , "*" ) )
if err != nil {
return nil , err
}
if ok {
authorizedBag [ section ] = keys
continue
}
for key := range keys {
ok , err := eval ( ac . Scope ( "settings" , section , key ) )
if err != nil {
return nil , err
}
if ! ok {
continue
}
if _ , exists := authorizedBag [ section ] ; ! exists {
authorizedBag [ section ] = make ( map [ string ] map [ setting . VerboseSourceType ] string )
}
authorizedBag [ section ] [ key ] = bag [ section ] [ key ]
}
}
return authorizedBag , nil
}
2022-07-27 16:54:37 +03:00
// swagger:response adminGetSettingsResponse
type GetSettingsResponse struct {
// in:body
Body setting . SettingsBag ` json:"body" `
}
// swagger:response adminGetStatsResponse
type GetStatsResponse struct {
// in:body
2023-01-17 14:17:54 +01:00
Body stats . AdminStats ` json:"body" `
2022-07-27 16:54:37 +03:00
}