Initial cloud-services repo - gateway service + pkg modules
This commit is contained in:
136
pkg/superset/guest_token.go
Normal file
136
pkg/superset/guest_token.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package superset
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"fiskerinc.com/modules/httpclient"
|
||||
"fiskerinc.com/modules/redis"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var errUnauthorized = errors.New("superset unauthorized")
|
||||
|
||||
type (
|
||||
guestTokenRequest struct {
|
||||
User user `json:"user"`
|
||||
Resources []resource `json:"resources"`
|
||||
Rls []rule `json:"rls"`
|
||||
}
|
||||
user struct {
|
||||
UserName string `json:"username"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
}
|
||||
resource struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
rule struct {
|
||||
Clause string `json:"clause"`
|
||||
}
|
||||
|
||||
guestTokenResponse struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
)
|
||||
|
||||
func GetGuestToken(r redis.Client, accToken string) (string, error) {
|
||||
token, err := getGuestToken(accToken)
|
||||
if err == nil {
|
||||
return token, nil
|
||||
}
|
||||
if err != nil && !errors.Is(err, errUnauthorized) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// if unauthorized
|
||||
accToken, err = loginFunc(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return getGuestToken(accToken)
|
||||
}
|
||||
|
||||
func getGuestToken(accToken string) (string, error) {
|
||||
req, err := getGuestTokenReq(accToken)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := httpclient.Client.Do(req)
|
||||
if err != nil {
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode == http.StatusUnauthorized {
|
||||
return "", errors.WithStack(errUnauthorized)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", errors.Errorf("superset guest token answered with status: %s", resp.Status)
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
var structResp guestTokenResponse
|
||||
err = json.Unmarshal(body, &structResp)
|
||||
if err != nil {
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
return structResp.Token, nil
|
||||
}
|
||||
|
||||
func getGuestTokenReq(accToken string) (*http.Request, error) {
|
||||
body, err := json.Marshal(guestTokenRequest{
|
||||
User: user{
|
||||
UserName: guestUserName,
|
||||
FirstName: guestFirstName,
|
||||
LastName: guestLastName,
|
||||
},
|
||||
Resources: compileResources(accToken),
|
||||
Rls: []rule{},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, host+"/security/guest_token", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
req.Header.Add("Authorization", "Bearer "+accToken)
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func compileResources(accToken string) []resource {
|
||||
var res []resource
|
||||
|
||||
dashes, err := GetEmbeddableDashboards(accToken)
|
||||
dashIDs := make([]string, 0)
|
||||
if err == nil {
|
||||
for _, d := range dashes {
|
||||
dashIDs = append(dashIDs, d.EmbeddingId)
|
||||
}
|
||||
}
|
||||
|
||||
for _, id := range dashIDs {
|
||||
if id == "" {
|
||||
continue
|
||||
}
|
||||
res = append(res, resource{
|
||||
ID: id,
|
||||
Type: "dashboard",
|
||||
})
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
Reference in New Issue
Block a user