Add support for the user create admin service command
This adds support for user create, a new service command only accessible to admin users. This lets users create other users on the fly and makes soju start the user routine immediately; unlike sojuctl which currently requires closing soju, creating the user, and starting soju again.
This commit is contained in:
parent
f5611ae3f9
commit
5be25711c7
@ -138,6 +138,12 @@ abbreviated form, for instance *network* can be abbreviated as *net* or just
|
||||
Connect with the specified nickname. By default, the account's username
|
||||
is used.
|
||||
|
||||
*network delete* <name>
|
||||
Disconnect and delete a network.
|
||||
|
||||
*network status*
|
||||
Show a list of saved networks and their current status.
|
||||
|
||||
*certfp generate* *[options...]* <network name>
|
||||
Generate self-signed certificate and use it for authentication.
|
||||
|
||||
@ -159,15 +165,12 @@ abbreviated form, for instance *network* can be abbreviated as *net* or just
|
||||
*certfp reset* <network name>
|
||||
Disable SASL EXTERNAL authentication and remove stored certificate.
|
||||
|
||||
*user create* -username <username> -password <password> [-admin]
|
||||
Create a new soju user. Only admin users can create new accounts.
|
||||
|
||||
*change-password* <new password>
|
||||
Change current user password.
|
||||
|
||||
*network delete* <name>
|
||||
Disconnect and delete a network.
|
||||
|
||||
*network status*
|
||||
Show a list of saved networks and their current status.
|
||||
|
||||
# AUTHORS
|
||||
|
||||
Maintained by Simon Ser <contact@emersion.fr>, who is assisted by other
|
||||
|
20
server.go
20
server.go
@ -88,6 +88,26 @@ func (s *Server) Run() error {
|
||||
select {}
|
||||
}
|
||||
|
||||
func (s *Server) createUser(user *User) (*user, error) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if _, ok := s.users[user.Username]; ok {
|
||||
return nil, fmt.Errorf("user %q already exists", user.Username)
|
||||
}
|
||||
|
||||
err := s.db.StoreUser(user)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create user in db: %v", err)
|
||||
}
|
||||
|
||||
s.Logger.Printf("starting bouncer for new user %q", user.Username)
|
||||
u := newUser(s, user)
|
||||
s.users[u.Username] = u
|
||||
go u.run()
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (s *Server) getUser(name string) *user {
|
||||
s.lock.Lock()
|
||||
u := s.users[name]
|
||||
|
45
service.go
45
service.go
@ -162,6 +162,17 @@ func init() {
|
||||
},
|
||||
},
|
||||
},
|
||||
"user": {
|
||||
children: serviceCommandSet{
|
||||
"create": {
|
||||
usage: "-username <username> -password <password> [-admin]",
|
||||
desc: "create a new soju user",
|
||||
handle: handleUserCreate,
|
||||
admin: true,
|
||||
},
|
||||
},
|
||||
admin: true,
|
||||
},
|
||||
"change-password": {
|
||||
usage: "<new password>",
|
||||
desc: "change your password",
|
||||
@ -567,3 +578,37 @@ func handlePasswordChange(dc *downstreamConn, params []string) error {
|
||||
sendServicePRIVMSG(dc, "password updated")
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleUserCreate(dc *downstreamConn, params []string) error {
|
||||
fs := newFlagSet()
|
||||
username := fs.String("username", "", "")
|
||||
password := fs.String("password", "", "")
|
||||
admin := fs.Bool("admin", false, "")
|
||||
|
||||
if err := fs.Parse(params); err != nil {
|
||||
return err
|
||||
}
|
||||
if *username == "" {
|
||||
return fmt.Errorf("flag -username is required")
|
||||
}
|
||||
if *password == "" {
|
||||
return fmt.Errorf("flag -password is required")
|
||||
}
|
||||
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(*password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to hash password: %v", err)
|
||||
}
|
||||
|
||||
user := &User{
|
||||
Username: *username,
|
||||
Password: string(hashed),
|
||||
Admin: *admin,
|
||||
}
|
||||
if _, err := dc.srv.createUser(user); err != nil {
|
||||
return fmt.Errorf("could not create user: %v", err)
|
||||
}
|
||||
|
||||
sendServicePRIVMSG(dc, fmt.Sprintf("created user %q", *username))
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user