How to save data within CheckHealth

Hey there!
I’m writing a backend plugin for Grafana and I am unsure on how to proceed an issue.

I’m currently writing a datasource plugin that requires authorizing with Google OAuth2. It goes like this:

  • a person goes to a Google page, asking for consent for a specific client ID and scopes
  • a person is redirected to some URI
  • this code (one-time use) is sent to a Google server, then access and refresh tokens are returned
  • these tokens are used to request Google API.

I’ve figured out how to get a code from user: make a link to Google on a frontend side with redirect_uri as the Grafana editing datasource URI. This will redirect user back, then I can get the code from the query string.

Question is, I need to exchange it and receive access and refresh token and somehow store it in the database. Can I do it from within a healthcheck endpoint?

Here’s currently what I have:

// CheckHealth handles health checks sent from Grafana to the plugin.
// The main use case for these health checks is the test button on the
// datasource configuration page which allows users to verify that
// a datasource is working as expected.
func (td *SampleDatasource) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
	log.DefaultLogger.Info("QueryData", "request", req.PluginContext.DataSourceInstanceSettings)

	if val, ok := req.PluginContext.DataSourceInstanceSettings.DecryptedSecureJSONData["code"]; !ok || val == "" {
		return &backend.CheckHealthResult{
			Status:  backend.HealthStatusError,
			Message: "Code is not provided. Please press \"Sign in with Google\"",
		}, nil
	}

	if val, ok := req.PluginContext.DataSourceInstanceSettings.DecryptedSecureJSONData["clientSecret"]; !ok || val == "" {
		return &backend.CheckHealthResult{
			Status:  backend.HealthStatusError,
			Message: "Client secret is not provided",
		}, nil
	}

	jsonData, err := simplejson.NewJson([]byte(req.PluginContext.DataSourceInstanceSettings.JSONData))
	if err != nil {
		return &backend.CheckHealthResult{
			Status:  backend.HealthStatusError,
			Message: "Could not parse JSON",
		}, nil
	}

	clientID := jsonData.Get("clientId").MustString()
	if clientID == "" {
		return &backend.CheckHealthResult{
			Status:  backend.HealthStatusError,
			Message: "Client ID is not provided",
		}, nil
	}

	redirectURI := jsonData.Get("redirectURI").MustString()
	if redirectURI == "" {
		return &backend.CheckHealthResult{
			Status:  backend.HealthStatusError,
			Message: "Redirect URI is not provided",
		}, nil
	}

	clientSecret := req.PluginContext.DataSourceInstanceSettings.DecryptedSecureJSONData["clientSecret"]
	code := req.PluginContext.DataSourceInstanceSettings.DecryptedSecureJSONData["code"]

	log.DefaultLogger.Info("QueryData", "clientId", clientID)
	log.DefaultLogger.Info("QueryData", "clientSecret", clientSecret)
	log.DefaultLogger.Info("QueryData", "code", code)
	log.DefaultLogger.Info("QueryData", "redirectURI", redirectURI)

	if token, err = getToken(ctx, clientID, clientSecret, code, redirectURI); err != nil {
		return &backend.CheckHealthResult{
			Status:  backend.HealthStatusError,
			Message: "Error authorizing",
		}, nil
	}
	

	return &backend.CheckHealthResult{
		Status:  backend.HealthStatusOk,
		Message: "Everything is okay.",
	}, nil
}

func getToken(ctx context.Context, clientID string, clientSecret string, code string, redirectURI string) (*oauth2.Token, error) {
	conf := &oauth2.Config{
		ClientID:     clientID,
		ClientSecret: clientSecret,
		Endpoint:     google.Endpoint,
		RedirectURL:  redirectURI,
	}

	token, err := conf.Exchange(ctx, code)
	log.DefaultLogger.Debug("QueryData", "err", err)
	log.DefaultLogger.Debug("QueryData", "token", token)
	if err != nil {
		return nil, err
	}

	return token, err
}

I need to store access and refresh tokens somehow on backend based on what user has sent and I’m not sure how to proceed here. How can I do this?
The code is saved to the DB but unfortunately it only can be use once.