register.go 3.15 KB
Newer Older
ElyKar's avatar
ElyKar committed
1
package cmd
2
3

import (
Loïck Bonniot's avatar
Loïck Bonniot committed
4
	"bufio"
5
6
	"errors"
	"fmt"
Loïck Bonniot's avatar
Loïck Bonniot committed
7
8
9
10
	"os"
	osuser "os/user"
	"strconv"
	"strings"
11

Loïck Bonniot's avatar
Loïck Bonniot committed
12
	"dfss/dfssc/user"
ElyKar's avatar
ElyKar committed
13
	"github.com/spf13/cobra"
14
15
16
	"golang.org/x/crypto/ssh/terminal"
)

ElyKar's avatar
ElyKar committed
17
18
19
20
21
22
23
24
var registerCmd = &cobra.Command{
	Use:   "register",
	Short: "register a new client",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Registering a new user")
		// Initialize variables
		var country, mail, organization, unit, passphrase string
		var bits int
Loïck Bonniot's avatar
Loïck Bonniot committed
25

ElyKar's avatar
ElyKar committed
26
27
28
29
30
		name := "Jon Doe"
		u, err := osuser.Current()
		if err == nil {
			name = u.Name
		}
Loïck Bonniot's avatar
Loïck Bonniot committed
31

ElyKar's avatar
ElyKar committed
32
33
34
35
36
37
38
39
40
41
42
43
		// Get all the necessary parameters
		readStringParam("Mail", "", &mail)
		readStringParam("Country", "FR", &country)
		readStringParam("Organization", name, &organization)
		readStringParam("Organizational unit", name, &unit)
		readIntParam("Length of the key (2048 or 4096)", "2048", &bits)
		err = readPassword(&passphrase, true)
		if err != nil {
			fmt.Println("An error occurred:", err.Error())
			os.Exit(1)
			return
		}
Loïck Bonniot's avatar
Loïck Bonniot committed
44

ElyKar's avatar
ElyKar committed
45
46
47
48
49
50
51
		recapUser(mail, country, organization, unit)
		err = user.Register(passphrase, country, organization, unit, mail, bits)
		if err != nil {
			fmt.Fprintln(os.Stderr, "An error occurred:", err.Error())
			os.Exit(2)
		}
	},
Loïck Bonniot's avatar
Loïck Bonniot committed
52
53
}

54
55
56
// We need to use ONLY ONE reader: buffio buffers some data (= consumes from stdin)
var reader *bufio.Reader

57
58
// Get a string parameter from standard input
func readStringParam(message, def string, ptr *string) {
Loïck Bonniot's avatar
Loïck Bonniot committed
59
60
61
62
63
64
	fmt.Print(message)
	if len(def) > 0 {
		fmt.Printf(" [%s]", def)
	}
	fmt.Print(": ")

65
66
67
	if reader == nil {
		reader = bufio.NewReader(os.Stdin)
	}
Loïck Bonniot's avatar
Loïck Bonniot committed
68
69
70
71
72
73
74
75
	value, _ := reader.ReadString('\n')

	// Trim newline symbols
	value = strings.TrimRight(value, "\n")
	value = strings.TrimRight(value, "\r")

	*ptr = value
	if value == "" {
76
77
		*ptr = def
	}
Loïck Bonniot's avatar
Loïck Bonniot committed
78

79
80
}

Loïck Bonniot's avatar
Loïck Bonniot committed
81
82
83
84
85
86
87
88
func readIntParam(message, def string, ptr *int) {
	var str string
	readStringParam(message, def, &str)
	value, err := strconv.Atoi(str)
	if err != nil {
		*ptr = 0
	} else {
		*ptr = value
89
90
91
92
	}
}

// Get the password from standard input
Loïck Bonniot's avatar
Loïck Bonniot committed
93
func readPassword(ptr *string, needConfirm bool) error {
94
95
96
97
98
99
100
101
102

	if !terminal.IsTerminal(0) {
		fmt.Println("+------------------------- WARNING --------------------------+")
		fmt.Println("| This is not a UNIX terminal, your password will be visible |")
		fmt.Println("+------------------------- WARNING --------------------------+")
		readStringParam("Enter your passphrase", "", ptr)
		return nil
	}

103
104
105
106
107
	oldState, err := terminal.MakeRaw(0)
	if err != nil {
		return err
	}

Loïck Bonniot's avatar
Loïck Bonniot committed
108
	fmt.Print("Enter your passphrase: ")
109
	passphrase, err := terminal.ReadPassword(0)
Loïck Bonniot's avatar
Loïck Bonniot committed
110
	fmt.Println()
111
112
113
114
	if err != nil {
		return err
	}

Loïck Bonniot's avatar
Loïck Bonniot committed
115
116
117
118
119
120
121
	if needConfirm {
		fmt.Print("Confirm your passphrase: ")
		confirm, err := terminal.ReadPassword(0)
		fmt.Println()
		if err != nil {
			return err
		}
122

Loïck Bonniot's avatar
Loïck Bonniot committed
123
124
125
		if fmt.Sprintf("%s", passphrase) != fmt.Sprintf("%s", confirm) {
			return errors.New("Password do not match")
		}
126
127
128
129
130
131
132
133
	}

	*ptr = fmt.Sprintf("%s", passphrase)
	_ = terminal.Restore(0, oldState)

	return nil
}

Loïck Bonniot's avatar
Loïck Bonniot committed
134
135
136
137
138
139
func recapUser(mail, country, organization, unit string) {
	fmt.Println("Summary of the new user:")
	fmt.Println("  Common Name:", mail)
	fmt.Println("  Country:", country)
	fmt.Println("  Organization:", organization)
	fmt.Println("  Organizational unit:", unit)
140
}