ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
1 changed files with 145336 additions and 0 deletions
66
packages/grafana-rcon/backend/auth.go
Normal file
66
packages/grafana-rcon/backend/auth.go
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/authlib/authn"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/config"
|
||||
)
|
||||
|
||||
type authorizer struct {
|
||||
url string
|
||||
client *http.Client
|
||||
verifier authn.Verifier[struct{}]
|
||||
}
|
||||
|
||||
func newAuthorizer(base string) *authorizer {
|
||||
base = strings.TrimRight(base, "/")
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
keys := authn.NewKeyRetriever(authn.KeyRetrieverConfig{SigningKeysURL: base + "/api/signing-keys/keys"}, authn.WithHTTPClientKeyRetrieverOpt(client))
|
||||
return &authorizer{
|
||||
url: base,
|
||||
client: client,
|
||||
verifier: authn.NewVerifier[struct{}](authn.VerifierConfig{}, authn.TokenTypeID, keys),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *authorizer) canSubmit(req *http.Request) (bool, error) {
|
||||
cfg := config.GrafanaConfigFromContext(req.Context())
|
||||
token, err := cfg.PluginAppClientSecret()
|
||||
if err != nil || token == "" {
|
||||
return false, errors.New("plugin service account is unavailable")
|
||||
}
|
||||
claims, err := a.verifier.Verify(req.Context(), req.Header.Get("X-Grafana-Id"))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
id, ok := strings.CutPrefix(claims.Subject, "user:")
|
||||
if !ok || id == "" {
|
||||
return false, nil
|
||||
}
|
||||
request, err := http.NewRequestWithContext(req.Context(), "GET", a.url+"/api/users/"+url.PathEscape(id), nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
request.Header.Set("Authorization", "Bearer "+token)
|
||||
response, err := a.client.Do(request)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return false, errors.New("user lookup is unavailable")
|
||||
}
|
||||
var profile struct {
|
||||
Admin bool `json:"isGrafanaAdmin"`
|
||||
}
|
||||
if err := json.NewDecoder(response.Body).Decode(&profile); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return profile.Admin, nil
|
||||
}
|
||||
Loading…
Reference in a new issue