First iteration of selfpass gRPC backend, w/ credentials CRUD functional

This commit is contained in:
mitchell 2019-04-14 20:56:55 -07:00
commit 719a462048
15 changed files with 1610 additions and 0 deletions

View file

@ -0,0 +1,67 @@
package endpoints
import (
"context"
"github.com/go-kit/kit/endpoint"
"github.com/mitchell/selfpass/credentials/types"
)
// MakeGetAllMetadataEndpoint TODO
func MakeGetAllMetadataEndpoint(svc types.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
r := request.(GetAllMetadataRequest)
mdch, errch := svc.GetAllMetadata(ctx, r.SourceHost)
return MetadataStream{
Metadata: mdch,
Errors: errch,
}, nil
}
}
// MakeCreateEndpoint TODO
func MakeCreateEndpoint(svc types.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
r := request.(types.CredentialInput)
return svc.Create(ctx, r)
}
}
// MakeUpdateEndpoint TODO
func MakeUpdateEndpoint(svc types.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
r := request.(UpdateRequest)
return svc.Update(ctx, r.ID, r.Credential)
}
}
func MakeDeleteEndpoint(svc types.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
r := request.(IDRequest)
return nil, svc.Delete(ctx, r.ID)
}
}
// IDRequest TODO
type IDRequest struct {
ID string
}
// GetAllMetadataRequest TODO
type GetAllMetadataRequest struct {
SourceHost string
}
// MetadataStream TODO
type MetadataStream struct {
Metadata <-chan types.Metadata
Errors chan error
}
// UpdateRequest TODO
type UpdateRequest struct {
ID string
Credential types.CredentialInput
}

View file

