]> git.r.bdr.sh - rbdr/mobius/commitdiff
Implement handling of special case Dropbox and Upload folders
authorJeff Halter <redacted>
Sun, 29 May 2022 17:03:19 +0000 (10:03 -0700)
committerJeff Halter <redacted>
Sun, 29 May 2022 17:03:19 +0000 (10:03 -0700)
hotline/access.go
hotline/file_path.go
hotline/transaction_handlers.go
hotline/transaction_handlers_test.go

index 8d6dd63f75f6399f68f2d3932191e68a6aa1020a..69bf53ee62a17cbbffb53101c7d74b9684521fce 100644 (file)
@@ -34,12 +34,12 @@ const (
        accessDisconUser     = 22 // Toggles red user name in user list
        accessCannotBeDiscon = 23
        accessGetClientInfo  = 24
-       // accessUploadAnywhere   = 25
+       accessUploadAnywhere = 25
        // accessAnyName          = 26
        // accessNoAgreement      = 27
        // accessSetFileComment   = 28
        // accessSetFolderComment = 29
-       // accessViewDropBoxes    = 30
+       accessViewDropBoxes = 30
        accessMakeAlias     = 31
        accessBroadcast     = 32
        accessNewsDeleteArt = 33
index 2e2e085046a6269f5f577930ec7b7e1781d2c436..d5ddd230c2a7b84ad15ef6b50950aedd23fd655a 100644 (file)
@@ -5,6 +5,7 @@ import (
        "encoding/binary"
        "errors"
        "path"
+       "strings"
 )
 
 const pathSeparator = "/" // File path separator TODO: make configurable to support Windows
@@ -31,6 +32,7 @@ type FilePath struct {
 }
 
 const minFilePathLen = 2
+
 func (fp *FilePath) UnmarshalBinary(b []byte) error {
        if b == nil {
                return nil
@@ -53,6 +55,22 @@ func (fp *FilePath) UnmarshalBinary(b []byte) error {
        return nil
 }
 
+func (fp *FilePath) IsDropbox() bool {
+       if fp.Len() == 0 {
+               return false
+       }
+
+       return strings.Contains(strings.ToLower(string(fp.Items[fp.Len()-1].Name)), "drop box")
+}
+
+func (fp *FilePath) IsUploadDir() bool {
+       if fp.Len() == 0 {
+               return false
+       }
+
+       return strings.Contains(strings.ToLower(string(fp.Items[fp.Len()-1].Name)), "uploads")
+}
+
 func (fp *FilePath) Len() uint16 {
        return binary.BigEndian.Uint16(fp.ItemCount[:])
 }
index 270f73efb13bed9d506ff585e4e622fffe6896a2..c17510a53d214da3c054d322d72704f8cff9ce82 100644 (file)
@@ -1066,8 +1066,8 @@ func HandleDelNewsItem(cc *ClientConn, t *Transaction) (res []Transaction, err e
 
        delName := pathStrs[len(pathStrs)-1]
        if len(pathStrs) > 1 {
-               for _, path := range pathStrs[0 : len(pathStrs)-1] {
-                       cats = cats[path].SubCats
+               for _, fp := range pathStrs[0 : len(pathStrs)-1] {
+                       cats = cats[fp].SubCats
                }
        }
 
@@ -1295,6 +1295,21 @@ func HandleUploadFolder(cc *ClientConn, t *Transaction) (res []Transaction, err
        transactionRef := cc.Server.NewTransactionRef()
        data := binary.BigEndian.Uint32(transactionRef)
 
+       var fp FilePath
+       if t.GetField(fieldFilePath).Data != nil {
+               if err = fp.UnmarshalBinary(t.GetField(fieldFilePath).Data); err != nil {
+                       return res, err
+               }
+       }
+
+       // Handle special cases for Upload and Drop Box folders
+       if !authorize(cc.Account.Access, 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
+               }
+       }
+
        fileTransfer := &FileTransfer{
                FileName:        t.GetField(fieldFileName).Data,
                FilePath:        t.GetField(fieldFilePath).Data,
@@ -1309,8 +1324,10 @@ func HandleUploadFolder(cc *ClientConn, t *Transaction) (res []Transaction, err
        return res, err
 }
 
+// HandleUploadFile
+// Special cases:
+// * If the target directory contains "uploads" (case insensitive)
 func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
-       // TODO: add permission handing for upload folders and drop boxes
        if !authorize(cc.Account.Access, accessUploadFile) {
                res = append(res, cc.NewErrReply(t, "You are not allowed to upload files."))
                return res, err
@@ -1319,6 +1336,21 @@ func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err er
        fileName := t.GetField(fieldFileName).Data
        filePath := t.GetField(fieldFilePath).Data
 
+       var fp FilePath
+       if filePath != nil {
+               if err = fp.UnmarshalBinary(filePath); err != nil {
+                       return res, err
+               }
+       }
+
+       // Handle special cases for Upload and Drop Box folders
+       if !authorize(cc.Account.Access, 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
+               }
+       }
+
        transactionRef := cc.Server.NewTransactionRef()
        data := binary.BigEndian.Uint32(transactionRef)
 
@@ -1395,6 +1427,19 @@ func HandleGetFileNameList(cc *ClientConn, t *Transaction) (res []Transaction, e
                return res, err
        }
 
+       var fp FilePath
+       if t.GetField(fieldFilePath).Data != nil {
+               if err = fp.UnmarshalBinary(t.GetField(fieldFilePath).Data); err != nil {
+                       return res, err
+               }
+       }
+
+       // Handle special case for drop box folders
+       if fp.IsDropbox() && !authorize(cc.Account.Access, accessViewDropBoxes) {
+               res = append(res, cc.NewReply(t))
+               return res, err
+       }
+
        fileNames, err := getFileNameList(fullPath)
        if err != nil {
                return res, err
index b8c74bbe7f9691b717bd47f6887c0d699840ef29..e1dc8cbe9336baa4d7e141169a31e87bc6dfa28c 100644 (file)
@@ -818,7 +818,7 @@ func TestHandleUploadFile(t *testing.T) {
                wantErr bool
        }{
                {
-                       name: "when request is valid",
+                       name: "when request is valid and user has Upload Anywhere permission",
                        args: args{
                                cc: &ClientConn{
                                        Server: &Server{
@@ -828,6 +828,7 @@ func TestHandleUploadFile(t *testing.T) {
                                                Access: func() *[]byte {
                                                        var bits accessBitmap
                                                        bits.Set(accessUploadFile)
+                                                       bits.Set(accessUploadAnywhere)
                                                        access := bits[:]
                                                        return &access
                                                }(),