auth

package
v1.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 20, 2021 License: AGPL-3.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var GetPermissions = func(visas Visas) []string {
	log.Debug("parsing permissions from visas")
	var datasets []string

	log.Debugf("number of visas to check: %d", len(visas.Visa))

	for _, v := range visas.Visa {

		log.Debug("checking visa type")

		unknownToken, err := jwt.Parse([]byte(v))
		if err != nil {
			log.Errorf("failed to parse visa, %s", err)
			continue
		}
		unknownTokenVisaClaim := unknownToken.PrivateClaims()["ga4gh_visa_v1"]
		unknownTokenVisa := Visa{}
		unknownTokenVisaClaimJSON, err := json.Marshal(unknownTokenVisaClaim)
		if err != nil {
			log.Errorf("failed to parse unknown visa claim to JSON, %s, %s", err, unknownTokenVisaClaim)
			continue
		}
		err = json.Unmarshal(unknownTokenVisaClaimJSON, &unknownTokenVisa)
		if err != nil {
			log.Errorf("failed to parse unknown visa claim JSON into struct, %s, %s", err, unknownTokenVisaClaimJSON)
			continue
		}
		if unknownTokenVisa.Type != "ControlledAccessGrants" {
			log.Debug("visa is not a ControlledAccessGrants, skip")
			continue
		}
		log.Debug("visa type check passed")

		log.Debug("start visa validation")

		header, err := jws.Parse([]byte(v))
		if err != nil {
			log.Errorf("failed to parse visa header, %s", err)
			continue
		}

		o := OIDCDetails{
			JWK: header.Signatures()[0].ProtectedHeaders().JWKSetURL(),
		}

		verifiedVisa, err := VerifyJWT(o, v)
		if err != nil {
			log.Errorf("failed to validate visa, %s", err)
			continue
		}

		if err := jwt.Validate(verifiedVisa); err != nil {
			log.Error("failed to validate visa")
			continue
		}
		log.Debug("visa validated")

		visaClaim := verifiedVisa.PrivateClaims()["ga4gh_visa_v1"]
		visa := Visa{}
		visaClaimJSON, err := json.Marshal(visaClaim)
		if err != nil {
			log.Errorf("failed to parse visa claim to JSON, %s, %s", err, visaClaim)
			continue
		}
		err = json.Unmarshal(visaClaimJSON, &visa)
		if err != nil {
			log.Errorf("failed to parse visa claim JSON into struct, %s, %s", err, visaClaimJSON)
			continue
		}
		exists, err := database.CheckDataset(visa.Dataset)
		if err != nil {
			log.Debugf("visa contained dataset %s which doesn't exist in this instance, skip", visa.Dataset)
			continue
		}
		if exists {
			log.Debugf("checking dataset list for duplicates of %s", visa.Dataset)

			duplicate := false
			for i := range datasets {
				if datasets[i] == visa.Dataset {
					duplicate = true
					log.Debugf("found a duplicate: dataset %s is already found, skip", visa.Dataset)
					continue
				}
			}
			if !duplicate {
				log.Debugf("no duplicates of dataset: %s, add dataset to list of permissions", visa.Dataset)
				datasets = append(datasets, visa.Dataset)
			}
		}
	}

	log.Debugf("matched datasets, %s", datasets)
	return datasets
}

GetPermissions parses visas and finds matching dataset names from the database, returning a list of matches

View Source
var GetToken = func(header string) (string, int, error) {
	log.Debug("parsing access token from header")
	if len(header) == 0 {
		log.Debug("authorization check failed")
		return "", 401, errors.New("access token must be provided")
	}

	headerParts := strings.Split(header, " ")
	if headerParts[0] != "Bearer" {
		log.Debug("authorization check failed")
		return "", 400, errors.New("authorization scheme must be bearer")
	}

	// Check that header contains a token string
	var token string
	if len(headerParts) == 2 {
		token = headerParts[1]
	} else {
		log.Debug("authorization check failed")
		return "", 400, errors.New("token string is missing from authorization header")
	}
	log.Debug("access token found")
	return token, 0, nil
}

GetToken parses the token string from header

View Source
var GetVisas = func(o OIDCDetails, token string) (*Visas, error) {
	log.Debugf("requesting visas from %s", o.Userinfo)

	headers := map[string]string{}
	headers["Authorization"] = "Bearer " + token

	response, err := request.MakeRequest("GET", o.Userinfo, headers, nil)
	if err != nil {
		log.Errorf("request failed, %s", err)
		return nil, err
	}
	// Parse response
	var v Visas
	err = json.NewDecoder(response.Body).Decode(&v)
	if err != nil {
		log.Errorf("failed to parse JSON response, %s", err)
		return nil, err
	}
	log.Debug("visas received")
	return &v, nil
}

GetVisas requests the list of visas from userinfo endpoint

Functions

func VerifyJWT

func VerifyJWT(o OIDCDetails, token string) (jwt.Token, error)

VerifyJWT verifies the token signature

Types

type JKU

type JKU struct {
	URL string `json:"jku"`
}

type OIDCDetails

type OIDCDetails struct {
	Userinfo string `json:"userinfo_endpoint"`
	JWK      string `json:"jwks_uri"`
}

OIDCDetails is used to draw the response bytes to a struct

var Details OIDCDetails

Details stores an OIDCDetails struct

func GetOIDCDetails

func GetOIDCDetails(url string) (OIDCDetails, error)

GetOIDCDetails requests OIDC configuration information

type Visa

type Visa struct {
	Type    string `json:"type"`
	Dataset string `json:"value"`
}

Visa is used to draw the dataset name out of the visa

type Visas

type Visas struct {
	Visa []string `json:"ga4gh_passport_v1"`
}

Visas is used to draw the response bytes to a struct

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL