func (ru RemoteUsernames) String() string {
	return strings.Join(ru, ",")
}
String returns the string representation of RemoteUsernames
package bless
import (
	"context"
	"crypto"
	"crypto/x509"
	"encoding/base64"
	"encoding/json"
	"strings"
	"github.com/chanzuckerberg/blessclient/pkg/config"
	cziAWS "github.com/chanzuckerberg/go-misc/aws"
	"github.com/davecgh/go-spew/spew"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"golang.org/x/crypto/ssh"
)
type Response struct {
	Certificate  *Certificate `json:"certificate,omitempty"`
	ErrorType    *string      `json:"errorType,omitempty"`
	ErrorMessage *string      `json:"errorMessage,omitempty"`
}
type Certificate struct {
	cert *ssh.Certificate
}
func (c *Certificate) MarshalJSON() ([]byte, error) {
	data := base64.StdEncoding.EncodeToString(c.cert.Marshal())
	return json.Marshal(map[string]string{"cert": data})
}
func (c *Certificate) UnmarshalJSON(data []byte) error {
	intermediate := map[string]string{}
	err := json.Unmarshal(data, &intermediate)
	if err != nil {
		return errors.Wrap(err, "could not json unmarshal public key")
	}
	certB64, ok := intermediate["cert"]
	if !ok {
		return errors.New("unknown serialization format")
	}
	b, err := base64.StdEncoding.DecodeString(certB64)
	if err != nil {
		return errors.Wrap(err, "could not b64 decode certificate")
	}
	sshPub, err := ssh.ParsePublicKey(b)
	if err != nil {
		return errors.Wrap(err, "could not ssh parse certificate")
	}
	cert, ok := sshPub.(*ssh.Certificate)
	if !ok {
		return errors.New("cert incorrect type")
	}
	c.cert = cert
	return nil
}
type OIDC struct {
	awsClient *cziAWS.Client
	lambdaConfig *config.LambdaConfig
}
func NewOIDC(
	awsClient *cziAWS.Client,
	lambdaConfig *config.LambdaConfig,
) *OIDC {
	return &OIDC{
		awsClient:    awsClient,
		lambdaConfig: lambdaConfig,
	}
}
func (o *OIDC) RequestCert(
	ctx context.Context,
	awsClient *cziAWS.Client,
	signingRequest *SigningRequest,
) (*ssh.Certificate, error) {
	payload, err := json.Marshal(signingRequest)
	if err != nil {
		return nil, errors.Wrap(err, "could not json marshal payload")
	}
	return o.getCert(ctx, payload)
}
func (o *OIDC) getCert(ctx context.Context, payload []byte) (*ssh.Certificate, error) {
	responseBytes, err := o.awsClient.Lambda.ExecuteWithQualifier(
		ctx,
		o.lambdaConfig.FunctionName,
		o.lambdaConfig.FunctionVersion,
		payload,
	)
	if err != nil {
		return nil, err
	}
	logrus.Debugf("Raw lambda response %s", string(responseBytes))
	response := &Response{}
	err = json.Unmarshal(responseBytes, response)
	if err != nil {
		return nil, errors.Wrap(err, "Could not deserialize lambda reponse")
	}
	logrus.Debugf("Parsed lambda response %s", spew.Sdump(response))
	if response.ErrorType != nil {
		if response.ErrorMessage != nil {
			return nil, errors.Errorf("bless error: %s: %s", *response.ErrorType, *response.ErrorMessage)
		}
		return nil, errors.Errorf("bless error: %s", *response.ErrorType)
	}
	if response.Certificate == nil || response.Certificate.cert == nil {
		return nil, errors.New("No certificate in response")
	}
	return response.Certificate.cert, nil
}
type SigningRequest struct {
	RemoteUsernames RemoteUsernames  `json:"remote_usernames,omitempty"`
	PublicKeyToSign *PublicKeyToSign `json:"public_key_to_sign,omitempty"`
	Identity Identity `json:"identity,omitempty"`
}
type Identity struct {
	OktaAccessToken *OktaAccessTokenInput `json:"okta_identity,omitempty"`
}
type OktaAccessTokenInput struct {
	AccessToken string
}
type RemoteUsernames []string