Plugins: Pass OAuth Token to CallResource Function (#47028)

* adds oauth support to call resource requests

* adds oauth docs for call resource

* fixes case where dsUID is empty

* improve datasource error handling
This commit is contained in:
Braden Snell 2022-04-05 09:40:34 -06:00 committed by GitHub
parent 9b61f1cd9f
commit 3fff301367
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 0 deletions

View File

@ -315,4 +315,15 @@ func (ds *dataSource) QueryData(ctx context.Context, req *backend.QueryDataReque
}
```
The `Authorization` and `X-ID-Token` headers will also be available on the `CallResourceRequest` object on the `CallResource` request in your backend data source when `jsonData.oauthPassThru` is `true`.
```go
func (ds *dataSource) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
token := req.Headers["Authorization"]
idToken := req.Headers["X-ID-Token"] // present if user's token includes an ID token
// ...
}
```
> **Note:** Due to a bug in Grafana, using this feature with PostgreSQL can cause a deadlock. For more information, refer to [Grafana causes deadlocks in PostgreSQL, while trying to refresh users token](https://github.com/grafana/grafana/issues/20515).

View File

@ -506,6 +506,31 @@ func (hs *HTTPServer) callPluginResource(c *models.ReqContext, pluginID, dsUID s
}
clonedReq.URL = urlPath
if dsUID != "" {
ds, err := hs.DataSourceCache.GetDatasourceByUID(c.Req.Context(), dsUID, c.SignedInUser, c.SkipCache)
if err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
c.JsonApiErr(404, "Datasource not found", err)
return
}
c.JsonApiErr(500, "Failed to get datasource", err)
return
}
if hs.DataProxy.OAuthTokenService.IsOAuthPassThruEnabled(ds) {
if token := hs.DataProxy.OAuthTokenService.GetCurrentOAuthToken(c.Req.Context(), c.SignedInUser); token != nil {
clonedReq.Header.Add("Authorization", fmt.Sprintf("%s %s", token.Type(), token.AccessToken))
idToken, ok := token.Extra("id_token").(string)
if ok && idToken != "" {
clonedReq.Header.Add("X-ID-Token", idToken)
}
}
}
}
if err = hs.makePluginResourceRequest(c.Resp, clonedReq, pCtx); err != nil {
handleCallResourceError(err, c)
}