mirror of
https://github.com/mitchell/selfpass.git
synced 2025-12-13 21:07:22 +00:00
Update list and get commands to use better choosing strategy;
refactor Makefile to use go mod vendoring and docker caching
This commit is contained in:
parent
b2a41cf07c
commit
383a3aa1cd
9 changed files with 193 additions and 224 deletions
|
|
@ -13,22 +13,86 @@ import (
|
|||
"github.com/spf13/viper"
|
||||
"gopkg.in/AlecAivazis/survey.v1"
|
||||
|
||||
"github.com/mitchell/selfpass/credentials/types"
|
||||
"github.com/mitchell/selfpass/crypto"
|
||||
)
|
||||
|
||||
func MakeGet(masterpass string, cfg *viper.Viper, initClient CredentialClientInit) *cobra.Command {
|
||||
getCmd := &cobra.Command{
|
||||
Use: "get [id]",
|
||||
Use: "get",
|
||||
Short: "Get a credential info and copy password to clipboard",
|
||||
Long: `Get a credential's info and copy password to clipboard, from Selfpass server, after
|
||||
decrypting password.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
|
||||
cred, err := initClient(ctx).Get(ctx, args[0])
|
||||
client := initClient(ctx)
|
||||
mdch, errch := client.GetAllMetadata(ctx, "")
|
||||
mds := map[string][]types.Metadata{}
|
||||
|
||||
fmt.Println()
|
||||
|
||||
receive:
|
||||
for count := 0; ; count++ {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
check(fmt.Errorf("context timeout"))
|
||||
|
||||
case err := <-errch:
|
||||
check(err)
|
||||
|
||||
case md, ok := <-mdch:
|
||||
if !ok {
|
||||
break receive
|
||||
}
|
||||
|
||||
mds[md.SourceHost] = append(mds[md.SourceHost], md)
|
||||
}
|
||||
}
|
||||
|
||||
sources := []string{}
|
||||
for source := range mds {
|
||||
sources = append(sources, source)
|
||||
}
|
||||
|
||||
var prompt survey.Prompt
|
||||
prompt = &survey.Select{
|
||||
Message: "Source host:",
|
||||
Options: sources,
|
||||
PageSize: 10,
|
||||
VimMode: true,
|
||||
}
|
||||
|
||||
var source string
|
||||
check(survey.AskOne(prompt, &source, nil))
|
||||
|
||||
keys := []string{}
|
||||
keyIDMap := map[string]string{}
|
||||
for _, md := range mds[source] {
|
||||
key := md.Primary
|
||||
if md.Tag != "" {
|
||||
key += "-" + md.Tag
|
||||
}
|
||||
keys = append(keys, key)
|
||||
keyIDMap[key] = md.ID
|
||||
}
|
||||
|
||||
prompt = &survey.Select{
|
||||
Message: "Primary user key (and tag):",
|
||||
Options: keys,
|
||||
PageSize: 10,
|
||||
VimMode: true,
|
||||
}
|
||||
|
||||
var idKey string
|
||||
check(survey.AskOne(prompt, &idKey, nil))
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
|
||||
cred, err := client.Get(ctx, keyIDMap[idKey])
|
||||
check(err)
|
||||
|
||||
fmt.Println(cred)
|
||||
|
|
@ -44,7 +108,7 @@ decrypting password.`,
|
|||
check(err)
|
||||
|
||||
var copyPass bool
|
||||
prompt := &survey.Confirm{Message: "Copy password to clipboard?", Default: true}
|
||||
prompt = &survey.Confirm{Message: "Copy password to clipboard?", Default: true}
|
||||
check(survey.AskOne(prompt, ©Pass, nil))
|
||||
|
||||
if copyPass {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ package commands
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/AlecAivazis/survey.v1"
|
||||
|
||||
"github.com/mitchell/selfpass/credentials/types"
|
||||
)
|
||||
|
||||
func MakeList(initClient CredentialClientInit) *cobra.Command {
|
||||
|
|
@ -18,9 +21,11 @@ func MakeList(initClient CredentialClientInit) *cobra.Command {
|
|||
includes almost all the information but the most sensitive.`,
|
||||
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
|
||||
ctx := context.Background()
|
||||
mdch, errch := initClient(ctx).GetAllMetadata(ctx, sourceHost)
|
||||
mds := map[string][]types.Metadata{}
|
||||
|
||||
fmt.Println()
|
||||
|
||||
|
|
@ -38,33 +43,32 @@ includes almost all the information but the most sensitive.`,
|
|||
break receive
|
||||
}
|
||||
|
||||
if count != 0 && count%3 == 0 {
|
||||
var proceed bool
|
||||
prompt := &survey.Confirm{Message: "Next page?", Default: true}
|
||||
check(survey.AskOne(prompt, &proceed, nil))
|
||||
|
||||
if !proceed {
|
||||
break receive
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
fmt.Println(md)
|
||||
mds[md.SourceHost] = append(mds[md.SourceHost], md)
|
||||
}
|
||||
}
|
||||
|
||||
sources := []string{}
|
||||
for source := range mds {
|
||||
sources = append(sources, source)
|
||||
}
|
||||
|
||||
prompt := &survey.Select{
|
||||
Message: "Source host:",
|
||||
Options: sources,
|
||||
PageSize: 10,
|
||||
VimMode: true,
|
||||
}
|
||||
|
||||
var source string
|
||||
check(survey.AskOne(prompt, &source, nil))
|
||||
|
||||
for _, md := range mds[source] {
|
||||
fmt.Println(md)
|
||||
}
|
||||
|
||||
fmt.Println("Done listing.")
|
||||
},
|
||||
}
|
||||
|
||||
listCmd.Flags().StringVarP(
|
||||
&sourceHost,
|
||||
"source-host",
|
||||
"s",
|
||||
"",
|
||||
"specify which source host to filter the results by",
|
||||
)
|
||||
|
||||
return listCmd
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
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"
|
||||
)
|
||||
|
||||
func NewDynamoTable(name string) DynamoTable {
|
||||
cfg, err := external.LoadDefaultAWSConfig()
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return DynamoTable{
|
||||
name: name,
|
||||
svc: dynamodb.New(cfg),
|
||||
}
|
||||
}
|
||||
|
||||
type DynamoTable struct {
|
||||
name string
|
||||
svc *dynamodb.DynamoDB
|
||||
}
|
||||
|
||||
func (t DynamoTable) GetAllMetadata(ctx context.Context, sourceHost string, errch chan<- error) (output <-chan types.Metadata) {
|
||||
mdch := make(chan types.Metadata, 1)
|
||||
in := &dynamodb.ScanInput{TableName: &t.name}
|
||||
|
||||
if sourceHost != "" {
|
||||
filterExpr := "SourceHost = :sh"
|
||||
in.FilterExpression = &filterExpr
|
||||
in.ExpressionAttributeValues = map[string]dynamodb.AttributeValue{
|
||||
":sh": {S: &sourceHost},
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue