github.com/companieshouse/insolvency-api@v0.0.0-20231024103413-440c973d9e9b/service/attachment.go (about) 1 package service 2 3 import ( 4 "fmt" 5 "mime/multipart" 6 "net/http" 7 "strings" 8 9 "github.com/companieshouse/chs.go/log" 10 "github.com/companieshouse/go-sdk-manager/manager" 11 "github.com/companieshouse/insolvency-api/constants" 12 "github.com/companieshouse/insolvency-api/dao" 13 "github.com/companieshouse/insolvency-api/models" 14 ) 15 16 const maxFileSize = 1048576 * 4 // 4MB 17 18 // UploadAttachment sends a file to be uploaded to the File Transfer API and returns the ID 19 func UploadAttachment(file multipart.File, header *multipart.FileHeader, req *http.Request) (string, ResponseType, error) { 20 // Create SDK session 21 api, err := manager.GetSDK(req) 22 if err != nil { 23 err = fmt.Errorf("error creating SDK to upload attachment: [%v]", err) 24 log.ErrorR(req, err) 25 return "", Error, err 26 } 27 28 uploadedFileResponse, err := api.FileTransfer.UploadFile(file, header).Do() 29 if err != nil { 30 err = fmt.Errorf(constants.MsgErrorCommsFileTransferAPI, err) 31 log.ErrorR(req, err) 32 return "", Error, err 33 } 34 if uploadedFileResponse == nil { 35 err = fmt.Errorf("error uploading file: [%v]", err) 36 log.ErrorR(req, err) 37 return "", Error, err 38 } 39 return uploadedFileResponse.Id, Success, nil 40 } 41 42 // ValidateAttachmentDetails checks that the incoming attachment details are valid 43 func ValidateAttachmentDetails(svc dao.Service, transactionID string, attachmentType string, header *multipart.FileHeader) (string, error) { 44 var errs []string 45 46 // Check attachment is of valid type 47 if !constants.IsAttachmentTypeValid(attachmentType) { 48 errs = append(errs, "attachment_type is invalid") 49 } 50 51 // Check if attachment has already been filed 52 attachments, err := svc.GetAttachmentResources(transactionID) 53 if err != nil { 54 return "", err 55 } 56 if len(attachments) > 0 { 57 if attachmentType == constants.StatementOfAffairsLiquidator.String() { 58 errs = append(errs, fmt.Sprintf("attachment of type [%s] cannot be filed for insolvency case with transaction ID [%s] - other attachments have already been filed for this case", attachmentType, transactionID)) 59 } else { 60 for _, a := range attachments { 61 if a.Type == constants.StatementOfAffairsLiquidator.String() { 62 errs = append(errs, fmt.Sprintf("attachment of type [%s] has been filed for insolvency case with transaction ID [%s] - no other attachments can be filed for this case", a.Type, transactionID)) 63 break 64 } 65 if a.Type == attachmentType { 66 errs = append(errs, fmt.Sprintf("attachment of type [%s] has already been filed for insolvency case with transaction ID [%s]", attachmentType, transactionID)) 67 break 68 } 69 } 70 } 71 } 72 73 // Check file type is PDF 74 fileType := header.Header.Get("Content-Type") 75 if fileType != "application/pdf" && header.Filename[len(header.Filename)-3:] != "pdf" { 76 errs = append(errs, "attachment file format should be pdf") 77 } 78 79 // Check if attachment size is less than maxFileSize 80 if header.Size > maxFileSize { 81 errs = append(errs, "attachment file size is too large to be processed") 82 } 83 84 return strings.Join(errs, ", "), nil 85 } 86 87 // GetAttachmentDetails gets attachment details from File Transfer API 88 func GetAttachmentDetails(id string, req *http.Request) (*models.AttachmentFile, ResponseType, error) { 89 // Create SDK session 90 api, err := manager.GetSDK(req) 91 if err != nil { 92 err = fmt.Errorf("error creating SDK to get attachment details: [%v]", err) 93 log.ErrorR(req, err) 94 return nil, Error, err 95 } 96 97 response, err := api.FileTransfer.GetFile(id).Do() 98 99 if err != nil { 100 err = fmt.Errorf(constants.MsgErrorCommsFileTransferAPI, err) 101 log.ErrorR(req, err) 102 return nil, Error, err 103 } 104 // Add relevant file transfer attachment details to response 105 GetFileResponse := models.AttachmentFile{ 106 Name: response.Name, 107 Size: response.Size, 108 ContentType: response.ContentType, 109 AVStatus: response.AvStatus, 110 } 111 112 if (models.AttachmentFile{}) == GetFileResponse { 113 err = fmt.Errorf("error getting file: [%v]", err) 114 log.ErrorR(req, err) 115 return nil, Error, err 116 } 117 118 return &GetFileResponse, Success, nil 119 } 120 121 // DownloadAttachment downloads a file from the File Transfer API writes it to a ResponseWriter 122 func DownloadAttachment(attachmentID string, req *http.Request, w http.ResponseWriter) (ResponseType, error) { 123 124 // Create SDK session 125 api, err := manager.GetSDK(req) 126 if err != nil { 127 err = fmt.Errorf("error creating SDK to upload attachment: [%v]", err) 128 log.ErrorR(req, err) 129 return Error, err 130 } 131 132 downloadedFileResponse, err := api.FileTransfer.DownloadFile(attachmentID, w).Do() 133 if err != nil { 134 err = fmt.Errorf(constants.MsgErrorCommsFileTransferAPI, err) 135 log.ErrorR(req, err) 136 return Error, err 137 } 138 139 if downloadedFileResponse == nil { 140 err = fmt.Errorf("error downloading file: [%v]", err) 141 log.ErrorR(req, err) 142 return Error, err 143 } 144 return Success, nil 145 } 146 147 // DeleteAttachment deletes an attachment via the File Transfer API 148 func DeleteAttachment(id string, req *http.Request) (ResponseType, error) { 149 // Create SDK session 150 api, err := manager.GetSDK(req) 151 if err != nil { 152 err = fmt.Errorf("error creating SDK to get attachment details: [%v]", err) 153 log.ErrorR(req, err) 154 return Error, err 155 } 156 157 response, err := api.FileTransfer.DeleteFile(id).Do() 158 159 if err != nil { 160 err = fmt.Errorf(constants.MsgErrorCommsFileTransferAPI, err) 161 log.ErrorR(req, err) 162 return Error, err 163 } 164 165 if response == nil { 166 err = fmt.Errorf("error deleting file: [%v]", err) 167 log.ErrorR(req, err) 168 return Error, err 169 } 170 171 return Success, nil 172 }