]> git.r.bdr.sh - rbdr/mobius/commitdiff
Refactor user access bitmap handling
authorJeff Halter <redacted>
Sun, 26 Jun 2022 22:40:18 +0000 (15:40 -0700)
committerJeff Halter <redacted>
Sun, 26 Jun 2022 22:40:18 +0000 (15:40 -0700)
hotline/access.go
hotline/access_test.go [new file with mode: 0644]
hotline/account.go
hotline/client_conn.go
hotline/server.go
hotline/transaction_handlers.go
hotline/transaction_handlers_test.go

index ae72780871c61213d3976fbf1695aff6b9ed0911..83a4e16ffcde54e98e0fd2c1a4792d2e637fe5b1 100644 (file)
@@ -1,10 +1,5 @@
 package hotline
 
-import (
-       "encoding/binary"
-       "math/big"
-)
-
 const (
        accessDeleteFile       = 0  // File System Maintenance: Can Delete Files
        accessUploadFile       = 1  // File System Maintenance: Can Upload Files
@@ -52,10 +47,6 @@ func (bits *accessBitmap) Set(i int) {
        bits[i/8] |= 1 << uint(7-i%8)
 }
 
-// authorize checks if 64 bit access slice contain has accessBit set
-// TODO: refactor to use accessBitmap type
-func authorize(access *[]byte, accessBit int) bool {
-       bits := big.NewInt(int64(binary.BigEndian.Uint64(*access)))
-
-       return bits.Bit(63-accessBit) == 1
+func (bits *accessBitmap) IsSet(i int) bool {
+       return bits[i/8]&(1<<uint(7-i%8)) != 0
 }
diff --git a/hotline/access_test.go b/hotline/access_test.go
new file mode 100644 (file)
index 0000000..b262407
--- /dev/null
@@ -0,0 +1,39 @@
+package hotline
+
+import (
+       "github.com/stretchr/testify/assert"
+       "testing"
+)
+
+func Test_accessBitmap_IsSet(t *testing.T) {
+       type args struct {
+               i int
+       }
+       tests := []struct {
+               name string
+               bits accessBitmap
+               args args
+               want bool
+       }{
+               {
+                       name: "returns true when bit is set",
+                       bits: func() (access accessBitmap) {
+                               access.Set(22)
+                               return access
+                       }(),
+                       args: args{i: 22},
+                       want: true,
+               },
+               {
+                       name: "returns false when bit is unset",
+                       bits: accessBitmap{},
+                       args: args{i: 22},
+                       want: false,
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       assert.Equalf(t, tt.want, tt.bits.IsSet(tt.args.i), "IsSet(%v)", tt.args.i)
+               })
+       }
+}
index 2c400aceafb56e28c6746f4f582d8347f69ddeab..a6808615f5fad507526b7b8b4ec3d59d52e0b9a6 100644 (file)
@@ -8,10 +8,10 @@ import (
 const GuestAccount = "guest" // default account used when no login is provided for a connection
 
 type Account struct {
-       Login    string  `yaml:"Login"`
-       Name     string  `yaml:"Name"`
-       Password string  `yaml:"Password"`
-       Access   *[]byte `yaml:"Access"` // 8 byte bitmap
+       Login    string       `yaml:"Login"`
+       Name     string       `yaml:"Name"`
+       Password string       `yaml:"Password"`
+       Access   accessBitmap `yaml:"Access"`
 }
 
 // Read implements io.Reader interface for Account
@@ -19,7 +19,7 @@ func (a *Account) Read(p []byte) (n int, err error) {
        fields := []Field{
                NewField(fieldUserName, []byte(a.Name)),
                NewField(fieldUserLogin, negateString([]byte(a.Login))),
-               NewField(fieldUserAccess, *a.Access),
+               NewField(fieldUserAccess, a.Access[:]),
        }
 
        if bcrypt.CompareHashAndPassword([]byte(a.Password), []byte("")) != nil {
index 076919fbd99f73aa9ef4543cba236d473d12ce64..7f7870442c6a9237b64f63dbc5ca66a359634c52 100644 (file)
@@ -135,9 +135,7 @@ func (cc *ClientConn) uint16ID() uint16 {
 
 // Authorize checks if the user account has the specified permission
 func (cc *ClientConn) Authorize(access int) bool {
-       i := big.NewInt(int64(binary.BigEndian.Uint64(*cc.Account.Access)))
-
-       return i.Bit(63-access) == 1
+       return cc.Account.Access.IsSet(access)
 }
 
 // Disconnect notifies other clients that a client has disconnected
index 0d66e08f1290f3adc4a54caa81b696474be8c39a..3a43c95b4aaf15e69c70a294e1905f798e842cd7 100644 (file)
@@ -392,7 +392,7 @@ func (s *Server) NewClientConn(conn io.ReadWriteCloser, remoteAddr string) *Clie
 }
 
 // NewUser creates a new user account entry in the server map and config file
-func (s *Server) NewUser(login, name, password string, access []byte) error {
+func (s *Server) NewUser(login, name, password string, access accessBitmap) error {
        s.mux.Lock()
        defer s.mux.Unlock()
 
@@ -400,7 +400,7 @@ func (s *Server) NewUser(login, name, password string, access []byte) error {
                Login:    login,
                Name:     name,
                Password: hashAndSalt([]byte(password)),
-               Access:   &access,
+               Access:   access,
        }
        out, err := yaml.Marshal(&account)
        if err != nil {
@@ -411,7 +411,7 @@ func (s *Server) NewUser(login, name, password string, access []byte) error {
        return s.FS.WriteFile(filepath.Join(s.ConfigDir, "Users", login+".yaml"), out, 0666)
 }
 
-func (s *Server) UpdateUser(login, newLogin, name, password string, access []byte) error {
+func (s *Server) UpdateUser(login, newLogin, name, password string, access accessBitmap) error {
        s.mux.Lock()
        defer s.mux.Unlock()
 
@@ -426,7 +426,7 @@ func (s *Server) UpdateUser(login, newLogin, name, password string, access []byt
        }
 
        account := s.Accounts[newLogin]
-       account.Access = &access
+       account.Access = access
        account.Name = name
        account.Password = password
 
@@ -651,7 +651,7 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
        )
 
        // Send user access privs so client UI knows how to behave
-       c.Server.outbox <- *NewTransaction(tranUserAccess, c.ID, NewField(fieldUserAccess, *c.Account.Access))
+       c.Server.outbox <- *NewTransaction(tranUserAccess, c.ID, NewField(fieldUserAccess, c.Account.Access[:]))
 
        // Accounts with accessNoAgreement do not receive the server agreement on login.  The behavior is different between
        // client versions.  For 1.2.3 client, we do not send tranShowAgreement.  For other client versions, we send
index 85879a4de1bc714c0a9d18e56e9e610bf0ad5f91..23ac68a38bb86c89a080ab70b6bb5e21b41f15fd 100644 (file)
@@ -238,7 +238,7 @@ var TransactionHandlers = map[uint16]TransactionType{
 }
 
 func HandleChatSend(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessSendChat) {
+       if !cc.Authorize(accessSendChat) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to participate in chat."))
                return res, err
        }
@@ -276,7 +276,7 @@ func HandleChatSend(cc *ClientConn, t *Transaction) (res []Transaction, err erro
 
        for _, c := range sortedClients(cc.Server.Clients) {
                // Filter out clients that do not have the read chat permission
-               if authorize(c.Account.Access, accessReadChat) {
+               if c.Authorize(accessReadChat) {
                        res = append(res, *NewTransaction(tranChatMsg, c.ID, NewField(fieldData, []byte(formattedMsg))))
                }
        }
@@ -404,12 +404,12 @@ func HandleSetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e
        if t.GetField(fieldFileComment).Data != nil {
                switch mode := fi.Mode(); {
                case mode.IsDir():
-                       if !authorize(cc.Account.Access, accessSetFolderComment) {
+                       if !cc.Authorize(accessSetFolderComment) {
                                res = append(res, cc.NewErrReply(t, "You are not allowed to set comments for folders."))
                                return res, err
                        }
                case mode.IsRegular():
-                       if !authorize(cc.Account.Access, accessSetFileComment) {
+                       if !cc.Authorize(accessSetFileComment) {
                                res = append(res, cc.NewErrReply(t, "You are not allowed to set comments for files."))
                                return res, err
                        }
@@ -438,7 +438,7 @@ func HandleSetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e
        if fileNewName != nil {
                switch mode := fi.Mode(); {
                case mode.IsDir():
-                       if !authorize(cc.Account.Access, accessRenameFolder) {
+                       if !cc.Authorize(accessRenameFolder) {
                                res = append(res, cc.NewErrReply(t, "You are not allowed to rename folders."))
                                return res, err
                        }
@@ -448,7 +448,7 @@ func HandleSetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e
                                return res, err
                        }
                case mode.IsRegular():
-                       if !authorize(cc.Account.Access, accessRenameFile) {
+                       if !cc.Authorize(accessRenameFile) {
                                res = append(res, cc.NewErrReply(t, "You are not allowed to rename files."))
                                return res, err
                        }
@@ -499,12 +499,12 @@ func HandleDeleteFile(cc *ClientConn, t *Transaction) (res []Transaction, err er
 
        switch mode := fi.Mode(); {
        case mode.IsDir():
-               if !authorize(cc.Account.Access, accessDeleteFolder) {
+               if !cc.Authorize(accessDeleteFolder) {
                        res = append(res, cc.NewErrReply(t, "You are not allowed to delete folders."))
                        return res, err
                }
        case mode.IsRegular():
-               if !authorize(cc.Account.Access, accessDeleteFile) {
+               if !cc.Authorize(accessDeleteFile) {
                        res = append(res, cc.NewErrReply(t, "You are not allowed to delete files."))
                        return res, err
                }
@@ -549,12 +549,12 @@ func HandleMoveFile(cc *ClientConn, t *Transaction) (res []Transaction, err erro
        }
        switch mode := fi.Mode(); {
        case mode.IsDir():
-               if !authorize(cc.Account.Access, accessMoveFolder) {
+               if !cc.Authorize(accessMoveFolder) {
                        res = append(res, cc.NewErrReply(t, "You are not allowed to move folders."))
                        return res, err
                }
        case mode.IsRegular():
-               if !authorize(cc.Account.Access, accessMoveFile) {
+               if !cc.Authorize(accessMoveFile) {
                        res = append(res, cc.NewErrReply(t, "You are not allowed to move files."))
                        return res, err
                }
@@ -569,7 +569,7 @@ func HandleMoveFile(cc *ClientConn, t *Transaction) (res []Transaction, err erro
 }
 
 func HandleNewFolder(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessCreateFolder) {
+       if !cc.Authorize(accessCreateFolder) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to create folders."))
                return res, err
        }
@@ -612,7 +612,7 @@ func HandleNewFolder(cc *ClientConn, t *Transaction) (res []Transaction, err err
 }
 
 func HandleSetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessModifyUser) {
+       if !cc.Authorize(accessModifyUser) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to modify accounts."))
                return res, err
        }
@@ -623,8 +623,8 @@ func HandleSetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error
        newAccessLvl := t.GetField(fieldUserAccess).Data
 
        account := cc.Server.Accounts[login]
-       account.Access = &newAccessLvl
        account.Name = userName
+       copy(account.Access[:], newAccessLvl)
 
        // If the password field is cleared in the Hotline edit user UI, the SetUser transaction does
        // not include fieldUserPassword
@@ -651,7 +651,7 @@ func HandleSetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error
                        res = append(res, *newT)
 
                        flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(c.Flags)))
-                       if authorize(c.Account.Access, accessDisconUser) {
+                       if cc.Authorize(accessDisconUser) {
                                flagBitmap.SetBit(flagBitmap, userFlagAdmin, 1)
                        } else {
                                flagBitmap.SetBit(flagBitmap, userFlagAdmin, 0)
@@ -675,7 +675,7 @@ func HandleSetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error
 }
 
 func HandleGetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessOpenUser) {
+       if !cc.Authorize(accessOpenUser) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to view accounts."))
                return res, err
        }
@@ -690,13 +690,13 @@ func HandleGetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error
                NewField(fieldUserName, []byte(account.Name)),
                NewField(fieldUserLogin, negateString(t.GetField(fieldUserLogin).Data)),
                NewField(fieldUserPassword, []byte(account.Password)),
-               NewField(fieldUserAccess, *account.Access),
+               NewField(fieldUserAccess, account.Access[:]),
        ))
        return res, err
 }
 
 func HandleListUsers(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessOpenUser) {
+       if !cc.Authorize(accessOpenUser) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to view accounts."))
                return res, err
        }
@@ -736,7 +736,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                        login := DecodeUserString(getField(fieldData, &subFields).Data)
                        cc.logger.Infow("DeleteUser", "login", login)
 
-                       if !authorize(cc.Account.Access, accessDeleteUser) {
+                       if !cc.Authorize(accessDeleteUser) {
                                res = append(res, cc.NewErrReply(t, "You are not allowed to delete accounts."))
                                return res, err
                        }
@@ -754,7 +754,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                        cc.logger.Infow("UpdateUser", "login", login)
 
                        // account dataFile, so this is an update action
-                       if !authorize(cc.Account.Access, accessModifyUser) {
+                       if !cc.Authorize(accessModifyUser) {
                                res = append(res, cc.NewErrReply(t, "You are not allowed to modify accounts."))
                                return res, err
                        }
@@ -767,7 +767,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                        }
 
                        if getField(fieldUserAccess, &subFields) != nil {
-                               acc.Access = &getField(fieldUserAccess, &subFields).Data
+                               copy(acc.Access[:], getField(fieldUserAccess, &subFields).Data)
                        }
 
                        err = cc.Server.UpdateUser(
@@ -775,7 +775,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                                DecodeUserString(getField(fieldUserLogin, &subFields).Data),
                                string(getField(fieldUserName, &subFields).Data),
                                acc.Password,
-                               *acc.Access,
+                               acc.Access,
                        )
                        if err != nil {
                                return res, err
@@ -783,17 +783,15 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                } else {
                        cc.logger.Infow("CreateUser", "login", login)
 
-                       if !authorize(cc.Account.Access, accessCreateUser) {
+                       if !cc.Authorize(accessCreateUser) {
                                res = append(res, cc.NewErrReply(t, "You are not allowed to create new accounts."))
                                return res, err
                        }
 
-                       err := cc.Server.NewUser(
-                               login,
-                               string(getField(fieldUserName, &subFields).Data),
-                               string(getField(fieldUserPassword, &subFields).Data),
-                               getField(fieldUserAccess, &subFields).Data,
-                       )
+                       newAccess := accessBitmap{}
+                       copy(newAccess[:], getField(fieldUserAccess, &subFields).Data[:])
+
+                       err := cc.Server.NewUser(login, string(getField(fieldUserName, &subFields).Data), string(getField(fieldUserPassword, &subFields).Data), newAccess)
                        if err != nil {
                                return []Transaction{}, err
                        }
@@ -806,7 +804,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
 
 // HandleNewUser creates a new user account
 func HandleNewUser(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessCreateUser) {
+       if !cc.Authorize(accessCreateUser) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to create new accounts."))
                return res, err
        }
@@ -819,12 +817,10 @@ func HandleNewUser(cc *ClientConn, t *Transaction) (res []Transaction, err error
                return res, err
        }
 
-       if err := cc.Server.NewUser(
-               login,
-               string(t.GetField(fieldUserName).Data),
-               string(t.GetField(fieldUserPassword).Data),
-               t.GetField(fieldUserAccess).Data,
-       ); err != nil {
+       newAccess := accessBitmap{}
+       copy(newAccess[:], t.GetField(fieldUserAccess).Data[:])
+
+       if err := cc.Server.NewUser(login, string(t.GetField(fieldUserName).Data), string(t.GetField(fieldUserPassword).Data), newAccess); err != nil {
                return []Transaction{}, err
        }
 
@@ -833,7 +829,7 @@ func HandleNewUser(cc *ClientConn, t *Transaction) (res []Transaction, err error
 }
 
 func HandleDeleteUser(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessDeleteUser) {
+       if !cc.Authorize(accessDeleteUser) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to delete accounts."))
                return res, err
        }
@@ -851,7 +847,7 @@ func HandleDeleteUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
 
 // HandleUserBroadcast sends an Administrator Message to all connected clients of the server
 func HandleUserBroadcast(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessBroadcast) {
+       if !cc.Authorize(accessBroadcast) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to send broadcast messages."))
                return res, err
        }
@@ -886,7 +882,7 @@ func byteToInt(bytes []byte) (int, error) {
 // 102 User name
 // 101 Data            User info text string
 func HandleGetClientInfoText(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessGetClientInfo) {
+       if !cc.Authorize(accessGetClientInfo) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to get client info."))
                return res, err
        }
@@ -984,7 +980,7 @@ __________________________________________________________`
 // Fields used in this request:
 // 101 Data
 func HandleTranOldPostNews(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessNewsPostArt) {
+       if !cc.Authorize(accessNewsPostArt) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to post news."))
                return res, err
        }
@@ -1024,14 +1020,14 @@ func HandleTranOldPostNews(cc *ClientConn, t *Transaction) (res []Transaction, e
 }
 
 func HandleDisconnectUser(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessDisconUser) {
+       if !cc.Authorize(accessDisconUser) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to disconnect users."))
                return res, err
        }
 
        clientConn := cc.Server.Clients[binary.BigEndian.Uint16(t.GetField(fieldUserID).Data)]
 
-       if authorize(clientConn.Account.Access, accessCannotBeDiscon) {
+       if clientConn.Authorize(accessCannotBeDiscon) {
                res = append(res, cc.NewErrReply(t, clientConn.Account.Login+" is not allowed to be disconnected."))
                return res, err
        }
@@ -1084,7 +1080,7 @@ func HandleDisconnectUser(cc *ClientConn, t *Transaction) (res []Transaction, er
 // Fields used in the request:
 // 325 News path       (Optional)
 func HandleGetNewsCatNameList(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessNewsReadArt) {
+       if !cc.Authorize(accessNewsReadArt) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to read news."))
                return res, err
        }
@@ -1116,7 +1112,7 @@ func HandleGetNewsCatNameList(cc *ClientConn, t *Transaction) (res []Transaction
 }
 
 func HandleNewNewsCat(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessNewsCreateCat) {
+       if !cc.Authorize(accessNewsCreateCat) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to create news categories."))
                return res, err
        }
@@ -1143,7 +1139,7 @@ func HandleNewNewsCat(cc *ClientConn, t *Transaction) (res []Transaction, err er
 // 322 News category name
 // 325 News path
 func HandleNewNewsFldr(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessNewsCreateFldr) {
+       if !cc.Authorize(accessNewsCreateFldr) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to create news folders."))
                return res, err
        }
@@ -1173,7 +1169,7 @@ func HandleNewNewsFldr(cc *ClientConn, t *Transaction) (res []Transaction, err e
 // Reply fields:
 // 321 News article list data  Optional
 func HandleGetNewsArtNameList(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessNewsReadArt) {
+       if !cc.Authorize(accessNewsReadArt) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to read news."))
                return res, err
        }
@@ -1194,7 +1190,7 @@ func HandleGetNewsArtNameList(cc *ClientConn, t *Transaction) (res []Transaction
 }
 
 func HandleGetNewsArtData(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessNewsReadArt) {
+       if !cc.Authorize(accessNewsReadArt) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to read news."))
                return res, err
        }
@@ -1281,7 +1277,7 @@ func HandleDelNewsItem(cc *ClientConn, t *Transaction) (res []Transaction, err e
 }
 
 func HandleDelNewsArt(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessNewsDeleteArt) {
+       if !cc.Authorize(accessNewsDeleteArt) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to delete news articles."))
                return res, err
        }
@@ -1318,7 +1314,7 @@ func HandleDelNewsArt(cc *ClientConn, t *Transaction) (res []Transaction, err er
 // 327 News article data flavor                Currently “text/plain”
 // 333 News article data
 func HandlePostNewsArt(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessNewsPostArt) {
+       if !cc.Authorize(accessNewsPostArt) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to post news articles."))
                return res, err
        }
@@ -1381,7 +1377,7 @@ func HandlePostNewsArt(cc *ClientConn, t *Transaction) (res []Transaction, err e
 
 // HandleGetMsgs returns the flat news data
 func HandleGetMsgs(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessNewsReadArt) {
+       if !cc.Authorize(accessNewsReadArt) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to read news."))
                return res, err
        }
@@ -1392,7 +1388,7 @@ func HandleGetMsgs(cc *ClientConn, t *Transaction) (res []Transaction, err error
 }
 
 func HandleDownloadFile(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessDownloadFile) {
+       if !cc.Authorize(accessDownloadFile) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to download files."))
                return res, err
        }
@@ -1454,7 +1450,7 @@ func HandleDownloadFile(cc *ClientConn, t *Transaction) (res []Transaction, err
 
 // Download all files from the specified folder and sub-folders
 func HandleDownloadFolder(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessDownloadFile) {
+       if !cc.Authorize(accessDownloadFile) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to download folders."))
                return res, err
        }
@@ -1506,7 +1502,7 @@ func HandleUploadFolder(cc *ClientConn, t *Transaction) (res []Transaction, err
        }
 
        // Handle special cases for Upload and Drop Box folders
-       if !authorize(cc.Account.Access, accessUploadAnywhere) {
+       if !cc.Authorize(accessUploadAnywhere) {
                if !fp.IsUploadDir() && !fp.IsDropbox() {
                        res = append(res, cc.NewErrReply(t, fmt.Sprintf("Cannot accept upload of the folder \"%v\" because you are only allowed to upload to the \"Uploads\" folder.", string(t.GetField(fieldFileName).Data))))
                        return res, err
@@ -1533,7 +1529,7 @@ func HandleUploadFolder(cc *ClientConn, t *Transaction) (res []Transaction, err
 // Used only to resume download, currently has value 2"
 // 108 File transfer size      "Optional used if download is not resumed"
 func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessUploadFile) {
+       if !cc.Authorize(accessUploadFile) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to upload files."))
                return res, err
        }
@@ -1551,7 +1547,7 @@ func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err er
        }
 
        // Handle special cases for Upload and Drop Box folders
-       if !authorize(cc.Account.Access, accessUploadAnywhere) {
+       if !cc.Authorize(accessUploadAnywhere) {
                if !fp.IsUploadDir() && !fp.IsDropbox() {
                        res = append(res, cc.NewErrReply(t, fmt.Sprintf("Cannot accept upload of the file \"%v\" because you are only allowed to upload to the \"Uploads\" folder.", string(fileName))))
                        return res, err
@@ -1668,7 +1664,7 @@ func HandleGetFileNameList(cc *ClientConn, t *Transaction) (res []Transaction, e
        }
 
        // Handle special case for drop box folders
-       if fp.IsDropbox() && !authorize(cc.Account.Access, accessViewDropBoxes) {
+       if fp.IsDropbox() && !cc.Authorize(accessViewDropBoxes) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to view drop boxes."))
                return res, err
        }
@@ -1697,7 +1693,7 @@ func HandleGetFileNameList(cc *ClientConn, t *Transaction) (res []Transaction, e
 
 // HandleInviteNewChat invites users to new private chat
 func HandleInviteNewChat(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessOpenChat) {
+       if !cc.Authorize(accessOpenChat) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to request private chat."))
                return res, err
        }
@@ -1730,7 +1726,7 @@ func HandleInviteNewChat(cc *ClientConn, t *Transaction) (res []Transaction, err
 }
 
 func HandleInviteToChat(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessOpenChat) {
+       if !cc.Authorize(accessOpenChat) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to request private chat."))
                return res, err
        }
@@ -1893,7 +1889,7 @@ func HandleSetChatSubject(cc *ClientConn, t *Transaction) (res []Transaction, er
 // Fields used in the reply:
 // None
 func HandleMakeAlias(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       if !authorize(cc.Account.Access, accessMakeAlias) {
+       if !cc.Authorize(accessMakeAlias) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to make aliases."))
                return res, err
        }
index c504bbe8f11d6e2eabb635c8caa03c91a4459331..0d6b1dc3e7595345e1ba4583a58cd626f47e5e11 100644 (file)
@@ -36,13 +36,13 @@ func TestHandleSetChatSubject(t *testing.T) {
                                                                ClientConn: map[uint16]*ClientConn{
                                                                        uint16(1): {
                                                                                Account: &Account{
-                                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                                },
                                                                                ID: &[]byte{0, 1},
                                                                        },
                                                                        uint16(2): {
                                                                                Account: &Account{
-                                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                                },
                                                                                ID: &[]byte{0, 2},
                                                                        },
@@ -52,13 +52,13 @@ func TestHandleSetChatSubject(t *testing.T) {
                                                Clients: map[uint16]*ClientConn{
                                                        uint16(1): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                },
                                                                ID: &[]byte{0, 1},
                                                        },
                                                        uint16(2): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                },
                                                                ID: &[]byte{0, 2},
                                                        },
@@ -144,13 +144,13 @@ func TestHandleLeaveChat(t *testing.T) {
                                                                ClientConn: map[uint16]*ClientConn{
                                                                        uint16(1): {
                                                                                Account: &Account{
-                                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                                },
                                                                                ID: &[]byte{0, 1},
                                                                        },
                                                                        uint16(2): {
                                                                                Account: &Account{
-                                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                                },
                                                                                ID: &[]byte{0, 2},
                                                                        },
@@ -160,13 +160,13 @@ func TestHandleLeaveChat(t *testing.T) {
                                                Clients: map[uint16]*ClientConn{
                                                        uint16(1): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                },
                                                                ID: &[]byte{0, 1},
                                                        },
                                                        uint16(2): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                },
                                                                ID: &[]byte{0, 2},
                                                        },
@@ -306,11 +306,10 @@ func TestHandleChatSend(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessSendChat)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        UserName: []byte{0x00, 0x01},
@@ -318,13 +317,13 @@ func TestHandleChatSend(t *testing.T) {
                                                Clients: map[uint16]*ClientConn{
                                                        uint16(1): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                },
                                                                ID: &[]byte{0, 1},
                                                        },
                                                        uint16(2): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                },
                                                                ID: &[]byte{0, 2},
                                                        },
@@ -368,10 +367,9 @@ func TestHandleChatSend(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -402,11 +400,10 @@ func TestHandleChatSend(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessSendChat)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        UserName: []byte("Testy McTest"),
@@ -414,13 +411,13 @@ func TestHandleChatSend(t *testing.T) {
                                                Clients: map[uint16]*ClientConn{
                                                        uint16(1): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                },
                                                                ID: &[]byte{0, 1},
                                                        },
                                                        uint16(2): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                },
                                                                ID: &[]byte{0, 2},
                                                        },
@@ -465,11 +462,10 @@ func TestHandleChatSend(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessSendChat)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        UserName: []byte{0x00, 0x01},
@@ -477,13 +473,16 @@ func TestHandleChatSend(t *testing.T) {
                                                Clients: map[uint16]*ClientConn{
                                                        uint16(1): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
-                                                               },
+                                                                       Access: func() accessBitmap {
+                                                                               var bits accessBitmap
+                                                                               bits.Set(accessReadChat)
+                                                                               return bits
+                                                                       }()},
                                                                ID: &[]byte{0, 1},
                                                        },
                                                        uint16(2): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{0, 0, 0, 0, 0, 0, 0, 0},
+                                                                       Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
                                                                },
                                                                ID: &[]byte{0, 2},
                                                        },
@@ -516,11 +515,10 @@ func TestHandleChatSend(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessSendChat)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        UserName: []byte{0x00, 0x01},
@@ -540,19 +538,19 @@ func TestHandleChatSend(t *testing.T) {
                                                Clients: map[uint16]*ClientConn{
                                                        uint16(1): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                                       Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                                },
                                                                ID: &[]byte{0, 1},
                                                        },
                                                        uint16(2): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{0, 0, 0, 0, 0, 0, 0, 0},
+                                                                       Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
                                                                },
                                                                ID: &[]byte{0, 2},
                                                        },
                                                        uint16(3): {
                                                                Account: &Account{
-                                                                       Access: &[]byte{0, 0, 0, 0, 0, 0, 0, 0},
+                                                                       Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
                                                                },
                                                                ID: &[]byte{0, 3},
                                                        },
@@ -702,10 +700,9 @@ func TestHandleNewFolder(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                },
@@ -733,11 +730,10 @@ func TestHandleNewFolder(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessCreateFolder)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        ID: &[]byte{0, 1},
@@ -781,11 +777,10 @@ func TestHandleNewFolder(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessCreateFolder)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        ID: &[]byte{0, 1},
@@ -823,11 +818,10 @@ func TestHandleNewFolder(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessCreateFolder)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        ID: &[]byte{0, 1},
@@ -859,11 +853,10 @@ func TestHandleNewFolder(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessCreateFolder)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        ID: &[]byte{0, 1},
@@ -900,11 +893,10 @@ func TestHandleNewFolder(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessCreateFolder)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        ID: &[]byte{0, 1},
@@ -987,12 +979,11 @@ func TestHandleUploadFile(t *testing.T) {
                                                FileUpload: {},
                                        },
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessUploadFile)
                                                        bits.Set(accessUploadAnywhere)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                },
@@ -1026,10 +1017,9 @@ func TestHandleUploadFile(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                },
@@ -1091,11 +1081,10 @@ func TestHandleMakeAlias(t *testing.T) {
                                cc: &ClientConn{
                                        logger: NewTestLogger(),
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessMakeAlias)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1143,11 +1132,10 @@ func TestHandleMakeAlias(t *testing.T) {
                                cc: &ClientConn{
                                        logger: NewTestLogger(),
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessMakeAlias)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1197,10 +1185,9 @@ func TestHandleMakeAlias(t *testing.T) {
                                cc: &ClientConn{
                                        logger: NewTestLogger(),
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1273,11 +1260,10 @@ func TestHandleGetUser(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessOpenUser)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1286,7 +1272,7 @@ func TestHandleGetUser(t *testing.T) {
                                                                Login:    "guest",
                                                                Name:     "Guest",
                                                                Password: "password",
-                                                               Access:   &[]byte{1},
+                                                               Access:   accessBitmap{},
                                                        },
                                                },
                                        },
@@ -1307,7 +1293,7 @@ func TestHandleGetUser(t *testing.T) {
                                                NewField(fieldUserName, []byte("Guest")),
                                                NewField(fieldUserLogin, negateString([]byte("guest"))),
                                                NewField(fieldUserPassword, []byte("password")),
-                                               NewField(fieldUserAccess, []byte{1}),
+                                               NewField(fieldUserAccess, []byte{0, 0, 0, 0, 0, 0, 0, 0}),
                                        },
                                },
                        },
@@ -1318,10 +1304,9 @@ func TestHandleGetUser(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1352,11 +1337,10 @@ func TestHandleGetUser(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessOpenUser)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1411,11 +1395,10 @@ func TestHandleDeleteUser(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessDeleteUser)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1424,7 +1407,7 @@ func TestHandleDeleteUser(t *testing.T) {
                                                                Login:    "testuser",
                                                                Name:     "Testy McTest",
                                                                Password: "password",
-                                                               Access:   &[]byte{1},
+                                                               Access:   accessBitmap{},
                                                        },
                                                },
                                                FS: func() *MockFileStore {
@@ -1456,10 +1439,9 @@ func TestHandleDeleteUser(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1514,11 +1496,10 @@ func TestHandleGetMsgs(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessNewsReadArt)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1548,10 +1529,9 @@ func TestHandleGetMsgs(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1605,10 +1585,9 @@ func TestHandleNewUser(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1662,10 +1641,9 @@ func TestHandleListUsers(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1695,11 +1673,10 @@ func TestHandleListUsers(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessOpenUser)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1708,7 +1685,7 @@ func TestHandleListUsers(t *testing.T) {
                                                                Name:     "guest",
                                                                Login:    "guest",
                                                                Password: "zz",
-                                                               Access:   &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
+                                                               Access:   accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
                                                        },
                                                },
                                        },
@@ -1765,10 +1742,9 @@ func TestHandleDownloadFile(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{},
@@ -1797,11 +1773,10 @@ func TestHandleDownloadFile(t *testing.T) {
                                                FileDownload: {},
                                        },
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessDownloadFile)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1844,11 +1819,10 @@ func TestHandleDownloadFile(t *testing.T) {
                                        transfers: map[int]map[[4]byte]*FileTransfer{
                                                FileDownload: {},
                                        }, Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessDownloadFile)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -1962,10 +1936,9 @@ func TestHandleUpdateUser(t *testing.T) {
                                                Logger: NewTestLogger(),
                                        },
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                },
@@ -2019,10 +1992,9 @@ func TestHandleUpdateUser(t *testing.T) {
                                                },
                                        },
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                },
@@ -2075,10 +2047,9 @@ func TestHandleUpdateUser(t *testing.T) {
                                                },
                                        },
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                },
@@ -2136,10 +2107,9 @@ func TestHandleDelNewsArt(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                },
@@ -2190,10 +2160,9 @@ func TestHandleDisconnectUser(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                },
@@ -2225,22 +2194,20 @@ func TestHandleDisconnectUser(t *testing.T) {
                                                        uint16(1): {
                                                                Account: &Account{
                                                                        Login: "unnamed",
-                                                                       Access: func() *[]byte {
+                                                                       Access: func() accessBitmap {
                                                                                var bits accessBitmap
                                                                                bits.Set(accessCannotBeDiscon)
-                                                                               access := bits[:]
-                                                                               return &access
+                                                                               return bits
                                                                        }(),
                                                                },
                                                        },
                                                },
                                        },
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessDisconUser)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                },
@@ -2292,10 +2259,9 @@ func TestHandleSendInstantMsg(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                },
@@ -2323,11 +2289,10 @@ func TestHandleSendInstantMsg(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessSendPrivMsg)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        ID:       &[]byte{0, 1},
@@ -2373,11 +2338,10 @@ func TestHandleSendInstantMsg(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessSendPrivMsg)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        ID:       &[]byte{0, 1},
@@ -2457,10 +2421,9 @@ func TestHandleDeleteFile(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -2517,11 +2480,10 @@ func TestHandleDeleteFile(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessDeleteFile)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -2607,10 +2569,9 @@ func TestHandleGetFileNameList(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -2728,10 +2689,9 @@ func TestHandleGetClientInfoText(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        Server: &Server{
@@ -2764,11 +2724,10 @@ func TestHandleGetClientInfoText(t *testing.T) {
                                        UserName:   []byte("Testy McTest"),
                                        RemoteAddr: "1.2.3.4:12345",
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessGetClientInfo)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                                Name:  "test",
                                                Login: "test",
@@ -2780,11 +2739,10 @@ func TestHandleGetClientInfoText(t *testing.T) {
                                                                UserName:   []byte("Testy McTest"),
                                                                RemoteAddr: "1.2.3.4:12345",
                                                                Account: &Account{
-                                                                       Access: func() *[]byte {
+                                                                       Access: func() accessBitmap {
                                                                                var bits accessBitmap
                                                                                bits.Set(accessGetClientInfo)
-                                                                               access := bits[:]
-                                                                               return &access
+                                                                               return bits
                                                                        }(),
                                                                        Name:  "test",
                                                                        Login: "test",
@@ -2874,12 +2832,11 @@ func TestHandleTranAgreed(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
                                                        bits.Set(accessDisconUser)
                                                        bits.Set(accessAnyName)
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }()},
                                        Icon:    []byte{0, 1},
                                        Flags:   []byte{0, 1},
@@ -2951,10 +2908,9 @@ func TestHandleSetClientUserInfo(t *testing.T) {
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{
-                                               Access: func() *[]byte {
+                                               Access: func() accessBitmap {
                                                        var bits accessBitmap
-                                                       access := bits[:]
-                                                       return &access
+                                                       return bits
                                                }(),
                                        },
                                        ID:       &[]byte{0, 1},