func (e *Engine) RetrieveCredentials(ctx context.Context,
	notifier *observer.Notifier, cpath, cpathexp *string) ([]PlaintextCredentialEnvelope, error) {
	if cpath != nil && cpathexp != nil {
		panic("cannot use both cpath and cpathexp")
	}
	if cpath == nil && cpathexp == nil {
		panic("cpath or cpathexp required")
	}

	var err error
	var graphs []registry.CredentialGraph
	if cpath != nil {
		graphs, err = e.client.CredentialGraph.List(ctx, *cpath, nil, e.session.AuthID())
	} else if cpathexp != nil {
		graphs, err = e.client.CredentialGraph.Search(ctx, *cpathexp, e.session.AuthID())
	}
	if err != nil {
		log.Printf("error retrieving credential graphs: %s", err)
		return nil, err
	}

	cgs := newCredentialGraphSet()
	err = cgs.Add(graphs...)
	if err != nil {
		return nil, err
	}

	activeGraphs, err := cgs.Active()
	if err != nil {
		return nil, err
	}

	var steps uint = 1
	for _, graph := range activeGraphs {
		steps += uint(len(graph.GetCredentials()))
	}

	n := notifier.Notifier(steps)
	n.Notify(observer.Progress, "Credentials retrieved", true)

	keypairs := make(map[identity.ID]*crypto.KeyPairs)
	encryptingKeys := make(map[identity.ID]*primitive.PublicKey)

	// Loop over the trees and unpack the credentials; later on we will
	// actually do real work and decrypt each of these credentials but for
	// now we just need ot return a list of them!
	creds := []PlaintextCredentialEnvelope{}
	for _, graph := range activeGraphs {
		var orgID *identity.ID
		switch b := graph.GetKeyring().Body.(type) {
		case *primitive.Keyring:
			orgID = b.OrgID
		case *primitive.KeyringV1:
			orgID = b.OrgID
		default:
			return nil, &apitypes.Error{
				Type: apitypes.InternalServerError,
				Err:  []string{"Malformed keyring body"},
			}
		}
		kp, ok := keypairs[*orgID]
		if !ok {
			_, _, kp, err = fetchKeyPairs(ctx, e.client, orgID)
			if err != nil {
				log.Printf("Error fetching keypairs: %s", err)
				return nil, err
			}
			keypairs[*orgID] = kp
		}

		krm, mekshare, err := graph.FindMember(e.session.AuthID())
		if err != nil {
			log.Printf("Error finding keyring membership: %s", err)
			return nil, err
		}

		encryptingKey, ok := encryptingKeys[*krm.EncryptingKeyID]
		if !ok {
			encryptingKey, err = findEncryptingKey(ctx, e.client, orgID,
				krm.EncryptingKeyID)
			if err != nil {
				log.Printf("Error finding encrypting key for user: %s", err)
				return nil, err
			}
			encryptingKeys[*krm.EncryptingKeyID] = encryptingKey
		}

		err = e.crypto.WithUnboxer(ctx, *mekshare.Key.Value, *mekshare.Key.Nonce, &kp.Encryption, *encryptingKey.Key.Value, func(u crypto.Unboxer) error {
			for _, cred := range graph.GetCredentials() {
				var state *string

				base, err := baseCredential(&cred)
				if err != nil {
					return err
				}

				if c, ok := cred.Body.(*primitive.Credential); ok {
					state = c.State
				}

				pt, err := u.Unbox(ctx, *base.Credential.Value, *base.Nonce, *base.Credential.Nonce)
				if err != nil {
					log.Printf("Error decrypting credential: %s", err)
					return err
				}

				plainCred := PlaintextCredentialEnvelope{
					ID:      cred.ID,
					Version: cred.Version,
					Body: &PlaintextCredential{
						Name:      base.Name,
						PathExp:   base.PathExp,
						ProjectID: base.ProjectID,
						OrgID:     base.OrgID,
						Value:     string(pt),
						State:     state,
					},
				}
				creds = append(creds, plainCred)

				n.Notify(observer.Progress, "Credential decrypted", true)
			}
			return nil
		})
		if err != nil {
			return nil, err
		}
	}

	return creds, nil
}
// RetrieveCredentials returns all credentials for the given CPath string
RetrieveCredentials returns all credentials for the given CPath string
// RetrieveCredentials returns all credentials for the given CPath string
func (e *Engine) RetrieveCredentials(ctx context.Context,
	notifier *observer.Notifier, cpath, cpathexp *string) ([]PlaintextCredentialEnvelope, error) {
	if cpath != nil && cpathexp != nil {
		panic("cannot use both cpath and cpathexp")
	}
	if cpath == nil && cpathexp == nil {
		panic("cpath or cpathexp required")
	}
	var err error
	var graphs []registry.CredentialGraph
	if cpath != nil {
		graphs, err = e.client.CredentialGraph.List(ctx, *cpath, nil, e.session.AuthID())
	} else if cpathexp != nil {
		graphs, err = e.client.CredentialGraph.Search(ctx, *cpathexp, e.session.AuthID())
	}
	if err != nil {
		log.Printf("error retrieving credential graphs: %s", err)
		return nil, err
	}
	cgs := newCredentialGraphSet()
	err = cgs.Add(graphs...)
	if err != nil {
		return nil, err
	}
	activeGraphs, err := cgs.Active()
	if err != nil {
		return nil, err
	}
	var steps uint = 1
	for _, graph := range activeGraphs {
		steps += uint(len(graph.GetCredentials()))
	}
	n := notifier.Notifier(steps)
	n.Notify(observer.Progress, "Credentials retrieved", true)
	keypairs := make(map[identity.ID]*crypto.KeyPairs)
	encryptingKeys := make(map[identity.ID]*primitive.PublicKey)
	creds := []PlaintextCredentialEnvelope{}
	for _, graph := range activeGraphs {
		var orgID *identity.ID
		switch b := graph.GetKeyring().Body.(type) {
		case *primitive.Keyring:
			orgID = b.OrgID
		case *primitive.KeyringV1:
			orgID = b.OrgID
		default:
			return nil, &apitypes.Error{
				Type: apitypes.InternalServerError,
				Err:  []string{"Malformed keyring body"},
			}
		}
		kp, ok := keypairs[*orgID]
		if !ok {
			_, _, kp, err = fetchKeyPairs(ctx, e.client, orgID)
			if err != nil {
				log.Printf("Error fetching keypairs: %s", err)
				return nil, err
			}
			keypairs[*orgID] = kp
		}
		krm, mekshare, err := graph.FindMember(e.session.AuthID())
		if err != nil {
			log.Printf("Error finding keyring membership: %s", err)
			return nil, err
		}
		encryptingKey, ok := encryptingKeys[*krm.EncryptingKeyID]
		if !ok {
			encryptingKey, err = findEncryptingKey(ctx, e.client, orgID,
				krm.EncryptingKeyID)
			if err != nil {
				log.Printf("Error finding encrypting key for user: %s", err)
				return nil, err
			}
			encryptingKeys[*krm.EncryptingKeyID] = encryptingKey
		}
		err = e.crypto.WithUnboxer(ctx, *mekshare.Key.Value, *mekshare.Key.Nonce, &kp.Encryption, *encryptingKey.Key.Value, func(u crypto.Unboxer) error {
			for _, cred := range graph.GetCredentials() {
				var state *string
				base, err := baseCredential(&cred)
				if err != nil {
					return err
				}
				if c, ok := cred.Body.(*primitive.Credential); ok {
					state = c.State
				}
				pt, err := u.Unbox(ctx, *base.Credential.Value, *base.Nonce, *base.Credential.Nonce)
				if err != nil {
					log.Printf("Error decrypting credential: %s", err)
					return err
				}
				plainCred := PlaintextCredentialEnvelope{
					ID:      cred.ID,
					Version: cred.Version,
					Body: &PlaintextCredential{
						Name:      base.Name,
						PathExp:   base.PathExp,
						ProjectID: base.ProjectID,
						OrgID:     base.OrgID,
						Value:     string(pt),
						State:     state,
					},
				}
				creds = append(creds, plainCred)
				n.Notify(observer.Progress, "Credential decrypted", true)
			}
			return nil
		})
		if err != nil {
			return nil, err
		}
	}
	return creds, nil
}
func ( e * Engine ) RetrieveCredentials ( ctx context . Context , notifier * observer . Notifier , cpath , cpathexp * string ) ( [ ] PlaintextCredentialEnvelope , error ) { if cpath != nil && cpathexp != nil { panic ( " " ) } if cpath == nil && cpathexp == nil { panic ( " " ) } var err error var graphs [ ] registry . CredentialGraph if cpath != nil { graphs , err = e . client . CredentialGraph . List ( ctx , * cpath , nil , e . session . AuthID ( ) ) } else if cpathexp != nil { graphs , err = e . client . CredentialGraph . Search ( ctx , * cpathexp , e . session . AuthID ( ) ) } if err != nil { log . Printf ( " " , err ) return nil , err } cgs := newCredentialGraphSet ( ) err = cgs . Add ( graphs ... ) if err != nil { return nil , err } activeGraphs , err := cgs . Active ( ) if err != nil { return nil , err } var steps uint = 1 for _ , graph := range activeGraphs { steps += uint ( len ( graph . GetCredentials ( ) ) ) } n := notifier . Notifier ( steps ) n . Notify ( observer . Progress , " " , true ) keypairs := make ( map [ identity . ID ] * crypto . KeyPairs ) encryptingKeys := make ( map [ identity . ID ] * primitive . PublicKey ) creds := [ ] PlaintextCredentialEnvelope { } for _ , graph := range activeGraphs { var orgID * identity . ID switch b := graph . GetKeyring ( ) . Body . ( type ) { case * primitive . Keyring : orgID = b . OrgID case * primitive . KeyringV1 : orgID = b . OrgID default : return nil , & apitypes . Error { Type : apitypes . InternalServerError , Err : [ ] string { " " } , } } kp , ok := keypairs [ * orgID ] if ! ok { _ , _ , kp , err = fetchKeyPairs ( ctx , e . client , orgID ) if err != nil { log . Printf ( " " , err ) return nil , err } keypairs [ * orgID ] = kp } krm , mekshare , err := graph . FindMember ( e . session . AuthID ( ) ) if err != nil { log . Printf ( " " , err ) return nil , err } encryptingKey , ok := encryptingKeys [ * krm . EncryptingKeyID ] if ! ok { encryptingKey , err = findEncryptingKey ( ctx , e . client , orgID , krm . EncryptingKeyID ) if err != nil { log . Printf ( " " , err ) return nil , err } encryptingKeys [ * krm . EncryptingKeyID ] = encryptingKey } err = e . crypto . WithUnboxer ( ctx , * mekshare . Key . Value , * mekshare . Key . Nonce , & kp . Encryption , * encryptingKey . Key . Value , func ( u crypto . Unboxer ) error { for _ , cred := range graph . GetCredentials ( ) { var state * string base , err := baseCredential ( & cred ) if err != nil { return err } if c , ok := cred . Body . ( * primitive . Credential ) ; ok { state = c . State } pt , err := u . Unbox ( ctx , * base . Credential . Value , * base . Nonce , * base . Credential . Nonce ) if err != nil { log . Printf ( " " , err ) return err } plainCred := PlaintextCredentialEnvelope { ID : cred . ID , Version : cred . Version , Body : & PlaintextCredential { Name : base . Name , PathExp : base . PathExp , ProjectID : base . ProjectID , OrgID : base . OrgID , Value : string ( pt ) , State : state , } , } creds = append ( creds , plainCred ) n . Notify ( observer . Progress , " " , true ) } return nil } ) if err != nil { return nil , err } } return creds , nil }
RetrieveCredentials returns all credentials for the given CPath string
RetrieveCredentials returns all credentials for the given CPath string
// Loop over the trees and unpack the credentials; later on we will // actually do real work and decrypt each of these credentials but for // now we just need ot return a list of them!