Add some user related commands
This commit is contained in:
parent
d5a297cb86
commit
83a2d2a31f
8 changed files with 223 additions and 11 deletions
|
@ -1,13 +1,13 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.ctrlz.es/mgdelacroix/craban/services/store"
|
"git.ctrlz.es/mgdelacroix/craban/app"
|
||||||
)
|
)
|
||||||
|
|
||||||
type API struct {
|
type API struct {
|
||||||
store *store.Store
|
App *app.App
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAPI(store *store.Store) (*API, error) {
|
func NewAPI(app *app.App) *API {
|
||||||
return &API{store: store}, nil
|
return &API{App: app}
|
||||||
}
|
}
|
||||||
|
|
18
server/app/app.go
Normal file
18
server/app/app.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.ctrlz.es/mgdelacroix/craban/model"
|
||||||
|
"git.ctrlz.es/mgdelacroix/craban/services/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
type App struct {
|
||||||
|
config *model.Config
|
||||||
|
store *store.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApp(config *model.Config, store *store.Store) *App {
|
||||||
|
return &App{
|
||||||
|
config: config,
|
||||||
|
store: store,
|
||||||
|
}
|
||||||
|
}
|
36
server/app/user.go
Normal file
36
server/app/user.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.ctrlz.es/mgdelacroix/craban/model"
|
||||||
|
"git.ctrlz.es/mgdelacroix/craban/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *App) CreateUser(username, password, name, mail string) (*model.User, error) {
|
||||||
|
hashedPassword, err := utils.Encrypt(password)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot create user: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newUser := &model.User{
|
||||||
|
Username: username,
|
||||||
|
Password: hashedPassword,
|
||||||
|
Name: name,
|
||||||
|
Mail: mail,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := newUser.IsValid(); err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid user for creation: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.store.User().Create(newUser)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *App) ListUsers() ([]*model.User, error) {
|
||||||
|
return a.store.User().List()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *App) DeleteUserByUsername(username string) error {
|
||||||
|
return a.store.User().DeleteByUsername(username)
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ func RootCmd() *cobra.Command {
|
||||||
|
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
ServeCmd(),
|
ServeCmd(),
|
||||||
|
UserCmd(),
|
||||||
)
|
)
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|
|
@ -14,14 +14,15 @@ func ServeCmd() *cobra.Command {
|
||||||
return &cobra.Command{
|
return &cobra.Command{
|
||||||
Use: "serve",
|
Use: "serve",
|
||||||
Short: "Starts the craban server",
|
Short: "Starts the craban server",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
Run: serveCmdF,
|
Run: serveCmdF,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveCmdF(cmd *cobra.Command, _ []string) {
|
func serveCmdF(cmd *cobra.Command, _ []string) {
|
||||||
configPath, _ := cmd.Flags().GetString("config")
|
config, _ := cmd.Flags().GetString("config")
|
||||||
|
|
||||||
srv, err := server.NewServerWithConfigPath(configPath)
|
srv, err := server.NewServerWithConfigPath(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("cannot create server")
|
log.Error().Err(err).Msg("cannot create server")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
123
server/cmd/craban/commands/user.go
Normal file
123
server/cmd/craban/commands/user.go
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.ctrlz.es/mgdelacroix/craban/server"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UserCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "user",
|
||||||
|
Short: "User related commands",
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(
|
||||||
|
CreateUserCmd(),
|
||||||
|
ListUserCmd(),
|
||||||
|
DeleteUserCmd(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateUserCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "create",
|
||||||
|
Short: "Create a new user",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: createUserCmdF,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().StringP("username", "u", "", "the username of the new user")
|
||||||
|
cmd.MarkFlagRequired("username")
|
||||||
|
cmd.Flags().StringP("password", "p", "", "the password of the new user")
|
||||||
|
cmd.MarkFlagRequired("password")
|
||||||
|
cmd.Flags().StringP("name", "n", "", "the name of the new user")
|
||||||
|
cmd.MarkFlagRequired("name")
|
||||||
|
cmd.Flags().StringP("mail", "m", "", "the mail of the new user")
|
||||||
|
cmd.MarkFlagRequired("mail")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListUserCmd() *cobra.Command {
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "list",
|
||||||
|
Short: "List the users in the system",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: listUserCmdF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteUserCmd() *cobra.Command {
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "delete <username>",
|
||||||
|
Short: "Delete a user by username",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: deleteUserCmdF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createUserCmdF(cmd *cobra.Command, _ []string) {
|
||||||
|
username, _ := cmd.Flags().GetString("username")
|
||||||
|
password, _ := cmd.Flags().GetString("password")
|
||||||
|
name, _ := cmd.Flags().GetString("name")
|
||||||
|
mail, _ := cmd.Flags().GetString("mail")
|
||||||
|
|
||||||
|
config, _ := cmd.Flags().GetString("config")
|
||||||
|
srv, err := server.NewServerWithConfigPath(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("cannot create server")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer srv.Store.Close()
|
||||||
|
|
||||||
|
user, err := srv.App.CreateUser(username, password, name, mail)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("user couldn't be created")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info().Str("username", user.Username).Msg("user successfully created")
|
||||||
|
}
|
||||||
|
|
||||||
|
func listUserCmdF(cmd *cobra.Command, _ []string) {
|
||||||
|
config, _ := cmd.Flags().GetString("config")
|
||||||
|
srv, err := server.NewServerWithConfigPath(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("cannot create server")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer srv.Store.Close()
|
||||||
|
|
||||||
|
users, err := srv.App.ListUsers()
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("cannot get user list")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, user := range users {
|
||||||
|
log.Info().Str("username", user.Username).Msg("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteUserCmdF(cmd *cobra.Command, args []string) {
|
||||||
|
config, _ := cmd.Flags().GetString("config")
|
||||||
|
srv, err := server.NewServerWithConfigPath(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("cannot create server")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer srv.Store.Close()
|
||||||
|
|
||||||
|
if err := srv.App.DeleteUserByUsername(args[0]); err != nil {
|
||||||
|
log.Error().Err(err).Str("username", args[0]).Msg("cannot delete user")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info().Str("username", args[0]).Msg("user successfully deleted")
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.ctrlz.es/mgdelacroix/craban/api"
|
"git.ctrlz.es/mgdelacroix/craban/api"
|
||||||
|
"git.ctrlz.es/mgdelacroix/craban/app"
|
||||||
"git.ctrlz.es/mgdelacroix/craban/model"
|
"git.ctrlz.es/mgdelacroix/craban/model"
|
||||||
"git.ctrlz.es/mgdelacroix/craban/services/store"
|
"git.ctrlz.es/mgdelacroix/craban/services/store"
|
||||||
"git.ctrlz.es/mgdelacroix/craban/web"
|
"git.ctrlz.es/mgdelacroix/craban/web"
|
||||||
|
@ -22,6 +23,8 @@ func init() {
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Config *model.Config
|
Config *model.Config
|
||||||
|
|
||||||
|
App *app.App
|
||||||
|
API *api.API
|
||||||
Store *store.Store
|
Store *store.Store
|
||||||
WebServer *web.WebServer
|
WebServer *web.WebServer
|
||||||
}
|
}
|
||||||
|
@ -43,17 +46,18 @@ func NewServer(config *model.Config) (*Server, error) {
|
||||||
}
|
}
|
||||||
log.Debug().Msg("store created")
|
log.Debug().Msg("store created")
|
||||||
|
|
||||||
webAPI, err := api.NewAPI(store)
|
app := app.NewApp(config, store)
|
||||||
if err != nil {
|
log.Debug().Msg("app created")
|
||||||
return nil, fmt.Errorf("cannot create API: %w", err)
|
api := api.NewAPI(app)
|
||||||
}
|
|
||||||
log.Debug().Msg("API created")
|
log.Debug().Msg("API created")
|
||||||
webserver.RegisterRoutes(webAPI)
|
webserver.RegisterRoutes(api)
|
||||||
log.Debug().Msg("webserver routes registered with the API")
|
log.Debug().Msg("webserver routes registered with the API")
|
||||||
|
|
||||||
return &Server{
|
return &Server{
|
||||||
Config: config,
|
Config: config,
|
||||||
WebServer: webserver,
|
WebServer: webserver,
|
||||||
|
App: app,
|
||||||
|
API: api,
|
||||||
Store: store,
|
Store: store,
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,3 +85,32 @@ func (us *UserStore) Create(user *model.User) (*model.User, error) {
|
||||||
|
|
||||||
return us.GetByID(int(id))
|
return us.GetByID(int(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDo: add pagination and filtering
|
||||||
|
func (us *UserStore) List() ([]*model.User, error) {
|
||||||
|
rows, err := us.Q().Select(userColumns...).
|
||||||
|
From("users").
|
||||||
|
Query()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
users, err := us.usersFromRows(rows)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(users) == 0 {
|
||||||
|
return nil, sql.ErrNoRows
|
||||||
|
}
|
||||||
|
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (us *UserStore) DeleteByUsername(username string) error {
|
||||||
|
_, err := us.Q().Delete("users").
|
||||||
|
Where(sq.Eq{"username": username}).
|
||||||
|
Exec()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue