func()

in lib/translator/dbgap.go [211:360]


func (s *DbGapTranslator) translateToken(ctx context.Context, token *oidc.IDToken, claims dbGapClaims, now time.Time) (*ga4gh.Identity, error) {
	id := ga4gh.Identity{
		Issuer:     token.Issuer,
		Subject:    token.Subject,
		Expiry:     token.Expiry.Unix(),
		GivenName:  claims.Vcard.GivenName,
		FamilyName: claims.Vcard.FamilyName,
		Name:       strutil.JoinNonEmpty([]string{claims.Vcard.GivenName, claims.Vcard.FamilyName}, " "),
		Email:      claims.Vcard.Email,
		VisaJWTs:   []string{},
	}
	for _, ident := range claims.Identity {
		if ident.Authority == eraCommonsAuthority {
			if username, ok := ident.ID.(string); ok {
				id.Username = username
			}
		}
	}
	accessions := make(map[string]dbGapAccess)
	type source struct {
		orgID string
		by    string
	}
	affiliations := make(map[string]source)
	for _, p := range claims.DbGapPassport {
		for _, a := range p.Access {
			if a.Study.Accession == nil {
				continue
			}
			// TODO: Verify that the heuristics for de-duplicating access entries is correct.
			ac := *a.Study.Accession
			exp := a.Expires
			if access, ok := accessions[ac]; ok {
				// For duplicate accessions, only keep the one with the later expiry timestamp.
				if access.Expires > exp {
					continue
				}
			}
			accessions[ac] = dbGapAccess{
				Expires: exp,
				Issued:  a.Issued,
			}
		}
		if p.Org == nil || len(*p.Org) == 0 || p.Role == nil || len(*p.Role) == 0 {
			continue
		}
		var r string
		if *p.Role == "pi" || *p.Role == "downloader" {
			r = "nih.researcher"
		} else {
			r = "member"
		}
		o := removePunctuation.ReplaceAllString(*p.Org, "")
		o = strings.ReplaceAll(o, " ", "-")
		v := r + "@" + o + ".orgs.nih.gov"
		// Does not deal with complex cases where multiple org_DUNS attest to the same
		// "value" (v) for AffiliationAndRole.
		if src, ok := affiliations[v]; !ok || src.by == "self" {
			by := "so"
			if p.SO == nil || *p.SO == "" {
				by = "self"
			}
			affiliations[v] = source{
				orgID: *p.OrgID,
				by:    by,
			}
		}
	}

	currUnixTime := now.Unix()
	affiliationAsserted := now.Unix()
	for a, val := range accessions {
		visa := ga4gh.VisaData{
			StdClaims: ga4gh.StdClaims{
				Subject:   token.Subject,
				Issuer:    s.visaIssuer,
				ExpiresAt: val.Expires,
				IssuedAt:  val.Issued,
			},
			Assertion: ga4gh.Assertion{
				Type:     ga4gh.ControlledAccessGrants,
				Value:    ga4gh.Value("https://dac.nih.gov/datasets/" + a),
				Source:   dbGapIssuer,
				By:       ga4gh.DAC,
				Asserted: affiliationAsserted,
			},
			Scope: visaScope,
		}
		v, err := ga4gh.NewVisaFromData(ctx, &visa, s.visaJKU, s.signer)
		if err != nil {
			return nil, fmt.Errorf("sign ControlledAccessGrants claim failed: %s", err)
		}

		id.VisaJWTs = append(id.VisaJWTs, string(v.JWT()))

		// Keep the oldest Issued accession for use as affiliationAsserted.
		if val.Issued > 0 && val.Issued < affiliationAsserted {
			affiliationAsserted = val.Issued
		}
	}

	for a, src := range affiliations {
		// Claim for dbGap
		visa := ga4gh.VisaData{
			StdClaims: ga4gh.StdClaims{
				Issuer:    s.visaIssuer,
				ExpiresAt: currUnixTime + validSec,
				IssuedAt:  affiliationAsserted,
			},
			Assertion: ga4gh.Assertion{
				Type:     ga4gh.AffiliationAndRole,
				Value:    ga4gh.Value(a),
				Source:   dbGapIssuer,
				By:       ga4gh.System,
				Asserted: affiliationAsserted,
			},
			Scope: visaScope,
		}
		v, err := ga4gh.NewVisaFromData(ctx, &visa, s.visaJKU, s.signer)
		if err != nil {
			return nil, fmt.Errorf("sign dbGap ClaimAffiliationAndRole claim failed: %s", err)
		}

		id.VisaJWTs = append(id.VisaJWTs, string(v.JWT()))

		// Claim for org
		visa = ga4gh.VisaData{
			StdClaims: ga4gh.StdClaims{
				Issuer:    s.visaIssuer,
				ExpiresAt: currUnixTime + validSec,
				IssuedAt:  affiliationAsserted,
			},
			Assertion: ga4gh.Assertion{
				Type:     ga4gh.AffiliationAndRole,
				Value:    ga4gh.Value(a),
				Source:   ga4gh.Source(dbGapOrgURL + src.orgID),
				By:       ga4gh.By(src.by),
				Asserted: affiliationAsserted,
			},
			Scope: visaScope,
		}
		v, err = ga4gh.NewVisaFromData(ctx, &visa, s.visaJKU, s.signer)
		if err != nil {
			return nil, fmt.Errorf("sign org ClaimAffiliationAndRole claim failed: %s", err)
		}

		id.VisaJWTs = append(id.VisaJWTs, string(v.JWT()))
	}
	return &id, nil
}