package app import ( "context" "errors" "flag" "fmt" "net/http" "os" "os/exec" "strings" "time" ) func cliRegister(args []string) error { fs := flag.NewFlagSet("register", flag.ExitOnError) server := fs.String("server", envServer(), "server URL") if err := fs.Parse(args); err != nil { return err } email := prompt("Email: ") username := prompt("Username: ") password := prompt("Password: ") var out User if err := apiRequest(context.Background(), *server, http.MethodPost, "/api/register", "", map[string]string{"email": email, "username": username, "password": password}, &out); err != nil { return err } fmt.Printf("Registered %s <%s>\n", out.Username, out.Email) if out.IsAdmin { fmt.Println("This is the first user, so it is an admin account.") } return nil } func cliLogin(args []string) error { fs := flag.NewFlagSet("login", flag.ExitOnError) server := fs.String("server", envServer(), "server URL") if err := fs.Parse(args); err != nil { return err } login := prompt("Email or username: ") password := prompt("Password: ") var out struct { User User `json:"user"` Token string `json:"token"` ExpiresAt time.Time `json:"expires_at"` } if err := apiRequest(context.Background(), *server, http.MethodPost, "/api/login", "", map[string]string{"login": login, "password": password}, &out); err != nil { return err } cfg := Config{Server: strings.TrimRight(*server, "/"), Username: out.User.Username, Token: out.Token, ExpiresAt: out.ExpiresAt} if err := saveConfig(cfg); err != nil { return err } approveGitCredential(cfg) fmt.Printf("logged in as %s; token expires %s\n", cfg.Username, cfg.ExpiresAt.Format(time.RFC3339)) return nil } func cliLogout(args []string) error { cfg, err := loadConfig() if err != nil { return err } _ = apiRequest(context.Background(), cfg.Server, http.MethodPost, "/api/logout", cfg.Token, nil, nil) _ = os.Remove(configPath()) fmt.Println("logged out") return nil } func cliWhoami(args []string) error { cfg, err := loadConfig() if err != nil { return err } var user User if err := apiRequest(context.Background(), cfg.Server, http.MethodGet, "/api/me", cfg.Token, nil, &user); err != nil { return err } fmt.Printf("Username: %s\n", user.Username) fmt.Printf("Email: %s\n", user.Email) fmt.Printf("Admin: %v\n", user.IsAdmin) return nil } func cliClone(args []string) error { if len(args) != 1 { return errors.New("usage: gitocean clone OWNER/REPO") } server := envServer() if cfg, err := loadConfig(); err == nil && cfg.Server != "" { server = cfg.Server } owner, repo, err := splitOwnerRepo(args[0]) if err != nil { return err } remote := fmt.Sprintf("%s/%s/%s.git", strings.TrimRight(server, "/"), owner, repo) cmd := exec.Command("git", "clone", remote) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin return cmd.Run() }