Files
Marcus Efraimsson 6768c6c059 Chore: Remove public vars in setting package (#81018)
Removes the public variable setting.SecretKey plus some other ones. 
Introduces some new functions for creating setting.Cfg.
2024-01-23 12:36:22 +01:00

151 lines
4.1 KiB
Go

package api
import (
"net/http"
"time"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/anonymous/anonimpl/anonstore"
"github.com/grafana/grafana/pkg/services/anonymous/sortopts"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
const anonymousDeviceExpiration = 30 * 24 * time.Hour
type deviceDTO struct {
anonstore.Device
LastSeenAt string `json:"lastSeenAt"`
AvatarUrl string `json:"avatarUrl"`
}
type AnonDeviceServiceAPI struct {
cfg *setting.Cfg
store anonstore.AnonStore
accesscontrol accesscontrol.AccessControl
RouterRegister routing.RouteRegister
log log.Logger
}
func NewAnonDeviceServiceAPI(
cfg *setting.Cfg,
anonstore anonstore.AnonStore,
accesscontrol accesscontrol.AccessControl,
routerRegister routing.RouteRegister,
) *AnonDeviceServiceAPI {
return &AnonDeviceServiceAPI{
cfg: cfg,
store: anonstore,
accesscontrol: accesscontrol,
RouterRegister: routerRegister,
log: log.New("anon.api"),
}
}
func (api *AnonDeviceServiceAPI) RegisterAPIEndpoints() {
auth := accesscontrol.Middleware(api.accesscontrol)
api.RouterRegister.Group("/api/anonymous", func(anonRoutes routing.RouteRegister) {
anonRoutes.Get("/devices", auth(accesscontrol.EvalPermission(accesscontrol.ActionUsersRead)), routing.Wrap(api.ListDevices))
anonRoutes.Get("/search", auth(accesscontrol.EvalPermission(accesscontrol.ActionUsersRead)), routing.Wrap(api.SearchDevices))
})
}
// swagger:route GET /stats devices listDevices
//
// # Lists all devices within the last 30 days
//
// Produces:
// - application/json
//
// Responses:
//
// 200: devicesResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (api *AnonDeviceServiceAPI) ListDevices(c *contextmodel.ReqContext) response.Response {
fromTime := time.Now().Add(-anonymousDeviceExpiration)
toTime := time.Now()
devices, err := api.store.ListDevices(c.Req.Context(), &fromTime, &toTime)
if err != nil {
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to list devices", err)
}
// convert to response format
resDevices := make([]*deviceDTO, 0, len(devices))
for _, device := range devices {
resDevices = append(resDevices, &deviceDTO{
Device: *device,
LastSeenAt: util.GetAgeString(device.UpdatedAt),
AvatarUrl: dtos.GetGravatarUrl(api.cfg, device.DeviceID),
})
}
return response.JSON(http.StatusOK, resDevices)
}
// swagger:route POST /search devices SearchDevices
//
// # Lists all devices within the last 30 days
//
// Produces:
// - application/json
//
// Responses:
//
// 200: devicesSearchResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (api *AnonDeviceServiceAPI) SearchDevices(c *contextmodel.ReqContext) response.Response {
perPage := c.QueryInt("perpage")
if perPage <= 0 {
perPage = 100
}
page := c.QueryInt("page")
if page < 1 {
page = 1
}
searchQuery := c.Query("query")
sortOpts, err := sortopts.ParseSortQueryParam(c.Query("sort"))
if err != nil {
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to list devices", err)
}
// TODO: potential add from and to time to query
query := &anonstore.SearchDeviceQuery{
Query: searchQuery,
Page: page,
Limit: perPage,
SortOpts: sortOpts,
}
results, err := api.store.SearchDevices(c.Req.Context(), query)
if err != nil {
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to list devices", err)
}
return response.JSON(http.StatusOK, results)
}
// swagger:response devicesResponse
type DevicesResponse struct {
// in:body
Body []deviceDTO `json:"body"`
}
// swagger:response devicesSearchResponse
type DevicesSearchResponse struct {
// in:body
Body anonstore.SearchDeviceQueryResult `json:"body"`
}