focalboard/server/api/archive.go

144 lines
3.6 KiB
Go

package api
import (
"fmt"
"net/http"
"time"
"github.com/mattermost/focalboard/server/model"
"github.com/mattermost/focalboard/server/services/audit"
)
func (a *API) handleArchiveExport(w http.ResponseWriter, r *http.Request) {
// swagger:operation GET /api/v1/workspaces/{workspaceID}/archive/export archiveExport
//
// Exports an archive of all blocks for one or more boards. If board_id is provided then
// only that board will be exported, otherwise all boards in the workspace are exported.
//
// ---
// produces:
// - application/json
// parameters:
// - name: workspaceID
// in: path
// description: Workspace ID
// required: true
// type: string
// - name: board_id
// in: path
// description: Id of board to to export
// required: false
// type: string
// security:
// - BearerAuth: []
// responses:
// '200':
// description: success
// content:
// application-octet-stream:
// type: string
// format: binary
// default:
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
query := r.URL.Query()
boardID := query.Get("board_id")
container, err := a.getContainer(r)
if err != nil {
a.noContainerErrorResponse(w, r.URL.Path, err)
return
}
auditRec := a.makeAuditRecord(r, "archiveExport", audit.Fail)
defer a.audit.LogRecord(audit.LevelRead, auditRec)
auditRec.AddMeta("BoardID", boardID)
var boardIDs []string
if boardID != "" {
boardIDs = []string{boardID}
}
opts := model.ExportArchiveOptions{
WorkspaceID: container.WorkspaceID,
BoardIDs: boardIDs,
}
filename := fmt.Sprintf("archive-%s.focalboard", time.Now().Format("2006-01-02"))
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Disposition", "attachment; filename="+filename)
w.Header().Set("Content-Transfer-Encoding", "binary")
if err := a.app.ExportArchive(w, opts); err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
}
auditRec.Success()
}
func (a *API) handleArchiveImport(w http.ResponseWriter, r *http.Request) {
// swagger:operation POST /api/v1/workspaces/{workspaceID}/archive/import archiveImport
//
// Import an archive of boards.
//
// ---
// produces:
// - application/json
// consumes:
// - multipart/form-data
// parameters:
// - name: workspaceID
// in: path
// description: Workspace ID
// required: true
// type: string
// - name: file
// in: formData
// description: archive file to import
// required: true
// type: file
// security:
// - BearerAuth: []
// responses:
// '200':
// description: success
// default:
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
container, err := a.getContainer(r)
if err != nil {
a.noContainerErrorResponse(w, r.URL.Path, err)
return
}
ctx := r.Context()
session, _ := ctx.Value(sessionContextKey).(*model.Session)
userID := session.UserID
file, handle, err := r.FormFile(UploadFormFileKey)
if err != nil {
fmt.Fprintf(w, "%v", err)
return
}
defer file.Close()
auditRec := a.makeAuditRecord(r, "import", audit.Fail)
defer a.audit.LogRecord(audit.LevelModify, auditRec)
auditRec.AddMeta("filename", handle.Filename)
auditRec.AddMeta("size", handle.Size)
opt := model.ImportArchiveOptions{
WorkspaceID: container.WorkspaceID,
ModifiedBy: userID,
}
if err := a.app.ImportArchive(file, opt); err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}
jsonStringResponse(w, http.StatusOK, "{}")
auditRec.Success()
}