func (p *Policy) GetQueryDesriptors(
	claims map[string]interface{},
	qc QueryConstraint,
) ([]QueryDescriptor, error) {
	var qds []QueryDescriptor
	for queryName, argSpec := range p.QueryMap {
		qd := new(QueryDescriptor)
		qd.Constraint = qc
		if err := PopulateQueryDescriptor(claims, queryName, argSpec, qd); err != nil {
			return nil, err
		}
		qds = append(qds, *qd)
	}
	return qds, nil
}
GetQueryDesriptors returns GetQueryDesriptor's for running queries against
endorsement store in order to  obtain endorsements needed to validate a
token. The query descriptors are populated from the Policy's QueryMap using
the specified claims structure in order to resolve the parameter JSONpath's.
package common
import (
	"archive/zip"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"github.com/hashicorp/go-plugin"
)
type Policy struct {
	TokenFormat TokenFormat
	QueryMap QueryMap
	Rules []byte
}
func NewPolicy() *Policy {
	policy := new(Policy)
	policy.QueryMap = make(QueryMap)
	return policy
}
func (p *Policy) Write(w io.Writer) error {
	zw := zip.NewWriter(w)
	formatName := p.TokenFormat.String()
	rulesName := filepath.Join(formatName, "rules")
	rulesWriter, err := zw.Create(rulesName)
	if err != nil {
		return err
	}
	if _, err = rulesWriter.Write(p.Rules); err != nil {
		return err
	}
	qmapName := filepath.Join(formatName, "query-map")
	qmapWriter, err := zw.Create(qmapName)
	if err != nil {
		return err
	}
	qmapBytes, err := json.Marshal(p.QueryMap)
	if err != nil {
		return err
	}
	if _, err = qmapWriter.Write(qmapBytes); err != nil {
		return err
	}
	return zw.Close()
}
func (p *Policy) WriteToPath(path string) error {
	f, err := os.Create(path)
	if err != nil {
		return err
	}
	return p.Write(f)
}
func ReadPolicies(r io.ReaderAt, size int64) ([]*Policy, error) {
	reader, err := zip.NewReader(r, size)
	if err != nil {
		return nil, err
	}
	return doReadPolicies(reader)
}
func ReadPoliciesFromBytes(buffer []byte) ([]*Policy, error) {
	reader := bytes.NewReader(buffer)
	return ReadPolicies(reader, int64(len(buffer)))
}
func ReadPoliciesFromPath(path string) ([]*Policy, error) {
	rc, err := zip.OpenReader(path)
	if err != nil {
		return nil, err
	}
	defer rc.Close()
	return doReadPolicies(&rc.Reader)
}
func WritePoliciesToPath(policies []*Policy, path string) error {
	file, err := os.Create(path)
	if err != nil {
		return fmt.Errorf("could not open/create %q: %v", path, err)
	}
	defer file.Close()
	writer := zip.NewWriter(file)
	if err = doWritePolicies(writer, policies); err != nil {
		return fmt.Errorf("could not write policies: %v", err)
	}
	if err = writer.Close(); err != nil {
		return fmt.Errorf("could not finalize zip archive: %v", err)
	}
	return nil
}
func doWritePolicies(writer *zip.Writer, policies []*Policy) error {
	seenFormats := make(map[TokenFormat]bool)
	for _, policy := range policies {
		if _, ok := seenFormats[policy.TokenFormat]; ok {
			return fmt.Errorf("found multiple polcies with format %q", policy.TokenFormat.String())
		}
		queryMapData, err := json.Marshal(policy.QueryMap)
		if err != nil {
			return fmt.Errorf(
				"could not serialize query map for %q: %v",
				policy.TokenFormat.String(),
				err,
			)
		}
		queryMapPath := filepath.Join(policy.TokenFormat.String(), "query_map.json")
		file, err := writer.Create(queryMapPath)
		if err != nil {
			return fmt.Errorf("could not create %q: %v", queryMapPath, err)
		}
		if _, err = file.Write(queryMapData); err != nil {
			return fmt.Errorf("could not write %q: %v", queryMapPath, err)
		}
		rulesPath := filepath.Join(policy.TokenFormat.String(), "rules")
		file, err = writer.Create(rulesPath)
		if err != nil {
			return fmt.Errorf("could not create %q: %v", rulesPath, err)
		}
		if _, err := file.Write(policy.Rules); err != nil {
			return fmt.Errorf("could not write %q: %v", rulesPath, err)
		}
		seenFormats[policy.TokenFormat] = true
	}
	return nil
}