Skip to content
Snippets Groups Projects
Select Git revision
  • 8527dd124b44fb5edb9d5b2c1fdfd54aa9a7e8d3
  • release default protected
  • more-testing
  • attempt-vax90b1
  • attempt-1
  • conversion protected
  • linux
  • v0.9.1 protected
  • v0.9.0 protected
9 results

accounts.go

Blame
  • accounts.go 10.28 KiB
    package repl
    
    import (
    	"errors"
    	"fmt"
    	"strings"
    
    	"git.lyda.ie/kevin/bulletin/ask"
    	"git.lyda.ie/kevin/bulletin/dclish"
    	"git.lyda.ie/kevin/bulletin/key"
    	"git.lyda.ie/kevin/bulletin/storage"
    	"git.lyda.ie/kevin/bulletin/this"
    	"git.lyda.ie/kevin/bulletin/users"
    )
    
    // ActionUser handles the USER command - it prints out help for all the
    // USER subcommands.  This is new to the Go version of BULLETIN.
    func ActionUser(cmd *dclish.Command) error {
    	fmt.Println(cmd.Description)
    	return nil
    }
    
    // ActionUserAdd handles the `USER ADD` command.  This is used to add a
    // new user.  This is new to the Go version of BULLETIN.
    func ActionUserAdd(cmd *dclish.Command) error {
    	ctx := storage.Context()
    	login := strings.ToUpper(cmd.Args[0])
    	u, err := users.ValidExistingLogin(this.Q, login)
    	if err != nil {
    		fmt.Printf("ERROR: %s.\n", err)
    		return nil
    	}
    	if u.Login != "" {
    		fmt.Println("ERROR: User already exists.")
    		return nil
    	}
    	u, err = this.Q.AddUser(ctx, storage.AddUserParams{
    		Login: login,
    		Name:  cmd.Args[1],
    	})
    	if err != nil {
    		fmt.Printf("ERROR: %s.\n", err)
    		return nil
    	}
    	if u.Login == "" {
    		fmt.Println("ERROR: Failed to make user; unknown reason.")
    		return nil
    	}
    	return nil
    }
    
    // ActionUserList handles the `USER LIST` command.  This lists all the
    // users.  For now this is limited to only the admin users.
    //
    // This is new to the Go version of BULLETIN.
    func ActionUserList(_ *dclish.Command) error {
    	if this.User.Admin == 0 {
    		fmt.Println("ERROR: You are not an admin.")
    		return nil
    	}
    	ctx := storage.Context()
    	userlist, err := this.Q.ListUsers(ctx)
    	if err != nil {
    		fmt.Printf("ERROR: Failed to list users (%s).\n", err)
    		return nil
    	}
    	for _, u := range userlist {
    		fmt.Printf("%s\n", u)
    	}
    	return nil
    }
    
    // ActionUserDelete handles the `USER DELETE` command.  This will delete
    // the named user.  Only the admin can use this command.
    //
    // This is new to the Go version of BULLETIN.
    func ActionUserDelete(cmd *dclish.Command) error {
    	if this.User.Admin == 0 {
    		fmt.Println("ERROR: You are not an admin.")
    		return nil
    	}
    	u, err := users.ValidExistingLogin(this.Q, cmd.Args[0])
    	if err != nil || u.Login == "" {
    		fmt.Println("ERROR: User not found.")
    		return nil
    	}
    	ctx := storage.Context()
    	err = this.Q.DeleteUser(ctx, u.Login)
    	if err != nil {
    		fmt.Printf("ERROR: Failed to delete user (%s).\n", err)
    		return nil
    	}
    	fmt.Println("User deleted.")
    	return nil
    }
    
    func actionUserEnable(cmd *dclish.Command, disabled int64, doing string) error {
    	if this.User.Admin == 0 {
    		fmt.Println("ERROR: You are not an admin.")
    		return nil
    	}
    	u, err := users.ValidExistingLogin(this.Q, cmd.Args[0])
    	if err != nil || u.Login == "" {
    		fmt.Println("ERROR: User not found.")
    		return nil
    	}
    	if u.Disabled == disabled {
    		fmt.Printf("User already %sd.\n", doing)
    		return nil
    	}
    	ctx := storage.Context()
    	err = this.Q.UpdateUserDisabled(ctx, disabled, u.Login)
    	if err != nil {
    		fmt.Printf("ERROR: Failed to %s user (%s).\n", doing, err)
    		return nil
    	}
    	fmt.Printf("User %sd.\n", doing)
    	return nil
    }
    
    // ActionUserEnable handles the `USER ENABLE` command.  This enables
    // a user.  Only the admin can use this command.
    //
    // This is new to the Go version of BULLETIN.
    func ActionUserEnable(cmd *dclish.Command) error {
    	return actionUserEnable(cmd, 0, "enable")
    }
    
    // ActionUserDisable handles the `USER DISABLE` command.  This disables
    // a user.  Only the admin can use this command.
    //
    // This is new to the Go version of BULLETIN.
    func ActionUserDisable(cmd *dclish.Command) error {
    	return actionUserEnable(cmd, 1, "disable")
    }
    
    func actionUserAdmin(cmd *dclish.Command, admin int64, doing string) error {
    	if this.User.Admin == 0 {
    		fmt.Println("ERROR: You are not an admin.")
    		return nil
    	}
    	u, err := users.ValidExistingLogin(this.Q, cmd.Args[0])
    	if err != nil || u.Login == "" {
    		return errors.New("User not found")
    	}
    	if u.Login == this.User.Login || u.Login == "SYSTEM" {
    		return errors.New("Invalid user given")
    	}
    	if u.Admin == admin {
    		fmt.Printf("User is already %s.\n", doing)
    		return nil
    	}
    	ctx := storage.Context()
    	err = this.Q.UpdateUserAdmin(ctx, admin, u.Login)
    	if err != nil {
    		return fmt.Errorf("Failed to make user %s (%s)", doing, err)
    	}
    	fmt.Printf("User is now %s.\n", doing)
    	return nil
    }
    
    // ActionUserAdmin handles the `USER ADMIN` command.  This makes the given
    // user an admin.  Only the admin can use this command.
    //
    // This is new to the Go version of BULLETIN.
    func ActionUserAdmin(cmd *dclish.Command) error {
    	return actionUserAdmin(cmd, 1, "an admin")
    }
    
    // ActionUserNoadmin handles the `USER NOADMIN` command.  This removes the
    // admin bit from a given user.  Only the admin can use this command.
    //
    // This is new to the Go version of BULLETIN.
    func ActionUserNoadmin(cmd *dclish.Command) error {
    	return actionUserAdmin(cmd, 0, "not an admin")
    }
    
    func actionUserMod(cmd *dclish.Command, mod int64, doing string) error {
    	if this.User.Admin == 0 {
    		fmt.Println("ERROR: You are not an admin.")
    		return nil
    	}
    	u, err := users.ValidExistingLogin(this.Q, cmd.Args[0])
    	if err != nil || u.Login == "" {
    		fmt.Println("ERROR: User not found.")
    		return nil
    	}
    	if u.Moderator == mod {
    		fmt.Printf("User is already %s.\n", doing)
    		return nil
    	}
    	ctx := storage.Context()
    	err = this.Q.UpdateUserMod(ctx, mod, u.Login)
    	if err != nil {
    		fmt.Printf("ERROR: Failed to make user %s (%s).\n", doing, err)
    		return nil
    	}
    	fmt.Printf("User is now %s.\n", doing)
    	return nil
    }
    
    // ActionUserMod handles the `USER MOD` command.  Makes given the user a
    // moderator.  Only the admin can use this command.
    //
    // This is new to the Go version of BULLETIN.
    func ActionUserMod(cmd *dclish.Command) error {
    	return actionUserMod(cmd, 1, "a moderator")
    }
    
    // ActionUserNomod handles the `USER NOMOD` command.  Removes the
    // moderator bit from the given user.  Only the admin can use this command.
    //
    // This is new to the Go version of BULLETIN.
    func ActionUserNomod(cmd *dclish.Command) error {
    	return actionUserMod(cmd, 0, "not a moderator")
    }
    
    // ActionUserName handles the `USER NAME` command. Updates the user's
    // name.  Only the admin can use the two argument version of this command.
    //
    // This is new to the Go version of BULLETIN.
    func ActionUserName(cmd *dclish.Command) error {
    	if len(cmd.Args) == 2 && this.User.Admin == 0 {
    		fmt.Println("ERROR: You are not an admin.")
    		return nil
    	}
    	login := this.User.Login
    	name := cmd.Args[0]
    	if len(cmd.Args) == 2 {
    		login = strings.ToUpper(cmd.Args[0])
    		name = cmd.Args[1]
    		_, err := users.ValidExistingLogin(this.Q, login)
    		if err != nil {
    			fmt.Printf("ERROR: %s.\n", err)
    			return nil
    		}
    	}
    	ctx := storage.Context()
    	err := this.Q.UpdateUserName(ctx, name, login)
    	if err != nil {
    		fmt.Printf("ERROR: Failed to update user name (%s).\n", err)
    	}
    	return nil
    }
    
    // ActionSSH handles the `SSH` command.  This prints the help for all the
    // SSH commands.  These are used to manage the authorized_keys file.
    // These are new to the Go version of BULLETIN.
    func ActionSSH(cmd *dclish.Command) error {
    	fmt.Println(cmd.Description)
    	return nil
    }
    
    // ActionSSHAdd handles the `SSH ADD` command.  This adds a given ssh key
    // to the authorized_keys file for the given user.  An admin can add
    // a new public key for another user.
    //
    // This is new to the Go version of BULLETIN.
    func ActionSSHAdd(cmd *dclish.Command) error {
    	if this.User.Admin == 0 && len(cmd.Args) == 1 {
    		fmt.Println("ERROR: You are not an admin.")
    		return nil
    	}
    	login := this.User.Login
    	if len(cmd.Args) == 1 {
    		login = cmd.Args[0]
    	}
    	u, err := users.ValidExistingLogin(this.Q, login)
    	if err != nil || u.Login == "" {
    		fmt.Println("ERROR: User not found.")
    		return nil
    	}
    	sshkey, err := ask.GetLine("Enter ssh public key: ")
    	if err != nil {
    		fmt.Printf("ERROR: Failed to read ssh key (%s).\n", err)
    		return nil
    	}
    	key.Add(u.Login, sshkey)
    	fmt.Println("Key is added.")
    	return nil
    }
    
    // ActionSSHList handles the `SSH LIST` command.  This lists all the
    // public keys for this user.  An admin can list public keys for another
    // user.
    //
    // This is new to the Go version of BULLETIN.
    func ActionSSHList(cmd *dclish.Command) error {
    	if this.User.Admin == 0 && len(cmd.Args) == 1 {
    		fmt.Println("ERROR: You are not an admin.")
    		return nil
    	}
    	login := this.User.Login
    	if len(cmd.Args) == 1 {
    		login = cmd.Args[0]
    	}
    	u, err := users.ValidExistingLogin(this.Q, login)
    	if err != nil || u.Login == "" {
    		fmt.Println("ERROR: User not found.")
    		return nil
    	}
    	keys, err := key.List(login)
    	if err != nil {
    		fmt.Printf("ERROR: Problem listing keys (%s).\n", err)
    		return nil
    	}
    	fmt.Printf("The %d keys:\n  %s\n", len(keys), strings.Join(keys, "\n  "))
    	return nil
    }
    
    // ActionSSHDelete handles the `SSH DELETE` command.  Removes ssh public
    // keys for a user.  And admin can specify a different user to remove
    // public keys for.
    //
    // This is new to the Go version of BULLETIN.
    func ActionSSHDelete(cmd *dclish.Command) error {
    	if this.User.Admin == 0 && len(cmd.Args) == 1 {
    		fmt.Println("ERROR: You are not an admin.")
    		return nil
    	}
    	login := this.User.Login
    	if len(cmd.Args) == 1 {
    		login = cmd.Args[0]
    	}
    	u, err := users.ValidExistingLogin(this.Q, login)
    	if err != nil || u.Login == "" {
    		fmt.Println("ERROR: User not found.")
    		return nil
    	}
    	keys, err := key.List(login)
    	if err != nil {
    		fmt.Printf("ERROR: Problem listing keys (%s).\n", err)
    		return nil
    	}
    	if len(keys) == 0 {
    		fmt.Println("No keys to delete.")
    		return nil
    	}
    	choice, err := ask.Choose("Choose a key to delete:", keys)
    	if err != nil {
    		fmt.Printf("ERROR: Problem choosing key (%s).\n", err)
    		return nil
    	}
    	if choice < 0 {
    		fmt.Println("Aborted.")
    		return nil
    	}
    	err = key.Delete(keys[choice])
    	if err != nil {
    		fmt.Printf("ERROR: Problem deleting key (%s).\n", err)
    		return nil
    	}
    	fmt.Println("Key deleted.")
    	return nil
    }
    
    // ActionSSHFetch handles the `SSH FETCH` command.  This command pulls
    // public keys from code sites.  It's the quickest way to
    // add a number of keys for a user.  An admin can do this
    // for another user.
    //
    // This is new to the Go version of BULLETIN.
    func ActionSSHFetch(cmd *dclish.Command) error {
    	login := this.User.Login
    	sitename := cmd.Args[0]
    	username := cmd.Args[1]
    	if len(cmd.Args) == 3 && this.User.Admin == 0 {
    		fmt.Println("ERROR: You are not an admin.")
    		return nil
    	}
    	if len(cmd.Args) == 3 {
    		login = cmd.Args[0]
    		sitename = cmd.Args[1]
    		username = cmd.Args[2]
    	}
    	fmt.Print(key.Fetch(login, sitename, username))
    	return nil
    }