Changeset 329 in code for trunk


Ignore:
Timestamp:
Jun 8, 2020, 8:30:09 PM (5 years ago)
Author:
delthas
Message:

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.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/soju.1.scd

    r323 r329  
    139139                is used.
    140140
     141*network delete* <name>
     142        Disconnect and delete a network.
     143
     144*network status*
     145        Show a list of saved networks and their current status.
     146
    141147*certfp generate* *[options...]* <network name>
    142148        Generate self-signed certificate and use it for authentication.
     
    160166        Disable SASL EXTERNAL authentication and remove stored certificate.
    161167
     168*user create* -username <username> -password <password> [-admin]
     169    Create a new soju user. Only admin users can create new accounts.
     170
    162171*change-password* <new password>
    163172        Change current user password.
    164 
    165 *network delete* <name>
    166         Disconnect and delete a network.
    167 
    168 *network status*
    169         Show a list of saved networks and their current status.
    170173
    171174# AUTHORS
  • trunk/server.go

    r323 r329  
    8989}
    9090
     91func (s *Server) createUser(user *User) (*user, error) {
     92        s.lock.Lock()
     93        defer s.lock.Unlock()
     94
     95        if _, ok := s.users[user.Username]; ok {
     96                return nil, fmt.Errorf("user %q already exists", user.Username)
     97        }
     98
     99        err := s.db.StoreUser(user)
     100        if err != nil {
     101                return nil, fmt.Errorf("could not create user in db: %v", err)
     102        }
     103
     104        s.Logger.Printf("starting bouncer for new user %q", user.Username)
     105        u := newUser(s, user)
     106        s.users[u.Username] = u
     107        go u.run()
     108        return u, nil
     109}
     110
    91111func (s *Server) getUser(name string) *user {
    92112        s.lock.Lock()
  • trunk/service.go

    r328 r329  
    163163                        },
    164164                },
     165                "user": {
     166                        children: serviceCommandSet{
     167                                "create": {
     168                                        usage:  "-username <username> -password <password> [-admin]",
     169                                        desc:   "create a new soju user",
     170                                        handle: handleUserCreate,
     171                                        admin:  true,
     172                                },
     173                        },
     174                        admin: true,
     175                },
    165176                "change-password": {
    166177                        usage:  "<new password>",
     
    568579        return nil
    569580}
     581
     582func handleUserCreate(dc *downstreamConn, params []string) error {
     583        fs := newFlagSet()
     584        username := fs.String("username", "", "")
     585        password := fs.String("password", "", "")
     586        admin := fs.Bool("admin", false, "")
     587
     588        if err := fs.Parse(params); err != nil {
     589                return err
     590        }
     591        if *username == "" {
     592                return fmt.Errorf("flag -username is required")
     593        }
     594        if *password == "" {
     595                return fmt.Errorf("flag -password is required")
     596        }
     597
     598        hashed, err := bcrypt.GenerateFromPassword([]byte(*password), bcrypt.DefaultCost)
     599        if err != nil {
     600                return fmt.Errorf("failed to hash password: %v", err)
     601        }
     602
     603        user := &User{
     604                Username: *username,
     605                Password: string(hashed),
     606                Admin:    *admin,
     607        }
     608        if _, err := dc.srv.createUser(user); err != nil {
     609                return fmt.Errorf("could not create user: %v", err)
     610        }
     611
     612        sendServicePRIVMSG(dc, fmt.Sprintf("created user %q", *username))
     613        return nil
     614}
Note: See TracChangeset for help on using the changeset viewer.