func populatePersonaVisas()

in lib/persona/persona.go [265:397]


func populatePersonaVisas(ctx context.Context, pname, visaIssuer string, assertions []*cpb.Assertion, id *ga4gh.Identity) (*ga4gh.Identity, error) {
	issuer := id.Issuer
	jku := jkuURL(issuer)
	id.GA4GH = make(map[string][]ga4gh.OldClaim)
	id.VisaJWTs = make([]string, len(assertions))
	now := float64(time.Now().Unix())
	signer := signer(&personaKey)

	for i, assert := range assertions {
		typ := ga4gh.Type(assert.Type)
		if len(typ) == 0 {
			return nil, fmt.Errorf("persona %q visa %d missing assertion type", pname, i+1)
		}
		_, ok := id.GA4GH[assert.Type]
		if !ok {
			id.GA4GH[assert.Type] = make([]ga4gh.OldClaim, 0)
		}
		if len(assert.Value) == 0 {
			return nil, fmt.Errorf("persona %q visa %d missing assertion value", pname, i+1)
		}
		src := ga4gh.Source(issuer)
		if len(assert.Source) > 0 {
			src = ga4gh.Source(assert.Source)
		}
		// assert.AssertedDuration cannot be negative and is assumed to be a duration in the past.
		a, err := timeutil.ParseDuration(assert.AssertedDuration)
		if err != nil {
			return nil, fmt.Errorf("persona %q visa %d asserted duration %q: %v", pname, i+1, assert.AssertedDuration, err)
		}
		asserted := int64(now - a.Seconds())
		// assert.ExpiresDuration may be negative or positive where a negative value represents the past.
		e, err := timeutil.ParseDuration(assert.ExpiresDuration)
		if err != nil {
			return nil, fmt.Errorf("persona %q visa %d expires duration %q: %v", pname, i+1, assert.ExpiresDuration, err)
		}
		if e > 0 && e < minPersonaFutureExpiry {
			e = minPersonaFutureExpiry
		}
		expires := int64(now + e.Seconds())
		visa := ga4gh.VisaData{
			StdClaims: ga4gh.StdClaims{
				Subject:   id.Subject,
				Issuer:    visaIssuer,
				ExpiresAt: expires,
				IssuedAt:  int64(now),
			},
			Assertion: ga4gh.Assertion{
				Type:     typ,
				Value:    ga4gh.Value(assert.Value),
				Source:   src,
				Asserted: asserted,
				By:       ga4gh.By(assert.By),
			},
		}
		if len(assert.AnyOfConditions) > 0 {
			visa.Assertion.Conditions = make(ga4gh.Conditions, 0)
			for _, cond := range assert.AnyOfConditions {
				clauses := []ga4gh.Condition{}
				for _, clause := range cond.AllOf {
					c := ga4gh.Condition{
						Type:   ga4gh.Type(clause.Type),
						Value:  ga4gh.Pattern(clause.Value),
						Source: ga4gh.Pattern(clause.Source),
						By:     ga4gh.Pattern(clause.By),
					}
					clauses = append(clauses, c)
				}
				visa.Assertion.Conditions = append(visa.Assertion.Conditions, clauses)
			}
		}

		v, err := ga4gh.NewVisaFromData(ctx, &visa, jku, signer)
		if err != nil {
			return nil, fmt.Errorf("signing persona %q visa %d failed: %s", pname, i+1, err)
		}
		id.VisaJWTs[i] = string(v.JWT())

		// Populate old claims.
		c := ga4gh.OldClaim{
			Value:    assert.Value,
			Source:   string(src),
			Asserted: float64(asserted),
			Expires:  float64(expires),
			By:       assert.By,
		}
		if len(assert.AnyOfConditions) > 0 {
			c.Condition = make(map[string]ga4gh.OldClaimCondition)
			cType := ""
			cValue := []string{}
			cSource := []string{}
			cBy := []string{}
			for _, cond := range assert.AnyOfConditions {
				for _, clause := range cond.AllOf {
					cType = clause.Type
					clValue := clause.Value
					if clValues := strings.SplitN(clause.Value, ":", 2); len(clValues) > 1 {
						clValue = clValues[1]
					}
					clSource := clause.Source
					if clSources := strings.SplitN(clause.Source, ":", 2); len(clSources) > 1 {
						clSource = clSources[1]
					}
					clBy := clause.By
					if clBys := strings.SplitN(clause.By, ":", 2); len(clBys) > 1 {
						clBy = clBys[1]
					}
					if len(clValue) > 0 {
						cValue = append(cValue, clValue)
					}
					if len(clSource) > 0 {
						cSource = append(cSource, clSource)
					}
					if len(clBy) > 0 {
						cBy = append(cBy, clBy)
					}
				}
			}
			oldC := ga4gh.OldClaimCondition{}
			if len(cValue) > 0 {
				oldC.Value = cValue
			}
			if len(cSource) > 0 {
				oldC.Source = cSource
			}
			if len(cBy) > 0 {
				oldC.By = cBy
			}
			c.Condition[cType] = oldC
		}
		id.GA4GH[assert.Type] = append(id.GA4GH[assert.Type], c)
	}
	return id, nil
}