@ -0,0 +1,751 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: credentials/protobuf/service.proto
package protobuf
import (
context "context"
fmt "fmt"
math "math"
proto "github.com/golang/protobuf/proto"
timestamp "github.com/golang/protobuf/ptypes/timestamp"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type DeleteResponse struct {
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DeleteResponse) Reset() { *m = DeleteResponse{} }
func (m *DeleteResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteResponse) ProtoMessage() {}
func (*DeleteResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_ad34efc7bbd96e69, []int{0}
}
func (m *DeleteResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteResponse.Unmarshal(m, b)
}
func (m *DeleteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DeleteResponse.Marshal(b, m, deterministic)
}
func (m *DeleteResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_DeleteResponse.Merge(m, src)
}
func (m *DeleteResponse) XXX_Size() int {
return xxx_messageInfo_DeleteResponse.Size(m)
}
func (m *DeleteResponse) XXX_DiscardUnknown() {
xxx_messageInfo_DeleteResponse.DiscardUnknown(m)
}
var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo
func (m *DeleteResponse) GetSuccess() bool {
if m != nil {
return m.Success
}
return false
}
type GetAllMetadataRequest struct {
SourceHost string `protobuf:"bytes,1,opt,name=source_host,json=sourceHost,proto3" json:"source_host,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetAllMetadataRequest) Reset() { *m = GetAllMetadataRequest{} }
func (m *GetAllMetadataRequest) String() string { return proto.CompactTextString(m) }
func (*GetAllMetadataRequest) ProtoMessage() {}
func (*GetAllMetadataRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ad34efc7bbd96e69, []int{1}
}
func (m *GetAllMetadataRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetAllMetadataRequest.Unmarshal(m, b)
}
func (m *GetAllMetadataRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetAllMetadataRequest.Marshal(b, m, deterministic)
}
func (m *GetAllMetadataRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetAllMetadataRequest.Merge(m, src)
}
func (m *GetAllMetadataRequest) XXX_Size() int {
return xxx_messageInfo_GetAllMetadataRequest.Size(m)
}
func (m *GetAllMetadataRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetAllMetadataRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetAllMetadataRequest proto.InternalMessageInfo
func (m *GetAllMetadataRequest) GetSourceHost() string {
if m != nil {
return m.SourceHost
}
return ""
}
type IdRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *IdRequest) Reset() { *m = IdRequest{} }
func (m *IdRequest) String() string { return proto.CompactTextString(m) }
func (*IdRequest) ProtoMessage() {}
func (*IdRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ad34efc7bbd96e69, []int{2}
}
func (m *IdRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_IdRequest.Unmarshal(m, b)
}
func (m *IdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_IdRequest.Marshal(b, m, deterministic)
}
func (m *IdRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_IdRequest.Merge(m, src)
}
func (m *IdRequest) XXX_Size() int {
return xxx_messageInfo_IdRequest.Size(m)
}
func (m *IdRequest) XXX_DiscardUnknown() {
xxx_messageInfo_IdRequest.DiscardUnknown(m)
}
var xxx_messageInfo_IdRequest proto.InternalMessageInfo
func (m *IdRequest) GetId() string {
if m != nil {
return m.Id
}
return ""
}
type UpdateRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Credential *CredentialRequest `protobuf:"bytes,2,opt,name=credential,proto3" json:"credential,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *UpdateRequest) Reset() { *m = UpdateRequest{} }
func (m *UpdateRequest) String() string { return proto.CompactTextString(m) }
func (*UpdateRequest) ProtoMessage() {}
func (*UpdateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ad34efc7bbd96e69, []int{3}
}
func (m *UpdateRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UpdateRequest.Unmarshal(m, b)
}
func (m *UpdateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_UpdateRequest.Marshal(b, m, deterministic)
}
func (m *UpdateRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_UpdateRequest.Merge(m, src)
}
func (m *UpdateRequest) XXX_Size() int {
return xxx_messageInfo_UpdateRequest.Size(m)
}
func (m *UpdateRequest) XXX_DiscardUnknown() {
xxx_messageInfo_UpdateRequest.DiscardUnknown(m)
}
var xxx_messageInfo_UpdateRequest proto.InternalMessageInfo
func (m *UpdateRequest) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *UpdateRequest) GetCredential() *CredentialRequest {
if m != nil {
return m.Credential
}
return nil
}
type Metadata struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt *timestamp.Timestamp `protobuf:"bytes,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
UpdatedAt *timestamp.Timestamp `protobuf:"bytes,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
Primary string `protobuf:"bytes,4,opt,name=primary,proto3" json:"primary,omitempty"`
SourceHost string `protobuf:"bytes,5,opt,name=source_host,json=sourceHost,proto3" json:"source_host,omitempty"`
LoginUrl string `protobuf:"bytes,6,opt,name=login_url,json=loginUrl,proto3" json:"login_url,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Metadata) Reset() { *m = Metadata{} }
func (m *Metadata) String() string { return proto.CompactTextString(m) }
func (*Metadata) ProtoMessage() {}
func (*Metadata) Descriptor() ([]byte, []int) {
return fileDescriptor_ad34efc7bbd96e69, []int{4}
}
func (m *Metadata) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Metadata.Unmarshal(m, b)
}
func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Metadata.Marshal(b, m, deterministic)
}
func (m *Metadata) XXX_Merge(src proto.Message) {
xxx_messageInfo_Metadata.Merge(m, src)
}
func (m *Metadata) XXX_Size() int {
return xxx_messageInfo_Metadata.Size(m)
}
func (m *Metadata) XXX_DiscardUnknown() {
xxx_messageInfo_Metadata.DiscardUnknown(m)
}
var xxx_messageInfo_Metadata proto.InternalMessageInfo
func (m *Metadata) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *Metadata) GetCreatedAt() *timestamp.Timestamp {
if m != nil {
return m.CreatedAt
}
return nil
}
func (m *Metadata) GetUpdatedAt() *timestamp.Timestamp {
if m != nil {
return m.UpdatedAt
}
return nil
}
func (m *Metadata) GetPrimary() string {
if m != nil {
return m.Primary
}
return ""
}
func (m *Metadata) GetSourceHost() string {
if m != nil {
return m.SourceHost
}
return ""
}
func (m *Metadata) GetLoginUrl() string {
if m != nil {
return m.LoginUrl
}
return ""
}
type Credential struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt *timestamp.Timestamp `protobuf:"bytes,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
UpdatedAt *timestamp.Timestamp `protobuf:"bytes,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
Primary string `protobuf:"bytes,4,opt,name=primary,proto3" json:"primary,omitempty"`
Username string `protobuf:"bytes,5,opt,name=username,proto3" json:"username,omitempty"`
Email string `protobuf:"bytes,6,opt,name=email,proto3" json:"email,omitempty"`
Password string `protobuf:"bytes,7,opt,name=password,proto3" json:"password,omitempty"`
SourceHost string `protobuf:"bytes,8,opt,name=source_host,json=sourceHost,proto3" json:"source_host,omitempty"`
LoginUrl string `protobuf:"bytes,9,opt,name=login_url,json=loginUrl,proto3" json:"login_url,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Credential) Reset() { *m = Credential{} }
func (m *Credential) String() string { return proto.CompactTextString(m) }
func (*Credential) ProtoMessage() {}
func (*Credential) Descriptor() ([]byte, []int) {
return fileDescriptor_ad34efc7bbd96e69, []int{5}
}
func (m *Credential) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Credential.Unmarshal(m, b)
}
func (m *Credential) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Credential.Marshal(b, m, deterministic)
}
func (m *Credential) XXX_Merge(src proto.Message) {
xxx_messageInfo_Credential.Merge(m, src)
}
func (m *Credential) XXX_Size() int {
return xxx_messageInfo_Credential.Size(m)
}
func (m *Credential) XXX_DiscardUnknown() {
xxx_messageInfo_Credential.DiscardUnknown(m)
}
var xxx_messageInfo_Credential proto.InternalMessageInfo
func (m *Credential) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *Credential) GetCreatedAt() *timestamp.Timestamp {
if m != nil {
return m.CreatedAt
}
return nil
}
func (m *Credential) GetUpdatedAt() *timestamp.Timestamp {
if m != nil {
return m.UpdatedAt
}
return nil
}
func (m *Credential) GetPrimary() string {
if m != nil {
return m.Primary
}
return ""
}
func (m *Credential) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
func (m *Credential) GetEmail() string {
if m != nil {
return m.Email
}
return ""
}
func (m *Credential) GetPassword() string {
if m != nil {
return m.Password
}
return ""
}
func (m *Credential) GetSourceHost() string {
if m != nil {
return m.SourceHost
}
return ""
}
func (m *Credential) GetLoginUrl() string {
if m != nil {
return m.LoginUrl
}
return ""
}
type CredentialRequest struct {
Primary string `protobuf:"bytes,1,opt,name=primary,proto3" json:"primary,omitempty"`
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"`
SourceHost string `protobuf:"bytes,5,opt,name=source_host,json=sourceHost,proto3" json:"source_host,omitempty"`
LoginUrl string `protobuf:"bytes,6,opt,name=login_url,json=loginUrl,proto3" json:"login_url,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CredentialRequest) Reset() { *m = CredentialRequest{} }
func (m *CredentialRequest) String() string { return proto.CompactTextString(m) }
func (*CredentialRequest) ProtoMessage() {}
func (*CredentialRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ad34efc7bbd96e69, []int{6}
}
func (m *CredentialRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CredentialRequest.Unmarshal(m, b)
}
func (m *CredentialRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CredentialRequest.Marshal(b, m, deterministic)
}
func (m *CredentialRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_CredentialRequest.Merge(m, src)
}
func (m *CredentialRequest) XXX_Size() int {
return xxx_messageInfo_CredentialRequest.Size(m)
}
func (m *CredentialRequest) XXX_DiscardUnknown() {
xxx_messageInfo_CredentialRequest.DiscardUnknown(m)
}
var xxx_messageInfo_CredentialRequest proto.InternalMessageInfo
func (m *CredentialRequest) GetPrimary() string {
if m != nil {
return m.Primary
}
return ""
}
func (m *CredentialRequest) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
func (m *CredentialRequest) GetEmail() string {
if m != nil {
return m.Email
}
return ""
}
func (m *CredentialRequest) GetPassword() string {
if m != nil {
return m.Password
}
return ""
}
func (m *CredentialRequest) GetSourceHost() string {
if m != nil {
return m.SourceHost
}
return ""
}
func (m *CredentialRequest) GetLoginUrl() string {
if m != nil {
return m.LoginUrl
}
return ""
}
func init() {
proto.RegisterType((*DeleteResponse)(nil), "selfpass.credentials.DeleteResponse")
proto.RegisterType((*GetAllMetadataRequest)(nil), "selfpass.credentials.GetAllMetadataRequest")
proto.RegisterType((*IdRequest)(nil), "selfpass.credentials.IdRequest")
proto.RegisterType((*UpdateRequest)(nil), "selfpass.credentials.UpdateRequest")
proto.RegisterType((*Metadata)(nil), "selfpass.credentials.Metadata")
proto.RegisterType((*Credential)(nil), "selfpass.credentials.Credential")
proto.RegisterType((*CredentialRequest)(nil), "selfpass.credentials.CredentialRequest")
}
func init() { proto.RegisterFile("credentials/protobuf/service.proto", fileDescriptor_ad34efc7bbd96e69) }
var fileDescriptor_ad34efc7bbd96e69 = []byte{
// 493 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x54, 0x5d, 0x6b, 0xd4, 0x40,
0x14, 0x25, 0xd9, 0x76, 0x9b, 0xdc, 0xe2, 0x82, 0x43, 0x85, 0x90, 0x82, 0xbb, 0x44, 0xc1, 0xa2,
0x90, 0x4a, 0x7d, 0xd1, 0xc7, 0xb5, 0xc2, 0xd6, 0x07, 0x11, 0x52, 0xfb, 0xe2, 0xcb, 0x32, 0x4d,
0x6e, 0xb7, 0x81, 0xc9, 0x4e, 0x9c, 0x99, 0x28, 0xfe, 0x30, 0x41, 0xff, 0x91, 0x3f, 0x43, 0x32,
0xc9, 0xec, 0x47, 0x3a, 0xdb, 0x5d, 0xdf, 0xfa, 0x96, 0x3b, 0x39, 0x67, 0xe6, 0xdc, 0x33, 0x73,
0x2e, 0x44, 0xa9, 0xc0, 0x0c, 0xe7, 0x2a, 0xa7, 0x4c, 0x9e, 0x96, 0x82, 0x2b, 0x7e, 0x5d, 0xdd,
0x9c, 0x4a, 0x14, 0xdf, 0xf3, 0x14, 0x63, 0xbd, 0x40, 0x8e, 0x24, 0xb2, 0x9b, 0x92, 0x4a, 0x19,
0xaf, 0x80, 0xc3, 0xe1, 0x8c, 0xf3, 0x19, 0xc3, 0x25, 0x49, 0xe5, 0x05, 0x4a, 0x45, 0x8b, 0xb2,
0xa1, 0x45, 0x2f, 0x61, 0xf0, 0x01, 0x19, 0x2a, 0x4c, 0x50, 0x96, 0x7c, 0x2e, 0x91, 0x04, 0x70,
0x20, 0xab, 0x34, 0x45, 0x29, 0x03, 0x67, 0xe4, 0x9c, 0x78, 0x89, 0x29, 0xa3, 0xb7, 0xf0, 0x64,
0x82, 0x6a, 0xcc, 0xd8, 0x27, 0x54, 0x34, 0xa3, 0x8a, 0x26, 0xf8, 0xad, 0x42, 0xa9, 0xc8, 0x10,
0x0e, 0x25, 0xaf, 0x44, 0x8a, 0xd3, 0x5b, 0x2e, 0x95, 0xa6, 0xf9, 0x09, 0x34, 0x4b, 0x17, 0x5c,
0xaa, 0xe8, 0x18, 0xfc, 0x8f, 0x99, 0x41, 0x0f, 0xc0, 0xcd, 0xb3, 0x16, 0xe4, 0xe6, 0x59, 0x74,
0x0b, 0x8f, 0xae, 0xca, 0x8c, 0xd6, 0x12, 0xac, 0x00, 0x32, 0x01, 0x58, 0xf6, 0x14, 0xb8, 0x23,
0xe7, 0xe4, 0xf0, 0xec, 0x45, 0x6c, 0xeb, 0x37, 0x3e, 0x5f, 0x7c, 0xb7, 0x9b, 0x25, 0x2b, 0xd4,
0xe8, 0xaf, 0x03, 0x9e, 0xd1, 0x7e, 0xe7, 0x94, 0x77, 0xfa, 0x14, 0xaa, 0x30, 0x9b, 0x52, 0xd5,
0x9e, 0x12, 0xc6, 0x8d, 0x7f, 0xb1, 0xf1, 0x2f, 0xfe, 0x62, 0xfc, 0x4b, 0xfc, 0x16, 0x3d, 0x56,
0x35, 0xb5, 0xd2, 0x1d, 0x68, 0x6a, 0x6f, 0x3b, 0xb5, 0x45, 0x8f, 0x55, 0xed, 0x76, 0x29, 0xf2,
0x82, 0x8a, 0x9f, 0xc1, 0x9e, 0x96, 0x62, 0xca, 0xae, 0xa9, 0xfb, 0x5d, 0x53, 0xc9, 0x31, 0xf8,
0x8c, 0xcf, 0xf2, 0xf9, 0xb4, 0x12, 0x2c, 0xe8, 0xeb, 0xdf, 0x9e, 0x5e, 0xb8, 0x12, 0x2c, 0xfa,
0xed, 0x02, 0x2c, 0xcd, 0x78, 0xf0, 0xcd, 0x86, 0xe0, 0x55, 0x12, 0xc5, 0x9c, 0x16, 0xd8, 0x76,
0xba, 0xa8, 0xc9, 0x11, 0xec, 0x63, 0x41, 0x73, 0xd3, 0x63, 0x53, 0xd4, 0x8c, 0xfa, 0xf6, 0x7f,
0x70, 0x91, 0x05, 0x07, 0x0d, 0xc3, 0xd4, 0x5d, 0xeb, 0xbc, 0xfb, 0xad, 0xf3, 0x3b, 0xd6, 0xfd,
0x71, 0xe0, 0xf1, 0x9d, 0x77, 0xb4, 0xaa, 0xdd, 0xd9, 0xac, 0xdd, 0xdd, 0xa4, 0xbd, 0xb7, 0x49,
0xfb, 0xde, 0xfd, 0xda, 0xff, 0xef, 0xda, 0xcf, 0x7e, 0xf5, 0x56, 0xb5, 0x5f, 0x36, 0x13, 0x82,
0x4c, 0x61, 0xb0, 0x1e, 0x5c, 0xf2, 0xca, 0x1e, 0x1f, 0x6b, 0xbc, 0xc3, 0xa7, 0x76, 0xb0, 0x81,
0xbd, 0x76, 0xc8, 0x05, 0xf4, 0x26, 0xa8, 0xc8, 0xd0, 0x0e, 0x5c, 0x44, 0x3f, 0x1c, 0x6d, 0x4b,
0x2d, 0xb9, 0x84, 0xfe, 0xb9, 0x7e, 0x6a, 0x64, 0xd7, 0x84, 0xef, 0xb0, 0xe9, 0x67, 0xe8, 0x37,
0x13, 0x86, 0x3c, 0xb3, 0x63, 0xd7, 0xe6, 0xcf, 0x6e, 0x1b, 0x36, 0x53, 0x73, 0x7b, 0xcb, 0xcf,
0xed, 0x80, 0xf5, 0xa1, 0xfb, 0x1e, 0xbe, 0x7a, 0x26, 0x3a, 0xd7, 0x7d, 0xfd, 0xf5, 0xe6, 0x5f,
0x00, 0x00, 0x00, 0xff, 0xff, 0x8f, 0xb2, 0x15, 0xd8, 0xf6, 0x05, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// CredentialServiceClient is the client API for CredentialService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type CredentialServiceClient interface {
GetAllMetadata(ctx context.Context, in *GetAllMetadataRequest, opts ...grpc.CallOption) (CredentialService_GetAllMetadataClient, error)
Get(ctx context.Context, in *IdRequest, opts ...grpc.CallOption) (*Credential, error)
Create(ctx context.Context, in *CredentialRequest, opts ...grpc.CallOption) (*Credential, error)
Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*Credential, error)
Delete(ctx context.Context, in *IdRequest, opts ...grpc.CallOption) (*DeleteResponse, error)
}
type credentialServiceClient struct {
cc *grpc.ClientConn
}
func NewCredentialServiceClient(cc *grpc.ClientConn) CredentialServiceClient {
return &credentialServiceClient{cc}
}
func (c *credentialServiceClient) GetAllMetadata(ctx context.Context, in *GetAllMetadataRequest, opts ...grpc.CallOption) (CredentialService_GetAllMetadataClient, error) {
stream, err := c.cc.NewStream(ctx, &_CredentialService_serviceDesc.Streams[0], "/selfpass.credentials.CredentialService/GetAllMetadata", opts...)
if err != nil {
return nil, err
}
x := &credentialServiceGetAllMetadataClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type CredentialService_GetAllMetadataClient interface {
Recv() (*Metadata, error)
grpc.ClientStream
}
type credentialServiceGetAllMetadataClient struct {
grpc.ClientStream
}
func (x *credentialServiceGetAllMetadataClient) Recv() (*Metadata, error) {
m := new(Metadata)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *credentialServiceClient) Get(ctx context.Context, in *IdRequest, opts ...grpc.CallOption) (*Credential, error) {
out := new(Credential)
err := c.cc.Invoke(ctx, "/selfpass.credentials.CredentialService/Get", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *credentialServiceClient) Create(ctx context.Context, in *CredentialRequest, opts ...grpc.CallOption) (*Credential, error) {
out := new(Credential)
err := c.cc.Invoke(ctx, "/selfpass.credentials.CredentialService/Create", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *credentialServiceClient) Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*Credential, error) {
out := new(Credential)
err := c.cc.Invoke(ctx, "/selfpass.credentials.CredentialService/Update", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *credentialServiceClient) Delete(ctx context.Context, in *IdRequest, opts ...grpc.CallOption) (*DeleteResponse, error) {
out := new(DeleteResponse)
err := c.cc.Invoke(ctx, "/selfpass.credentials.CredentialService/Delete", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// CredentialServiceServer is the server API for CredentialService service.
type CredentialServiceServer interface {
GetAllMetadata(*GetAllMetadataRequest, CredentialService_GetAllMetadataServer) error
Get(context.Context, *IdRequest) (*Credential, error)
Create(context.Context, *CredentialRequest) (*Credential, error)
Update(context.Context, *UpdateRequest) (*Credential, error)
Delete(context.Context, *IdRequest) (*DeleteResponse, error)
}
// UnimplementedCredentialServiceServer can be embedded to have forward compatible implementations.
type UnimplementedCredentialServiceServer struct {
}
func (*UnimplementedCredentialServiceServer) GetAllMetadata(req *GetAllMetadataRequest, srv CredentialService_GetAllMetadataServer) error {
return status.Errorf(codes.Unimplemented, "method GetAllMetadata not implemented")
}
func (*UnimplementedCredentialServiceServer) Get(ctx context.Context, req *IdRequest) (*Credential, error) {
return nil, status.Errorf(codes.Unimplemented, "method Get not implemented")
}
func (*UnimplementedCredentialServiceServer) Create(ctx context.Context, req *CredentialRequest) (*Credential, error) {
return nil, status.Errorf(codes.Unimplemented, "method Create not implemented")
}
func (*UnimplementedCredentialServiceServer) Update(ctx context.Context, req *UpdateRequest) (*Credential, error) {
return nil, status.Errorf(codes.Unimplemented, "method Update not implemented")
}
func (*UnimplementedCredentialServiceServer) Delete(ctx context.Context, req *IdRequest) (*DeleteResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented")
}
func RegisterCredentialServiceServer(s *grpc.Server, srv CredentialServiceServer) {
s.RegisterService(&_CredentialService_serviceDesc, srv)
}
func _CredentialService_GetAllMetadata_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(GetAllMetadataRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(CredentialServiceServer).GetAllMetadata(m, &credentialServiceGetAllMetadataServer{stream})
}
type CredentialService_GetAllMetadataServer interface {
Send(*Metadata) error
grpc.ServerStream
}
type credentialServiceGetAllMetadataServer struct {
grpc.ServerStream
}
func (x *credentialServiceGetAllMetadataServer) Send(m *Metadata) error {
return x.ServerStream.SendMsg(m)
}
func _CredentialService_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(IdRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CredentialServiceServer).Get(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/selfpass.credentials.CredentialService/Get",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CredentialServiceServer).Get(ctx, req.(*IdRequest))
}
return interceptor(ctx, in, info, handler)
}
func _CredentialService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CredentialRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CredentialServiceServer).Create(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/selfpass.credentials.CredentialService/Create",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CredentialServiceServer).Create(ctx, req.(*CredentialRequest))
}
return interceptor(ctx, in, info, handler)
}
func _CredentialService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CredentialServiceServer).Update(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/selfpass.credentials.CredentialService/Update",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CredentialServiceServer).Update(ctx, req.(*UpdateRequest))
}
return interceptor(ctx, in, info, handler)
}
func _CredentialService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(IdRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CredentialServiceServer).Delete(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/selfpass.credentials.CredentialService/Delete",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CredentialServiceServer).Delete(ctx, req.(*IdRequest))
}
return interceptor(ctx, in, info, handler)
}
var _CredentialService_serviceDesc = grpc.ServiceDesc{
ServiceName: "selfpass.credentials.CredentialService",
HandlerType: (*CredentialServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Get",
Handler: _CredentialService_Get_Handler,
},
{
MethodName: "Create",
Handler: _CredentialService_Create_Handler,
},
{
MethodName: "Update",
Handler: _CredentialService_Update_Handler,
},
{
MethodName: "Delete",
Handler: _CredentialService_Delete_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "GetAllMetadata",
Handler: _CredentialService_GetAllMetadata_Handler,
ServerStreams: true,
},
},
Metadata: "credentials/protobuf/service.proto",
}

View file

@ -0,0 +1,62 @@
syntax = "proto3";
package selfpass.credentials;
option go_package = "protobuf";
import "google/protobuf/timestamp.proto";
service CredentialService {
rpc GetAllMetadata (GetAllMetadataRequest) returns (stream Metadata);
rpc Get (IdRequest) returns (Credential);
rpc Create (CredentialRequest) returns (Credential);
rpc Update (UpdateRequest) returns (Credential);
rpc Delete (IdRequest) returns (DeleteResponse);
}
message DeleteResponse {
bool success = 1;
}
message GetAllMetadataRequest {
string source_host = 1;
}
message IdRequest {
string id = 1;
}
message UpdateRequest {
string id = 1;
CredentialRequest credential = 2;
}
message Metadata {
string id = 1;
google.protobuf.Timestamp created_at = 2;
google.protobuf.Timestamp updated_at = 3;
string primary = 4;
string source_host = 5;
string login_url = 6;
}
message Credential {
string id = 1;
google.protobuf.Timestamp created_at = 2;
google.protobuf.Timestamp updated_at = 3;
string primary = 4;
string username = 5;
string email = 6;
string password = 7;
string source_host = 8;
string login_url = 9;
}
message CredentialRequest {
string primary = 1;
string username = 2;
string email = 3;
string password = 4;
string source_host = 5;
string login_url = 6;
}

View file

@ -0,0 +1,118 @@
package repositories
import (
"context"
"github.com/aws/aws-sdk-go-v2/aws/external"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/dynamodbattribute"
"github.com/mitchell/selfpass/credentials/types"
)
// NewDynamoTable TODO
func NewDynamoTable(name string) DynamoTable {
cfg, err := external.LoadDefaultAWSConfig()
if err != nil {
panic(err.Error())
}
return DynamoTable{
name: name,
svc: dynamodb.New(cfg),
}
}
// DynamoTable TODO
type DynamoTable struct {
name string
svc *dynamodb.DynamoDB
}
// GetAllMetadata TODO
func (t DynamoTable) GetAllMetadata(ctx context.Context, sourceService string, errch chan<- error) (output <-chan types.Metadata) {
mdch := make(chan types.Metadata, 1)
in := &dynamodb.ScanInput{TableName: &t.name}
if sourceService != "" {
filterExpr := "SourceHost = :sh"
in.FilterExpression = &filterExpr
in.ExpressionAttributeValues = map[string]dynamodb.AttributeValue{
":sh": {S: &sourceService},
}
}
req := t.svc.ScanRequest(in)
go func() {
defer close(mdch)
pgr := req.Paginate()
for pgr.Next() {
mds := []types.Metadata{}
out := pgr.CurrentPage()
if err := dynamodbattribute.UnmarshalListOfMaps(out.Items, &mds); err != nil {
errch <- err
return
}
for _, md := range mds {
mdch <- md
}
}
if err := pgr.Err(); err != nil {
errch <- err
return
}
}()
return mdch
}
// Get TODO
func (t DynamoTable) Get(ctx context.Context, id string) (output types.Credential, err error) {
req := t.svc.GetItemRequest(&dynamodb.GetItemInput{
TableName: &t.name,
Key: map[string]dynamodb.AttributeValue{
"ID": {S: &id},
},
})
out, err := req.Send()
if err != nil {
return output, err
}
err = dynamodbattribute.UnmarshalMap(out.Item, &output)
return output, err
}
// Put TODO
func (t DynamoTable) Put(ctx context.Context, c types.Credential) (err error) {
item, err := dynamodbattribute.MarshalMap(c)
if err != nil {
return err
}
req := t.svc.PutItemRequest(&dynamodb.PutItemInput{
TableName: &t.name,
Item: item,
})
req.SetContext(ctx)
_, err = req.Send()
return err
}
// Delete TODO
func (t DynamoTable) Delete(ctx context.Context, id string) (err error) {
req := t.svc.DeleteItemRequest(&dynamodb.DeleteItemInput{
TableName: &t.name,
Key: map[string]dynamodb.AttributeValue{
"ID": {S: &id},
},
})
_, err = req.Send()
return err
}

View file

@ -0,0 +1,84 @@
package service
import (
"context"
"time"
"github.com/google/uuid"
"github.com/mitchell/selfpass/credentials/types"
)
// NewCredentials TODO
func NewCredentials(repo types.CredentialRepo) Credentials {
return Credentials{
repo: repo,
}
}
// Credentials TODO
type Credentials struct {
repo types.CredentialRepo
}
// GetAllMetadata TODO
func (svc Credentials) GetAllMetadata(ctx context.Context, sourceService string) (output <-chan types.Metadata, errch chan error) {
errch = make(chan error, 1)
output = svc.repo.GetAllMetadata(ctx, sourceService, errch)
return output, errch
}
// Get TODO
func (svc Credentials) Get(ctx context.Context, id string) (output types.Credential, err error) {
return svc.repo.Get(nil, id)
}
// Create TODO
func (svc Credentials) Create(ctx context.Context, ci types.CredentialInput) (output types.Credential, err error) {
if err = validateCreate(ci); err != nil {
return output, err
}
var c types.Credential
c.ID = "cred-" + uuid.New().String()
c.CreatedAt = time.Now()
c.UpdatedAt = time.Now()
c.Primary = ci.Primary
c.LoginURL = ci.LoginURL
c.SourceHost = ci.SourceHost
c.Username = ci.Username
c.Email = ci.Email
c.Password = ci.Password
err = svc.repo.Put(ctx, c)
return c, err
}
func validateCreate(c types.CredentialInput) (err error) {
return err
}
// Update TODO
func (svc Credentials) Update(ctx context.Context, id string, ci types.CredentialInput) (output types.Credential, err error) {
c, err := svc.repo.Get(ctx, id)
if err != nil {
return output, err
}
c.UpdatedAt = time.Now()
c.Primary = ci.Primary
c.LoginURL = ci.LoginURL
c.SourceHost = ci.SourceHost
c.Password = ci.Password
c.Email = ci.Email
c.Username = ci.Username
return c, svc.repo.Put(ctx, c)
}
// Delete TODO
func (svc Credentials) Delete(ctx context.Context, id string) (err error) {
return svc.repo.Delete(nil, id)
}

View file

@ -0,0 +1,127 @@
package transport
import (
"context"
"github.com/golang/protobuf/ptypes"
"github.com/mitchell/selfpass/credentials/endpoints"
"github.com/mitchell/selfpass/credentials/protobuf"
"github.com/mitchell/selfpass/credentials/types"
)
func decodeGetAllMetadataRequest(ctx context.Context, request interface{}) (interface{}, error) {
r := request.(protobuf.GetAllMetadataRequest)
return endpoints.GetAllMetadataRequest{
SourceHost: r.SourceHost,
}, nil
}
func encodeMetadataStreamResponse(ctx context.Context, response interface{}) (interface{}, error) {
r := response.(endpoints.MetadataStream)
pbmdch := make(chan protobuf.Metadata, 1)
go func() {
defer close(pbmdch)
for md := range r.Metadata {
createdAt, err := ptypes.TimestampProto(md.CreatedAt)
if err != nil {
r.Errors <- err
return
}
updatedAt, err := ptypes.TimestampProto(md.UpdatedAt)
if err != nil {
r.Errors <- err
return
}
pbmdch <- protobuf.Metadata{
Id: md.ID,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
SourceHost: md.SourceHost,
Primary: md.Primary,
LoginUrl: md.LoginURL,
}
}
}()
return protobufMetadataStream{
Metadata: pbmdch,
Errors: r.Errors,
}, nil
}
type protobufMetadataStream struct {
Metadata <-chan protobuf.Metadata
Errors chan error
}
func decodeCredentialRequest(ctx context.Context, request interface{}) (interface{}, error) {
r := request.(protobuf.CredentialRequest)
return types.CredentialInput{
MetadataInput: types.MetadataInput{
Primary: r.Primary,
LoginURL: r.LoginUrl,
SourceHost: r.SourceHost,
},
Username: r.Username,
Email: r.Email,
Password: r.Password,
}, nil
}
func encodeCredentialResponse(ctx context.Context, response interface{}) (interface{}, error) {
r := response.(types.Credential)
createdAt, err := ptypes.TimestampProto(r.CreatedAt)
if err != nil {
return nil, err
}
updatedAt, err := ptypes.TimestampProto(r.UpdatedAt)
if err != nil {
return nil, err
}
return protobuf.Credential{
Id: r.ID,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
Primary: r.Primary,
SourceHost: r.SourceHost,
LoginUrl: r.LoginURL,
Username: r.Username,
Email: r.Email,
Password: r.Password,
}, nil
}
func decodeUpdateRequest(ctx context.Context, request interface{}) (interface{}, error) {
r := request.(protobuf.UpdateRequest)
return endpoints.UpdateRequest{
ID: r.Id,
Credential: types.CredentialInput{
MetadataInput: types.MetadataInput{
Primary: r.Credential.Primary,
SourceHost: r.Credential.SourceHost,
LoginURL: r.Credential.LoginUrl,
},
Username: r.Credential.Username,
Email: r.Credential.Email,
Password: r.Credential.Password,
},
}, nil
}
func decodeIdRequest(ctx context.Context, request interface{}) (interface{}, error) {
r := request.(protobuf.IdRequest)
return endpoints.IDRequest{
ID: r.Id,
}, nil
}
func noOpEncode(ctx context.Context, request interface{}) (interface{}, error) {
return nil, nil
}

View file

@ -0,0 +1,146 @@
package transport
import (
"context"
"fmt"
"strings"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/transport/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/mitchell/selfpass/credentials/endpoints"
"github.com/mitchell/selfpass/credentials/protobuf"
"github.com/mitchell/selfpass/credentials/types"
)
// NewGRPCServer TODO
func NewGRPCServer(svc types.Service, logger log.Logger) GRPCServer {
return GRPCServer{
getAllMetadata: grpc.NewServer(
endpoints.MakeGetAllMetadataEndpoint(svc),
decodeGetAllMetadataRequest,
encodeMetadataStreamResponse,
grpc.ServerErrorLogger(logger),
),
create: grpc.NewServer(
endpoints.MakeCreateEndpoint(svc),
decodeCredentialRequest,
encodeCredentialResponse,
grpc.ServerErrorLogger(logger),
),
update: grpc.NewServer(
endpoints.MakeUpdateEndpoint(svc),
decodeUpdateRequest,
encodeCredentialResponse,
grpc.ServerErrorLogger(logger),
),
delete: grpc.NewServer(
endpoints.MakeDeleteEndpoint(svc),
decodeIdRequest,
noOpEncode,
grpc.ServerErrorLogger(logger),
),
}
}
// GRPCServer TODO
type GRPCServer struct {
getAllMetadata *grpc.Server
create *grpc.Server
update *grpc.Server
delete *grpc.Server
}
// GetAllMetadata TODO
func (s GRPCServer) GetAllMetadata(r *protobuf.GetAllMetadataRequest, srv protobuf.CredentialService_GetAllMetadataServer) (err error) {
defer func() {
err = handlerGRPCError(err)
}()
var i interface{}
ctx := srv.Context()
ctx, i, err = s.getAllMetadata.ServeGRPC(ctx, *r)
if err != nil {
return err
}
mds := i.(protobufMetadataStream)
receiveLoop:
for {
select {
case <-ctx.Done():
break receiveLoop
case err = <-mds.Errors:
break receiveLoop
case md, ok := <-mds.Metadata:
if !ok {
break receiveLoop
}
fmt.Println(md)
if err = srv.Send(&md); err != nil {
break receiveLoop
}
}
}
return err
}
// Get TODO
func (s GRPCServer) Get(context.Context, *protobuf.IdRequest) (*protobuf.Credential, error) {
panic("implement me")
}
// Create TODO
func (s GRPCServer) Create(ctx context.Context, ci *protobuf.CredentialRequest) (*protobuf.Credential, error) {
ctx, i, err := s.create.ServeGRPC(ctx, *ci)
if err != nil {
err = handlerGRPCError(err)
return nil, err
}
c := &protobuf.Credential{}
*c = i.(protobuf.Credential)
return c, nil
}
// Update TODO
func (s GRPCServer) Update(ctx context.Context, r *protobuf.UpdateRequest) (*protobuf.Credential, error) {
ctx, i, err := s.update.ServeGRPC(ctx, *r)
if err != nil {
err = handlerGRPCError(err)
return nil, err
}
c := &protobuf.Credential{}
*c = i.(protobuf.Credential)
return c, nil
}
// Delete TODO
func (s GRPCServer) Delete(ctx context.Context, r *protobuf.IdRequest) (*protobuf.DeleteResponse, error) {
ctx, _, err := s.delete.ServeGRPC(ctx, *r)
if err != nil {
return nil, err
}
return &protobuf.DeleteResponse{Success: true}, nil
}
func handlerGRPCError(err error) error {
if err != nil {
switch {
case strings.HasPrefix(err.Error(), types.InvalidArgument):
err = status.Error(codes.InvalidArgument, err.Error())
case strings.HasPrefix(err.Error(), types.NotFound):
err = status.Error(codes.NotFound, err.Error())
default:
err = status.Error(codes.Internal, "an internal error has occurred")
}
}
return err
}

View file

@ -0,0 +1,36 @@
package types
import "time"
// Credential TODO
type Credential struct {
Metadata
Username string
Email string
Password string
}
// CredentialInput TODO
type CredentialInput struct {
MetadataInput
Username string
Email string
Password string
}
// Metadata TODO
type Metadata struct {
ID string
CreatedAt time.Time
UpdatedAt time.Time
Primary string
SourceHost string
LoginURL string
}
// MetadataInput TODO
type MetadataInput struct {
Primary string
SourceHost string
LoginURL string
}

View file

@ -0,0 +1,8 @@
package types
// These constants are the prefixes of errors that should be exposed to the client.
// All error encoders should check for them.
const (
NotFound = "not found:"
InvalidArgument = "invalid argument:"
)

View file

@ -0,0 +1,20 @@
package types
import "context"
// Service TODO
type Service interface {
GetAllMetadata(ctx context.Context, sourceService string) (output <-chan Metadata, errch chan error)
Get(ctx context.Context, id string) (output Credential, err error)
Create(ctx context.Context, ci CredentialInput) (output Credential, err error)
Update(ctx context.Context, id string, ci CredentialInput) (output Credential, err error)
Delete(ctx context.Context, id string) (err error)
}
// CredentialRepo TODO
type CredentialRepo interface {
GetAllMetadata(ctx context.Context, sourceService string, errch chan<- error) (output <-chan Metadata)
Get(ctx context.Context, id string) (output Credential, err error)
Put(ctx context.Context, c Credential) (err error)
Delete(ctx context.Context, id string) (err error)
}