github.com/elliott5/community@v0.14.1-0.20160709191136-823126fb026a/documize/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/documize/api/entity"
    24  	"github.com/documize/community/documize/api/request"
    25  	"github.com/documize/community/documize/api/util"
    26  	"github.com/documize/community/wordsmith/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.GetAttachmentByJobAndFileID(params["orgID"], params["job"], params["fileID"])
    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  	json, err := json.Marshal(a)
    95  
    96  	if err != nil {
    97  		writeJSONMarshalError(w, method, "attachments", err)
    98  		return
    99  	}
   100  
   101  	writeSuccessBytes(w, json)
   102  }
   103  
   104  // DeleteAttachment is an endpoint that deletes a particular document attachment.
   105  func DeleteAttachment(w http.ResponseWriter, r *http.Request) {
   106  	method := "DeleteAttachment"
   107  	p := request.GetPersister(r)
   108  
   109  	params := mux.Vars(r)
   110  	documentID := params["documentID"]
   111  	attachmentID := params["attachmentID"]
   112  
   113  	if len(documentID) == 0 || len(attachmentID) == 0 {
   114  		writeMissingDataError(w, method, "documentID, attachmentID")
   115  		return
   116  	}
   117  
   118  	if !p.CanChangeDocument(documentID) {
   119  		writeForbiddenError(w)
   120  		return
   121  	}
   122  
   123  	tx, err := request.Db.Beginx()
   124  
   125  	if err != nil {
   126  		writeTransactionError(w, method, err)
   127  		return
   128  	}
   129  
   130  	p.Context.Transaction = tx
   131  
   132  	_, err = p.DeleteAttachment(attachmentID)
   133  
   134  	if err != nil {
   135  		log.IfErr(tx.Rollback())
   136  		writeGeneralSQLError(w, method, err)
   137  		return
   138  	}
   139  
   140  	log.IfErr(tx.Commit())
   141  
   142  	writeSuccessEmptyJSON(w)
   143  }
   144  
   145  // AddAttachments stores files against a document.
   146  func AddAttachments(w http.ResponseWriter, r *http.Request) {
   147  	method := "AddAttachments"
   148  	p := request.GetPersister(r)
   149  
   150  	params := mux.Vars(r)
   151  	documentID := params["documentID"]
   152  
   153  	if len(documentID) == 0 {
   154  		writeMissingDataError(w, method, "documentID")
   155  		return
   156  	}
   157  
   158  	if !p.CanChangeDocument(documentID) {
   159  		w.WriteHeader(http.StatusForbidden)
   160  		return
   161  	}
   162  
   163  	filedata, filename, err := r.FormFile("attachment")
   164  
   165  	if err != nil {
   166  		writeMissingDataError(w, method, "attachment")
   167  		return
   168  	}
   169  
   170  	b := new(bytes.Buffer)
   171  	_, err = io.Copy(b, filedata)
   172  
   173  	if err != nil {
   174  		writeServerError(w, method, err)
   175  		return
   176  	}
   177  
   178  	var job = "some-uuid"
   179  
   180  	newUUID, err := uuid.NewV4()
   181  
   182  	if err != nil {
   183  		writeServerError(w, method, err)
   184  		return
   185  	}
   186  
   187  	job = newUUID.String()
   188  
   189  	var a entity.Attachment
   190  	refID := util.UniqueID()
   191  	a.RefID = refID
   192  	a.DocumentID = documentID
   193  	a.Job = job
   194  	random := util.GenerateSalt()
   195  	a.FileID = random[0:9]
   196  	a.Filename = filename.Filename
   197  	a.Data = b.Bytes()
   198  
   199  	tx, err := request.Db.Beginx()
   200  
   201  	if err != nil {
   202  		writeTransactionError(w, method, err)
   203  		return
   204  	}
   205  
   206  	p.Context.Transaction = tx
   207  
   208  	err = p.AddAttachment(a)
   209  
   210  	if err != nil {
   211  		log.IfErr(tx.Rollback())
   212  		writeGeneralSQLError(w, method, err)
   213  		return
   214  	}
   215  
   216  	log.IfErr(tx.Commit())
   217  
   218  	writeSuccessEmptyJSON(w)
   219  }