github.com/jancarloviray/community@v0.41.1-0.20170124221257-33a66c87cf2f/core/api/endpoint/attachment_endpoint.go (about)

     1  // Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
     2  //
     3  // This software (Documize Community Edition) is licensed under
     4  // GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
     5  //
     6  // You can operate outside the AGPL restrictions by purchasing
     7  // Documize Enterprise Edition and obtaining a commercial license
     8  // by contacting <sales@documize.com>.
     9  //
    10  // https://documize.com
    11  
    12  package endpoint
    13  
    14  import (
    15  	"bytes"
    16  	"database/sql"
    17  	"encoding/json"
    18  	"fmt"
    19  	"io"
    20  	"mime"
    21  	"net/http"
    22  
    23  	"github.com/documize/community/core/api/entity"
    24  	"github.com/documize/community/core/api/request"
    25  	"github.com/documize/community/core/api/util"
    26  	"github.com/documize/community/core/log"
    27  
    28  	uuid "github.com/nu7hatch/gouuid"
    29  
    30  	"github.com/gorilla/mux"
    31  
    32  	_ "github.com/mytrile/mime-ext" // this adds a large number of mime extensions
    33  )
    34  
    35  // AttachmentDownload is the end-point that responds to a request for a particular attachment
    36  // by sending the requested file to the client.
    37  func AttachmentDownload(w http.ResponseWriter, r *http.Request) {
    38  	method := "AttachmentDownload"
    39  	p := request.GetPersister(r)
    40  
    41  	params := mux.Vars(r)
    42  
    43  	attachment, err := p.GetAttachment(params["orgID"], params["attachmentID"])
    44  
    45  	if err == sql.ErrNoRows {
    46  		writeNotFoundError(w, method, params["fileID"])
    47  		return
    48  	}
    49  
    50  	if err != nil {
    51  		writeGeneralSQLError(w, method, err)
    52  		return
    53  	}
    54  
    55  	typ := mime.TypeByExtension("." + attachment.Extension)
    56  	if typ == "" {
    57  		typ = "application/octet-stream"
    58  	}
    59  
    60  	w.Header().Set("Content-Type", typ)
    61  	w.Header().Set("Content-Disposition", `Attachment; filename="`+attachment.Filename+`" ; `+`filename*="`+attachment.Filename+`"`)
    62  	w.Header().Set("Content-Length", fmt.Sprintf("%d", len(attachment.Data)))
    63  	w.WriteHeader(http.StatusOK)
    64  
    65  	_, err = w.Write(attachment.Data)
    66  	log.IfErr(err)
    67  }
    68  
    69  // GetAttachments is an end-point that returns all of the attachments of a particular documentID.
    70  func GetAttachments(w http.ResponseWriter, r *http.Request) {
    71  	method := "GetAttachments"
    72  	p := request.GetPersister(r)
    73  
    74  	params := mux.Vars(r)
    75  	documentID := params["documentID"]
    76  
    77  	if len(documentID) == 0 {
    78  		writeMissingDataError(w, method, "documentID")
    79  		return
    80  	}
    81  
    82  	if !p.CanViewDocument(documentID) {
    83  		writeForbiddenError(w)
    84  		return
    85  	}
    86  
    87  	a, err := p.GetAttachments(documentID)
    88  
    89  	if err != nil && err != sql.ErrNoRows {
    90  		writeGeneralSQLError(w, method, err)
    91  		return
    92  	}
    93  
    94  	if len(a) == 0 {
    95  		a = []entity.Attachment{}
    96  	}
    97  
    98  	json, err := json.Marshal(a)
    99  
   100  	if err != nil {
   101  		writeJSONMarshalError(w, method, "attachments", err)
   102  		return
   103  	}
   104  
   105  	writeSuccessBytes(w, json)
   106  }
   107  
   108  // DeleteAttachment is an endpoint that deletes a particular document attachment.
   109  func DeleteAttachment(w http.ResponseWriter, r *http.Request) {
   110  	method := "DeleteAttachment"
   111  	p := request.GetPersister(r)
   112  
   113  	params := mux.Vars(r)
   114  	documentID := params["documentID"]
   115  	attachmentID := params["attachmentID"]
   116  
   117  	if len(documentID) == 0 || len(attachmentID) == 0 {
   118  		writeMissingDataError(w, method, "documentID, attachmentID")
   119  		return
   120  	}
   121  
   122  	if !p.CanChangeDocument(documentID) {
   123  		writeForbiddenError(w)
   124  		return
   125  	}
   126  
   127  	tx, err := request.Db.Beginx()
   128  
   129  	if err != nil {
   130  		writeTransactionError(w, method, err)
   131  		return
   132  	}
   133  
   134  	p.Context.Transaction = tx
   135  
   136  	_, err = p.DeleteAttachment(attachmentID)
   137  
   138  	if err != nil {
   139  		log.IfErr(tx.Rollback())
   140  		writeGeneralSQLError(w, method, err)
   141  		return
   142  	}
   143  
   144  	log.IfErr(tx.Commit())
   145  
   146  	writeSuccessEmptyJSON(w)
   147  }
   148  
   149  // AddAttachments stores files against a document.
   150  func AddAttachments(w http.ResponseWriter, r *http.Request) {
   151  	method := "AddAttachments"
   152  	p := request.GetPersister(r)
   153  
   154  	params := mux.Vars(r)
   155  	documentID := params["documentID"]
   156  
   157  	if len(documentID) == 0 {
   158  		writeMissingDataError(w, method, "documentID")
   159  		return
   160  	}
   161  
   162  	if !p.CanChangeDocument(documentID) {
   163  		w.WriteHeader(http.StatusForbidden)
   164  		return
   165  	}
   166  
   167  	filedata, filename, err := r.FormFile("attachment")
   168  
   169  	if err != nil {
   170  		writeMissingDataError(w, method, "attachment")
   171  		return
   172  	}
   173  
   174  	b := new(bytes.Buffer)
   175  	_, err = io.Copy(b, filedata)
   176  
   177  	if err != nil {
   178  		writeServerError(w, method, err)
   179  		return
   180  	}
   181  
   182  	var job = "some-uuid"
   183  
   184  	newUUID, err := uuid.NewV4()
   185  
   186  	if err != nil {
   187  		writeServerError(w, method, err)
   188  		return
   189  	}
   190  
   191  	job = newUUID.String()
   192  
   193  	var a entity.Attachment
   194  	refID := util.UniqueID()
   195  	a.RefID = refID
   196  	a.DocumentID = documentID
   197  	a.Job = job
   198  	random := util.GenerateSalt()
   199  	a.FileID = random[0:9]
   200  	a.Filename = filename.Filename
   201  	a.Data = b.Bytes()
   202  
   203  	tx, err := request.Db.Beginx()
   204  
   205  	if err != nil {
   206  		writeTransactionError(w, method, err)
   207  		return
   208  	}
   209  
   210  	p.Context.Transaction = tx
   211  
   212  	err = p.AddAttachment(a)
   213  
   214  	if err != nil {
   215  		log.IfErr(tx.Rollback())
   216  		writeGeneralSQLError(w, method, err)
   217  		return
   218  	}
   219  
   220  	log.IfErr(tx.Commit())
   221  
   222  	writeSuccessEmptyJSON(w)
   223  }