]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/transaction_handlers.go
Implement "Can use any name" permission
[rbdr/mobius] / hotline / transaction_handlers.go
index 26eee12ef38a47931be98d034389f8269e48a50f..6389ed21de7b8507872a3a643307e52cb9d49dd9 100644 (file)
@@ -634,7 +634,7 @@ func HandleSetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error
        if err != nil {
                return res, err
        }
-       if err := os.WriteFile(cc.Server.ConfigDir+"Users/"+login+".yaml", out, 0666); err != nil {
+       if err := os.WriteFile(filepath.Join(cc.Server.ConfigDir, "Users", login+".yaml"), out, 0666); err != nil {
                return res, err
        }
 
@@ -698,8 +698,13 @@ func HandleListUsers(cc *ClientConn, t *Transaction) (res []Transaction, err err
 
        var userFields []Field
        for _, acc := range cc.Server.Accounts {
-               userField := acc.MarshalBinary()
-               userFields = append(userFields, NewField(fieldData, userField))
+               b := make([]byte, 0, 100)
+               n, err := acc.Read(b)
+               if err != nil {
+                       return res, err
+               }
+
+               userFields = append(userFields, NewField(fieldData, b[:n]))
        }
 
        res = append(res, cc.NewReply(t, userFields...))
@@ -903,7 +908,15 @@ func HandleGetUserNameList(cc *ClientConn, t *Transaction) (res []Transaction, e
 
 func HandleTranAgreed(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
        cc.Agreed = true
-       cc.UserName = t.GetField(fieldUserName).Data
+
+       if t.GetField(fieldUserName).Data != nil {
+               if cc.Authorize(accessAnyName) {
+                       cc.UserName = t.GetField(fieldUserName).Data
+               } else {
+                       cc.UserName = []byte(cc.Account.Name)
+               }
+       }
+
        *cc.Icon = t.GetField(fieldUserIconID).Data
 
        cc.logger = cc.logger.With("name", string(cc.UserName))
@@ -933,7 +946,7 @@ func HandleTranAgreed(cc *ClientConn, t *Transaction) (res []Transaction, err er
                cc.AutoReply = []byte{}
        }
 
-       for _, t := range cc.notifyOthers(
+       trans := cc.notifyOthers(
                *NewTransaction(
                        tranNotifyChangeUser, nil,
                        NewField(fieldUserName, cc.UserName),
@@ -941,12 +954,11 @@ func HandleTranAgreed(cc *ClientConn, t *Transaction) (res []Transaction, err er
                        NewField(fieldUserIconID, *cc.Icon),
                        NewField(fieldUserFlags, *cc.Flags),
                ),
-       ) {
-               cc.Server.outbox <- t
-       }
+       )
+       res = append(res, trans...)
 
        if cc.Server.Config.BannerFile != "" {
-               cc.Server.outbox <- *NewTransaction(tranServerBanner, cc.ID, NewField(fieldBannerType, []byte("JPEG")))
+               res = append(res, *NewTransaction(tranServerBanner, cc.ID, NewField(fieldBannerType, []byte("JPEG"))))
        }
 
        res = append(res, cc.NewReply(t))
@@ -1019,12 +1031,48 @@ func HandleDisconnectUser(cc *ClientConn, t *Transaction) (res []Transaction, er
                return res, err
        }
 
-       if err := clientConn.Connection.Close(); err != nil {
-               return res, err
+       // If fieldOptions is set, then the client IP is banned in addition to disconnected.
+       // 00 01 = temporary ban
+       // 00 02 = permanent ban
+       if t.GetField(fieldOptions).Data != nil {
+               switch t.GetField(fieldOptions).Data[1] {
+               case 1:
+                       // send message: "You are temporarily banned on this server"
+                       cc.logger.Infow("Disconnect & temporarily ban " + string(clientConn.UserName))
+
+                       res = append(res, *NewTransaction(
+                               tranServerMsg,
+                               clientConn.ID,
+                               NewField(fieldData, []byte("You are temporarily banned on this server")),
+                               NewField(fieldChatOptions, []byte{0, 0}),
+                       ))
+
+                       banUntil := time.Now().Add(tempBanDuration)
+                       cc.Server.banList[strings.Split(clientConn.RemoteAddr, ":")[0]] = &banUntil
+                       cc.Server.writeBanList()
+               case 2:
+                       // send message: "You are permanently banned on this server"
+                       cc.logger.Infow("Disconnect & ban " + string(clientConn.UserName))
+
+                       res = append(res, *NewTransaction(
+                               tranServerMsg,
+                               clientConn.ID,
+                               NewField(fieldData, []byte("You are permanently banned on this server")),
+                               NewField(fieldChatOptions, []byte{0, 0}),
+                       ))
+
+                       cc.Server.banList[strings.Split(clientConn.RemoteAddr, ":")[0]] = nil
+                       cc.Server.writeBanList()
+               }
        }
 
-       res = append(res, cc.NewReply(t))
-       return res, err
+       // TODO: remove this awful hack
+       go func() {
+               time.Sleep(1 * time.Second)
+               clientConn.Disconnect()
+       }()
+
+       return append(res, cc.NewReply(t)), err
 }
 
 // HandleGetNewsCatNameList returns a list of news categories for a path