2019-05-22 15:22:40 +00:00
|
|
|
package repositories
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/tls"
|
|
|
|
"crypto/x509"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
|
2019-05-28 01:16:50 +00:00
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/credentials"
|
|
|
|
|
2019-07-12 01:02:46 +00:00
|
|
|
protobuf "github.com/mitchell/selfpass/protobuf/go"
|
2019-07-11 02:33:22 +00:00
|
|
|
"github.com/mitchell/selfpass/services/credentials/endpoints"
|
|
|
|
"github.com/mitchell/selfpass/services/credentials/transport"
|
|
|
|
"github.com/mitchell/selfpass/services/credentials/types"
|
2019-05-22 15:22:40 +00:00
|
|
|
)
|
|
|
|
|
2019-07-12 01:02:46 +00:00
|
|
|
func NewCredentialsClient(ctx context.Context, target, ca, cert, key string) (types.CredentialsClient, error) {
|
2019-05-22 15:22:40 +00:00
|
|
|
keypair, err := tls.X509KeyPair([]byte(cert), []byte(key))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
capool := x509.NewCertPool()
|
|
|
|
capool.AppendCertsFromPEM([]byte(ca))
|
|
|
|
|
|
|
|
creds := credentials.NewTLS(&tls.Config{
|
|
|
|
RootCAs: capool,
|
|
|
|
Certificates: []tls.Certificate{keypair},
|
2019-06-07 09:03:15 +00:00
|
|
|
MinVersion: tls.VersionTLS12,
|
|
|
|
CurvePreferences: []tls.CurveID{
|
|
|
|
tls.CurveP256,
|
|
|
|
},
|
2019-05-22 15:22:40 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
conn, err := grpc.DialContext(ctx, target, grpc.WithTransportCredentials(creds), grpc.WithBlock())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-07-12 01:02:46 +00:00
|
|
|
return credentialsClient{
|
|
|
|
client: protobuf.NewCredentialsClient(conn),
|
2019-05-22 15:22:40 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-07-12 01:02:46 +00:00
|
|
|
type credentialsClient struct {
|
|
|
|
client protobuf.CredentialsClient
|
2019-05-22 15:22:40 +00:00
|
|
|
}
|
|
|
|
|
2019-07-12 01:02:46 +00:00
|
|
|
func (c credentialsClient) GetAllMetadata(ctx context.Context, sourceHost string) (output <-chan types.Metadata, errch chan error) {
|
2019-05-22 15:22:40 +00:00
|
|
|
pbmdch := make(chan protobuf.Metadata, 1)
|
|
|
|
errch = make(chan error, 1)
|
|
|
|
|
|
|
|
stream, err := transport.DecodeMetdataStreamResponse(ctx, transport.ProtobufMetadataStream{
|
|
|
|
Metadata: pbmdch,
|
|
|
|
Errors: errch,
|
|
|
|
})
|
|
|
|
|
2019-07-16 06:14:54 +00:00
|
|
|
srv, err := c.client.GetAllMetadata(
|
|
|
|
ctx,
|
|
|
|
transport.EncodeSourceHostRequest(endpoints.SourceHostRequest{SourceHost: sourceHost}),
|
|
|
|
)
|
2019-05-22 15:22:40 +00:00
|
|
|
if err != nil {
|
|
|
|
errch <- err
|
|
|
|
return nil, errch
|
|
|
|
}
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
defer close(pbmdch)
|
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
errch <- fmt.Errorf("context timeout")
|
|
|
|
return
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
pbmd, err := srv.Recv()
|
|
|
|
if err == io.EOF {
|
|
|
|
return
|
|
|
|
} else if err != nil {
|
|
|
|
errch <- err
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
pbmdch <- *pbmd
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
return stream.Metadata, stream.Errors
|
|
|
|
}
|
|
|
|
|
2019-07-12 01:02:46 +00:00
|
|
|
func (c credentialsClient) Get(ctx context.Context, id string) (output types.Credential, err error) {
|
2019-05-22 15:22:40 +00:00
|
|
|
req := transport.EncodeIdRequest(endpoints.IDRequest{ID: id})
|
|
|
|
|
|
|
|
res, err := c.client.Get(ctx, &req)
|
|
|
|
if err != nil {
|
|
|
|
return output, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return transport.DecodeCredential(*res)
|
|
|
|
}
|
|
|
|
|
2019-07-12 01:02:46 +00:00
|
|
|
func (c credentialsClient) Create(ctx context.Context, ci types.CredentialInput) (output types.Credential, err error) {
|
2019-05-22 15:22:40 +00:00
|
|
|
req := transport.EncodeCredentialRequest(ci)
|
|
|
|
|
|
|
|
res, err := c.client.Create(ctx, &req)
|
|
|
|
if err != nil {
|
|
|
|
return output, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return transport.DecodeCredential(*res)
|
|
|
|
}
|
|
|
|
|
2019-07-12 01:02:46 +00:00
|
|
|
func (c credentialsClient) Update(ctx context.Context, id string, ci types.CredentialInput) (output types.Credential, err error) {
|
2019-05-28 01:16:50 +00:00
|
|
|
req := transport.EncodeUpdateRequest(endpoints.UpdateRequest{ID: id, Credential: ci})
|
|
|
|
|
|
|
|
res, err := c.client.Update(ctx, &req)
|
|
|
|
if err != nil {
|
|
|
|
return output, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return transport.DecodeCredential(*res)
|
2019-05-22 15:22:40 +00:00
|
|
|
}
|
|
|
|
|
2019-07-12 01:02:46 +00:00
|
|
|
func (c credentialsClient) Delete(ctx context.Context, id string) (err error) {
|
2019-05-28 01:16:50 +00:00
|
|
|
req := transport.EncodeIdRequest(endpoints.IDRequest{ID: id})
|
|
|
|
|
|
|
|
res, err := c.client.Delete(ctx, &req)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if !res.Success {
|
|
|
|
return fmt.Errorf("delete unsuccessful")
|
|
|
|
}
|
|
|
|
return nil
|
2019-05-22 15:22:40 +00:00
|
|
|
}
|