1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
// Copyright (c) 2023, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE.md file distributed with the sources of this project regarding your
// rights to use or distribute this software.
package library
import (
"encoding/json"
"fmt"
"net/http"
"time"
scslibrary "github.com/sylabs/scs-library-client/client"
"github.com/sylabs/singularity/v4/pkg/sylog"
)
const (
userServicePath = "/v1/rbac/users/current"
)
type userOidcMeta struct {
Secret string `json:"secret"`
}
type userData struct {
OidcMeta userOidcMeta `json:"oidc_user_meta"`
Email string `json:"email"`
Realname string `json:"realname"`
Username string `json:"username"`
}
// getUserData retrives auth service user information from the current remote.
func getUserData(config *scslibrary.Config) (*userData, error) {
client := http.Client{Timeout: 5 * time.Second}
path := userServicePath
endPoint := config.BaseURL + path
req, err := http.NewRequest(http.MethodGet, endPoint, nil)
if err != nil {
return nil, fmt.Errorf("error creating new request: %v", err)
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", config.AuthToken))
res, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
sylog.Debugf("Status Code: %v", res.StatusCode)
if res.StatusCode == http.StatusUnauthorized {
return nil, fmt.Errorf("must be logged in to retrieve user data")
}
if res.StatusCode == http.StatusNotFound {
return nil, fmt.Errorf("user endpoint not found")
}
return nil, fmt.Errorf("status is not ok: %v", res.StatusCode)
}
var ud userData
err = json.NewDecoder(res.Body).Decode(&ud)
if err != nil {
return nil, fmt.Errorf("error decoding json response: %v", err)
}
return &ud, nil
}
// GetIdentity returns the username and email for the logged in user.
func GetIdentity(config *scslibrary.Config) (user, email string, err error) {
ud, err := getUserData(config)
if err != nil {
return "", "", err
}
return ud.Username, ud.Email, nil
}
// GetOCIToken retrieves the OCI registry token for the logged in user.
func GetOCIToken(config *scslibrary.Config) (string, error) {
ud, err := getUserData(config)
if err != nil {
return "", err
}
if ud.OidcMeta.Secret == "" {
return "", fmt.Errorf("no token was received from service")
}
return ud.OidcMeta.Secret, nil
}
|