Exemple #1
0
func handleLog(ctx *cli.Context, client *daemon.Client) error {
	log, err := client.Log(nil, nil)
	if err != nil {
		return err
	}

	for _, pnode := range log.Nodes {
		commitMH, err := multihash.Cast(pnode.Hash)
		if err != nil {
			return err
		}

		pcmt := pnode.Commit
		if pcmt == nil {
			return fmt.Errorf("Empty commit in log-commit")
		}

		rootMH, err := multihash.Cast(pcmt.Root)
		if err != nil {
			return err
		}

		fmt.Printf(
			"%s/%s by %s, %s\n",
			colors.Colorize(commitMH.B58String()[:10], colors.Green),
			colors.Colorize(rootMH.B58String()[:10], colors.Magenta),
			pcmt.Author,
			pcmt.Message,
		)
	}
	return nil
}
Exemple #2
0
func printCheckpoint(checkpoint *store.Checkpoint, idx, historylen int) {
	threeWayRune, twoWayRune := treeRuneTri, treeRunePipe
	if idx == historylen-1 {
		threeWayRune, twoWayRune = treeRuneCorner, " "
	}

	fmt.Printf(
		" %s%s %s #%d (%s by %s)\n",
		threeWayRune,
		treeRuneBar,
		colors.Colorize("Checkpoint", colors.Cyan),
		historylen-idx,
		colors.Colorize(checkpoint.ChangeType().String(), colors.Red),
		colors.Colorize(string(checkpoint.Author()), colors.Magenta),
	)

	fmt.Printf(
		" %s   ├─ % 9s: %v\n",
		twoWayRune,
		colors.Colorize("Hash", colors.Green),
		checkpoint.Hash().B58String(),
	)

	fmt.Printf(
		" %s   └─ % 9s: %v\n",
		twoWayRune,
		colors.Colorize("Date", colors.Yellow),
		time.Now(), // TODO: Use actual checkpoint mtime
	)
}
Exemple #3
0
func createStrengthPrompt(password []rune, prefix string) string {
	symbol, color := "", colors.Red
	strength := zxcvbn.PasswordStrength(string(password), nil)

	switch {
	case strength.Score <= 1:
		symbol = "✗"
		color = colors.Red
	case strength.Score <= 2:
		symbol = "⚡"
		color = colors.Magenta
	case strength.Score <= 3:
		symbol = "⚠"
		color = colors.Yellow
	case strength.Score <= 4:
		symbol = "✔"
		color = colors.Green
	}

	prompt := colors.Colorize(symbol, color)
	if strength.Entropy > 0 {
		entropy := fmt.Sprintf(" %3.0f", strength.Entropy)
		prompt += colors.Colorize(entropy, colors.Cyan)
	} else {
		prompt += colors.Colorize(" ENT", colors.Cyan)
	}

	prompt += colors.Colorize(" "+prefix+"passphrase: ", color)
	return prompt
}
Exemple #4
0
func printRemoteEntry(re *daemon.RemoteEntry) {
	state := colors.Colorize("offline", colors.Red)
	if re.IsOnline {
		state = colors.Colorize("online", colors.Green)
	}

	fmt.Printf("%s %-7s %s\n", re.Hash, state, re.Ident)
}
Exemple #5
0
// PromptNewPassword asks the user to input a password.
//
// While typing, the user gets feedback by the prompt color,
// which changes with the security of the password to green.
// Additionally the entrtopy of the password is shown.
// If minEntropy was not reached after hitting enter,
// this function will log a message and ask the user again.
func PromptNewPassword(minEntropy float64) ([]byte, error) {
	rl, err := readline.New("")
	if err != nil {
		return nil, err
	}
	defer util.Closer(rl)

	passwordCfg := rl.GenPasswordConfig()
	passwordCfg.SetListener(func(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) {
		rl.SetPrompt(createStrengthPrompt(line, "   New "))
		rl.Refresh()
		return nil, 0, false
	})

	pwd := []byte{}

	for {
		pwd, err = rl.ReadPasswordWithConfig(passwordCfg)
		if err != nil {
			return nil, err
		}

		strength := zxcvbn.PasswordStrength(string(pwd), nil)
		if strength.Entropy >= minEntropy {
			break
		}

		fmt.Printf(colors.Colorize(msgLowEntropy, colors.Yellow)+"\n", minEntropy)
	}

	passwordCfg.SetListener(func(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) {
		rl.SetPrompt(createStrengthPrompt(line, "Retype "))
		rl.Refresh()
		return nil, 0, false
	})

	fmt.Println(colors.Colorize(msgReEnter, colors.Green))

	for {
		newPwd, err := rl.ReadPasswordWithConfig(passwordCfg)
		if err != nil {
			return nil, err
		}

		if bytes.Equal(pwd, newPwd) {
			break
		}

		fmt.Println(colors.Colorize(msgBadPassword, colors.Yellow))
	}

	return pwd, nil
}
Exemple #6
0
func printChangesByUser(changesByuser changeByType) error {
	for typ, checkpoints := range changesByuser {
		changeType := store.ChangeType(typ)

		fmt.Printf("\n    %s:\n", strings.Title((&changeType).String()))
		for _, change := range checkpoints {
			msg := fmt.Sprintf(
				"        %s (%s)",
				"TODO: resolve checkpoint to path",
				humanize.Bytes(uint64(change.Size())),
			)

			color := 0
			switch typ {
			case store.ChangeAdd:
				color = colors.Green
			case store.ChangeRemove:
				color = colors.Red
			case store.ChangeModify:
				color = colors.Yellow
			case store.ChangeMove:
				color = colors.Cyan
			default:
				return fmt.Errorf("Invalid change type")

			}
			fmt.Println(colors.Colorize(msg, color))
		}
	}

	return nil
}
Exemple #7
0
func handleList(ctx *cli.Context, client *daemon.Client) error {
	path := "/"
	if ctx.NArg() > 0 {
		path = prefixSlash(ctx.Args().First())
	}

	depth := ctx.Int("depth")
	if ctx.Bool("recursive") {
		depth = -1
	}

	entries, err := client.List(path, depth)
	if err != nil {
		return ExitCode{
			UnknownError,
			fmt.Sprintf("ls: %v", err),
		}
	}

	for _, entry := range entries {
		modTime := time.Time{}
		if err := modTime.UnmarshalText(entry.ModTime); err != nil {
			log.Warningf("Could not parse mtime (%s): %v", entry.ModTime, err)
			continue
		}

		fmt.Printf(
			"%s\t%s\t%s\n",
			colors.Colorize(
				humanize.Bytes(uint64(entry.NodeSize)),
				colors.Green,
			),
			colors.Colorize(
				humanize.Time(modTime),
				colors.Cyan,
			),
			colors.Colorize(
				entry.Path,
				colors.Magenta,
			),
		)
	}

	return nil
}
Exemple #8
0
func (n *treeNode) Print() {
	parents := make([]*treeNode, n.depth)
	curr := n

	sort.Sort(n)

	// You could do probably go upwards and print to
	// a string buffer for performance, but this is "fun" code...
	for i := 0; i < n.depth; i++ {
		parents[n.depth-i-1] = curr
		curr = curr.parent
	}

	for i := 0; i < n.depth; i++ {
		if i == n.depth-1 {
			if n.isLast {
				fmt.Printf("%s", treeRuneCorner)
			} else {
				fmt.Printf("%s", treeRuneTri)
			}
		} else {
			if parents[i].isLast {
				fmt.Printf("%s  ", " ")
			} else {
				fmt.Printf("%s  ", treeRunePipe)
			}
		}
	}

	name, prefix := n.name, treeRuneBar

	switch {
	case n.name == "/":
		name, prefix = colors.Colorize(n.name, colors.Magenta), ""
	case n.entry.Type == store.NodeTypeDirectory:
		name = colors.Colorize(name, colors.Green)
	}

	fmt.Printf("%s%s\n", prefix, name)

	for _, child := range n.order {
		child.Print()
	}
}
Exemple #9
0
func handleDaemonPing(ctx *cli.Context, client *daemon.Client) error {
	for i := 0; i < 100; i++ {
		before := time.Now()
		symbol := colors.Colorize("✔", colors.Green)
		if !client.Ping() {
			symbol = colors.Colorize("✘", colors.Red)
		}

		delay := time.Since(before)

		fmt.Printf("#%02d %s ➔ %s: %s (%v)\n",
			i+1,
			client.LocalAddr().String(),
			client.RemoteAddr().String(),
			symbol, delay)

		time.Sleep(1 * time.Second)
	}

	return nil
}
Exemple #10
0
func promptPasswordColored(color int) (string, error) {
	prompt := "Password: "******"", err
	}
	defer util.Closer(rl)

	return doPromptLine(rl, prompt, true)
}
Exemple #11
0
func handleHistory(ctx *cli.Context, client *daemon.Client) error {
	repoPath := prefixSlash(ctx.Args().First())

	history, err := client.History(repoPath)
	if err != nil {
		return ExitCode{
			UnknownError,
			fmt.Sprintf("Unable to retrieve history: %v", err),
		}
	}

	fmt.Println(colors.Colorize(repoPath, colors.Magenta))
	for idx := range history {
		checkpoint := history[len(history)-idx-1]
		printCheckpoint(checkpoint, idx, len(history))

	}
	return nil
}
Exemple #12
0
func handleStatus(ctx *cli.Context, client *daemon.Client) error {
	status, err := client.Status()
	if err != nil {
		return err
	}

	statusCmt := status.Commit
	if statusCmt == nil {
		return fmt.Errorf("Empty status commit in response.")
	}

	checkpoints := statusCmt.Checkpoints
	if len(checkpoints) == 0 {
		fmt.Println("Nothing to commit.")
		return nil
	}

	userToChanges := make(map[id.ID]changeByType)
	for _, pckp := range checkpoints {
		byAuthor, ok := userToChanges[id.ID(pckp.Author)]
		if !ok {
			byAuthor = make(changeByType)
			userToChanges[id.ID(pckp.Author)] = byAuthor
		}

		byAuthor[pckp.Change] = append(byAuthor[pckp.Change], pckp)
	}

	for user, changesByuser := range userToChanges {
		fmt.Printf(
			"Changes by %s:\n",
			colors.Colorize(string(user), colors.Magenta),
		)
		printChangesByUser(changesByuser)
	}

	return nil
}