feature/users #1
| @@ -9,10 +9,13 @@ import ( | ||||
| 	"mime/multipart" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/urfave/cli/v2" | ||||
| 	"golang.org/x/term" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| @@ -32,19 +35,23 @@ func main() { | ||||
| 				Name:  "config", | ||||
| 				Usage: "Path to config-file.", | ||||
| 			}, | ||||
| 			&cli.StringFlag{ | ||||
| 				Name:  "url", | ||||
| 				Usage: "Base url of gpaste server", | ||||
| 			}, | ||||
| 		}, | ||||
| 		Commands: []*cli.Command{ | ||||
| 			{ | ||||
| 				Name:      "upload", | ||||
| 				Usage:     "Upload file(s)", | ||||
| 				ArgsUsage: "FILE [FILE]...", | ||||
| 				Flags: []cli.Flag{ | ||||
| 					&cli.StringFlag{ | ||||
| 						Name:  "url", | ||||
| 						Usage: "Base url of gpaste server", | ||||
| 					}, | ||||
| 				}, | ||||
| 				Action: ActionUpload, | ||||
| 				Action:    ActionUpload, | ||||
| 			}, | ||||
| 			{ | ||||
| 				Name:      "login", | ||||
| 				Usage:     "Login to gpaste server", | ||||
| 				ArgsUsage: "USERNAME", | ||||
| 				Action:    ActionLogin, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| @@ -105,3 +112,71 @@ func ActionUpload(c *cli.Context) error { | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func ActionLogin(c *cli.Context) error { | ||||
| 	username := c.Args().First() | ||||
| 	if username == "" { | ||||
| 		return cli.Exit("USERNAME not supplied.", 1) | ||||
| 	} | ||||
| 	password, err := readPassword() | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error reading password: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	url := fmt.Sprintf("%s/api/login", c.String("url")) | ||||
| 	client := &http.Client{} | ||||
| 	// TODO: Change timeout | ||||
| 	ctx, cancel := context.WithTimeout(c.Context, 10*time.Second) | ||||
| 	defer cancel() | ||||
|  | ||||
| 	body := new(bytes.Buffer) | ||||
| 	requestData := struct { | ||||
| 		Username string `json:"username"` | ||||
| 		Password string `json:"password"` | ||||
| 	}{ | ||||
| 		Username: username, | ||||
| 		Password: password, | ||||
| 	} | ||||
| 	encoder := json.NewEncoder(body) | ||||
| 	if err := encoder.Encode(&requestData); err != nil { | ||||
| 		return fmt.Errorf("error encoding response: %w", err) | ||||
| 	} | ||||
| 	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, body) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error creating request: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	resp, err := client.Do(req) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("unable to perform request: %s", err) | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	if resp.StatusCode != http.StatusOK { | ||||
| 		return cli.Exit("got non-ok response from server", 0) | ||||
| 	} | ||||
|  | ||||
| 	responseData := struct { | ||||
| 		Token string `json:"token"` | ||||
| 	}{} | ||||
|  | ||||
| 	decoder := json.NewDecoder(resp.Body) | ||||
| 	if err := decoder.Decode(&responseData); err != nil { | ||||
| 		return fmt.Errorf("unable to parse response: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	fmt.Printf("Token: %s", responseData.Token) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func readPassword() (string, error) { | ||||
| 	fmt.Print("Enter Password: ") | ||||
| 	bytePassword, err := term.ReadPassword(int(syscall.Stdin)) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	password := string(bytePassword) | ||||
| 	return strings.TrimSpace(password), nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @@ -14,6 +14,7 @@ require ( | ||||
| 	go.etcd.io/bbolt v1.3.6 | ||||
| 	go.uber.org/zap v1.20.0 | ||||
| 	golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce | ||||
| 	golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 | ||||
| ) | ||||
|  | ||||
| require ( | ||||
|   | ||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							| @@ -71,6 +71,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc | ||||
| golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= | ||||
| golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= | ||||
| golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
|   | ||||
							
								
								
									
										8
									
								
								http.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								http.go
									
									
									
									
									
								
							| @@ -32,6 +32,12 @@ func NewHTTPServer(cfg *ServerConfig) *HTTPServer { | ||||
| 	srv.Users = NewMemoryUserStore() | ||||
| 	srv.Auth = NewAuthService(srv.Users, []byte(srv.config.SigningSecret)) | ||||
|  | ||||
| 	// Create initial user | ||||
| 	// TODO: Do properly | ||||
| 	user := &User{Username: "admin"} | ||||
| 	user.SetPassword("admin") | ||||
| 	srv.Users.Store(user) | ||||
|  | ||||
| 	r := chi.NewRouter() | ||||
| 	r.Use(middleware.RealIP) | ||||
| 	r.Use(middleware.RequestID) | ||||
| @@ -174,6 +180,8 @@ func (s *HTTPServer) HandlerAPILogin(w http.ResponseWriter, r *http.Request) { | ||||
| 		Token: token, | ||||
| 	} | ||||
|  | ||||
| 	s.Logger.Infow("User logged in.", "req_id", reqID, "username", expectedRequest.Username) | ||||
|  | ||||
| 	encoder := json.NewEncoder(w) | ||||
| 	if err := encoder.Encode(&response); err != nil { | ||||
| 		s.Logger.Infow("Error encoding json response to client.", "req_id", reqID, "error", err, "remote_addr", r.RemoteAddr) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user