diff --git a/client/components/dropdown.js b/client/components/dropdown.js
index a501b6c4..29cf14dd 100644
--- a/client/components/dropdown.js
+++ b/client/components/dropdown.js
@@ -45,6 +45,9 @@ export class Dropdown extends React.Component {
}
toggleDropdown(e){
+ if(this.props.enable === false){
+ return
+ }
document.body.removeEventListener("click", this.closeDropdown);
this.setState({button: !this.state.button}, () => {
if(this.state.button === true){
diff --git a/client/helpers/index.js b/client/helpers/index.js
index 3d4f1d85..eb42e6bd 100644
--- a/client/helpers/index.js
+++ b/client/helpers/index.js
@@ -4,7 +4,7 @@ export { debounce, throttle } from './backpressure';
export { encrypt, decrypt, bcrypt_password } from './crypto';
export { event } from './events';
export { cache } from './cache';
-export { pathBuilder, basename, dirname, absoluteToRelative, filetype, currentShare, appendShareToUrl } from './path';
+export { pathBuilder, basename, dirname, absoluteToRelative, filetype, currentShare, findParams, appendShareToUrl } from './path';
export { memory } from './memory';
export { prepare } from './navigate';
export { invalidate, http_get, http_post, http_delete } from './ajax';
diff --git a/client/helpers/path.js b/client/helpers/path.js
index 10b7760e..a49e53fc 100644
--- a/client/helpers/path.js
+++ b/client/helpers/path.js
@@ -37,7 +37,11 @@ export function absoluteToRelative(from, to){
}
export function currentShare(){
- return new window.URL(location.href).searchParams.get("share") || ""
+ return findParams("share");
+}
+
+export function findParams(p){
+ return new window.URL(location.href).searchParams.get(p) || ""
}
export function appendShareToUrl(link) {
diff --git a/client/pages/filespage/thing-new.js b/client/pages/filespage/thing-new.js
index d825eb4c..e39b0965 100644
--- a/client/pages/filespage/thing-new.js
+++ b/client/pages/filespage/thing-new.js
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Card, NgIf, Icon, EventEmitter, EventReceiver, Dropdown, DropdownButton, DropdownList, DropdownItem } from '../../components/';
+import { Card, NgIf, Icon, EventEmitter, EventReceiver } from '../../components/';
import { pathBuilder, debounce } from '../../helpers/';
import "./thing.scss";
diff --git a/client/pages/sharepage.js b/client/pages/sharepage.js
index 75b62ca3..d07481b2 100644
--- a/client/pages/sharepage.js
+++ b/client/pages/sharepage.js
@@ -2,7 +2,7 @@ import React from 'react';
import { Redirect } from 'react-router';
import { Share } from '../model/';
-import { notify, basename, filetype } from '../helpers/';
+import { notify, basename, filetype, findParams } from '../helpers/';
import { Loader, Input, Button, Container, ErrorPage, Icon, NgIf } from '../components/';
import './error.scss';
import './sharepage.scss';
@@ -67,7 +67,20 @@ export class SharePage extends React.Component {
let className = this.state.error ? "error rand-"+Math.random().toString() : "";
if(this.state.path !== null){
- if(filetype(this.state.path) === "directory"){
+ if(!!findParams("next")){
+ const url = findParams("next");
+ if(url[0] === "/"){
+ requestAnimationFrame(() => {
+ window.location.pathname = url;
+ });
+ return (
+
+
+
+ );
+ }
+ notify.send("You can't do that :)", "error");
+ }else if(filetype(this.state.path) === "directory"){
return ( );
}else{
return ( );
diff --git a/client/pages/viewerpage.js b/client/pages/viewerpage.js
index 5284a99e..73f9f585 100644
--- a/client/pages/viewerpage.js
+++ b/client/pages/viewerpage.js
@@ -133,6 +133,7 @@ export class ViewerPage extends React.Component {
onSave={this.save.bind(this)}
content={this.state.content || ""}
url={this.state.url}
+ path={this.state.path}
filename={this.state.filename}/>
diff --git a/client/pages/viewerpage/ide.js b/client/pages/viewerpage/ide.js
index 9d6ad135..203b75db 100644
--- a/client/pages/viewerpage/ide.js
+++ b/client/pages/viewerpage/ide.js
@@ -4,8 +4,8 @@ import { withRouter } from 'react-router';
import { Prompt } from "react-router-dom";
import { Subject } from 'rxjs/Subject';
-import { NgIf, Fab, Icon } from '../../components/';
-import { confirm } from '../../helpers/';
+import { NgIf, Fab, Icon, Dropdown, DropdownButton, DropdownList, DropdownItem } from '../../components/';
+import { confirm, currentShare } from '../../helpers/';
import { Editor } from './editor';
import { MenuBar } from './menubar';
import { OrgTodosViewer, OrgEventsViewer } from './org_viewer';
@@ -48,6 +48,7 @@ export class IDE extends React.Component {
}
componentWillUnmount(){
this.unblock();
+ window.clearInterval(this.state.id);
}
save(){
@@ -70,7 +71,6 @@ export class IDE extends React.Component {
});
}
-
/* Org Viewer specific stuff */
toggleAgenda(force = null){
this.setState({appear_agenda: force === null ? !this.state.appear_agenda : !!force});
@@ -85,10 +85,25 @@ export class IDE extends React.Component {
this.state.event.next(["goTo", lineNumber]);
}
+ download(){
+ document.cookie = "download=yes; path=/; max-age=120;";
+ this.setState({random: Math.random()});
+ this.state.id = window.setInterval(() => {
+ if(/download=yes/.test(document.cookie) === false){
+ window.clearInterval(this.state.id);
+ this.setState({random: Math.random()});
+ }
+ }, 100);
+ }
+
render(){
+ const changeExt = function(filename, ext){
+ return filename.replace(/\.org$/, "."+ext);
+ };
+
return (
-
+
@@ -101,6 +116,22 @@ export class IDE extends React.Component {
+ this.download()} enable={/download=yes/.test(document.cookie) ? false : true}>
+
+
+
+
+ Save current file
+ Export as HTML
+ Export as PDF
+ Export as Text
+ Export as Latex
+ Export as Calendar
+ Export as Beamer
+ Export as Open office
+ Export as Markdown
+
+
diff --git a/client/pages/viewerpage/ide.scss b/client/pages/viewerpage/ide.scss
index 4dd43fe7..3c9d5412 100644
--- a/client/pages/viewerpage/ide.scss
+++ b/client/pages/viewerpage/ide.scss
@@ -9,6 +9,28 @@
// https://stackoverflow.com/questions/44948158/flexbox-overflow-issue-in-firefox
min-height: 0;
}
+
+ .component_menubar{
+ .component_dropdown{
+ float: right;
+ .dropdown_button{
+ border: none;
+ padding: 0; margin: 0;
+ }
+ &.active .dropdown_button{
+ box-shadow: none;
+ }
+ .dropdown_container ul li > div{
+ padding: 0;
+ a {
+ padding: 7px 5px 7px 10px;
+ display: inline-block;
+ width: 100%;
+ box-sizing: border-box;
+ }
+ }
+ }
+ }
}
diff --git a/client/pages/viewerpage/menubar.js b/client/pages/viewerpage/menubar.js
index 8d98a828..131f4d90 100644
--- a/client/pages/viewerpage/menubar.js
+++ b/client/pages/viewerpage/menubar.js
@@ -16,7 +16,7 @@ export const MenuBar = (props) => {
{props.children}
-
+ { props.download === null ? null : }
diff --git a/config/emacs.el b/config/emacs.el
new file mode 100644
index 00000000..efc681e4
--- /dev/null
+++ b/config/emacs.el
@@ -0,0 +1,12 @@
+;; this is the config that's loaded by emacs when using the org mode export
+
+;; org mode keywords
+(setq org-todo-keywords (quote ((sequence "TODO(t)" "DOING(d)" "WAITING(w)" "|" "CANCEL(C)" "DEFERRED(F)" "DONE(D)"))))
+
+;; html export
+(setq org-html-head "")
+(setq org-html-validation-link nil)
+(setq org-html-creator-string "Using Filestash")
+
+(setq org-export-use-babel nil)
+(setq org-confirm-babel-evaluate nil)
diff --git a/config/mime.json b/config/mime.json
index 19dcc554..c56b1afa 100644
--- a/config/mime.json
+++ b/config/mime.json
@@ -90,6 +90,7 @@
"ogg": "audio/ogg",
"ogv": "application/ogg",
"orf": "image/x-olympus-orf",
+ "org": "text/org",
"pdb": "application/x-pilot",
"pdf": "application/pdf",
"pef": "image/x-pentax-pef",
diff --git a/server/common/constants.go b/server/common/constants.go
index 5dc7cc63..bd3517cc 100644
--- a/server/common/constants.go
+++ b/server/common/constants.go
@@ -5,6 +5,7 @@ const (
CONFIG_PATH = "data/config/"
PLUGIN_PATH = "data/plugin/"
LOG_PATH = "data/log/"
+ TMP_PATH = "data/tmp/"
COOKIE_NAME_AUTH = "auth"
COOKIE_NAME_PROOF = "proof"
COOKIE_NAME_ADMIN = "admin"
diff --git a/server/common/error.go b/server/common/error.go
index 9eaf2b1e..dafda0be 100644
--- a/server/common/error.go
+++ b/server/common/error.go
@@ -15,6 +15,9 @@ var (
ErrNotValid error = NewError("Not Valid", 405)
ErrNotReachable error = NewError("Cannot Reach Destination", 502)
ErrInvalidPassword = NewError("Invalid Password", 403)
+ ErrNotImplemented = NewError("Not Implemented", 501)
+ ErrFilesystemError = NewError("Can't use filesystem", 503)
+ ErrMissingDependency = NewError("Missing dependency", 424)
)
type AppError struct {
diff --git a/server/ctrl/export.go b/server/ctrl/export.go
new file mode 100644
index 00000000..7549a606
--- /dev/null
+++ b/server/ctrl/export.go
@@ -0,0 +1,149 @@
+package ctrl
+
+import (
+ "fmt"
+ . "github.com/mickael-kerjean/filestash/server/common"
+ "github.com/mickael-kerjean/filestash/server/model"
+ "github.com/gorilla/mux"
+ "io"
+ "net/http"
+ "os"
+ "os/exec"
+ "runtime"
+ "strings"
+)
+
+
+var EXPORT_PATH string
+func init() {
+ EXPORT_PATH = GetAbsolutePath(TMP_PATH)
+ os.RemoveAll(EXPORT_PATH)
+ os.MkdirAll(EXPORT_PATH, os.ModePerm)
+}
+func FileExport(ctx App, res http.ResponseWriter, req *http.Request) {
+ query := req.URL.Query()
+ p := mux.Vars(req)
+ mimeType := fmt.Sprintf("%s/%s", p["mtype0"], p["mtype1"])
+ path, err := pathBuilder(ctx, strings.Replace(req.URL.Path, fmt.Sprintf("/api/export/%s/%s/%s", p["share"], p["mtype0"], p["mtype1"]), "", 1))
+ if err != nil {
+ SendErrorResult(res, err)
+ return
+ } else if model.CanRead(&ctx) == false {
+ SendErrorResult(res, ErrPermissionDenied)
+ return
+ }
+ http.SetCookie(res, &http.Cookie{
+ Name: "download",
+ Value: "",
+ MaxAge: -1,
+ Path: "/",
+ })
+
+ var tmpPath string = EXPORT_PATH + "/export_" + QuickString(10)
+ var cmd *exec.Cmd
+ var emacsPath string
+ var outPath string
+ if GetMimeType(path) == "text/org" {
+ if emacsPath, err = exec.LookPath("emacs"); err != nil {
+ SendErrorResult(res, ErrMissingDependency)
+ return
+ }
+ if runtime.GOOS == "darwin" {
+ // on OSX, the default emacs isn't usable so we default to the one provided by `brew`
+ if f, err := os.OpenFile("/usr/local/Cellar/emacs/", os.O_RDONLY, os.ModePerm); err == nil {
+ if dirs, err := f.Readdirnames(0); err == nil {
+ if len(dirs) > 0 {
+ emacsPath = "/usr/local/Cellar/emacs/" + dirs[0] + "/bin/emacs"
+ }
+ }
+ }
+ }
+
+ if mimeType == "text/html" {
+ cmd = exec.Command(
+ emacsPath, "--no-init-file", "--batch",
+ "--load", GetAbsolutePath(CONFIG_PATH + "emacs.el"),
+ "--eval", "(setq org-html-extension \"org\")",
+ tmpPath + "/index.org", "-f", "org-html-export-to-html",
+ )
+ outPath = "index.org.org"
+ } else if mimeType == "application/pdf" {
+ cmd = exec.Command(
+ emacsPath, "--no-init-file", "--batch",
+ tmpPath + "/index.org", "-f", "org-latex-export-to-pdf",
+ )
+ if query.Get("mode") == "beamer" {
+ cmd = exec.Command(
+ emacsPath, "--no-init-file", "--batch",
+ tmpPath + "/index.org", "-f", "org-beamer-export-to-pdf",
+ )
+ }
+ outPath = "index.pdf"
+ } else if mimeType == "text/calendar" {
+ cmd = exec.Command(
+ emacsPath, "--no-init-file", "--batch",
+ tmpPath + "/index.org", "-f", "org-icalendar-export-to-ics",
+ )
+ outPath = "index.ics"
+ } else if mimeType == "text/plain" {
+ cmd = exec.Command(
+ emacsPath, "--no-init-file", "--batch",
+ tmpPath + "/index.org", "-f", "org-ascii-export-to-ascii",
+ )
+ outPath = "index.txt"
+ } else if mimeType == "text/x-latex" {
+ cmd = exec.Command(
+ emacsPath, "--no-init-file", "--batch",
+ tmpPath + "/index.org", "-f", "org-latex-export-to-latex",
+ )
+ outPath = "index.tex"
+ } else if mimeType == "text/markdown" {
+ cmd = exec.Command(
+ emacsPath, "--no-init-file", "--batch",
+ tmpPath + "/index.org", "-f", "org-md-export-to-markdown",
+ )
+ outPath = "index.md"
+ } else if mimeType == "application/vnd.oasis.opendocument.text" {
+ cmd = exec.Command(
+ emacsPath, "--no-init-file", "--batch",
+ tmpPath + "/index.org", "-f", "org-odt-export-to-odt",
+ )
+ outPath = "index.odt"
+ }else {
+ SendErrorResult(res, ErrNotImplemented)
+ return
+ }
+
+ os.MkdirAll(tmpPath, os.ModePerm)
+ defer os.RemoveAll(tmpPath)
+ f, err := os.OpenFile(tmpPath + "/index.org", os.O_WRONLY|os.O_CREATE, os.ModePerm)
+ if err != nil {
+ SendErrorResult(res, ErrFilesystemError)
+ return
+ }
+ file, err := ctx.Backend.Cat(path)
+ if err != nil {
+ SendErrorResult(res, err)
+ return
+ }
+ io.Copy(f, file)
+ // TODO: insert related resources: eg: images
+
+ if err = cmd.Run(); err != nil {
+ SendErrorResult(res, NewError("emacs has quit with error: '%s'" + err.Error(), 400))
+ return
+ }
+
+ f, err = os.OpenFile(tmpPath + "/"+outPath, os.O_RDONLY, os.ModePerm)
+ if err != nil {
+ SendErrorResult(res, ErrFilesystemError)
+ return
+ }
+ res.Header().Set("Content-Type", mimeType)
+ io.Copy(res, f)
+ return
+ }
+
+ SendErrorResult(res, ErrNotImplemented)
+ return
+}
diff --git a/server/ctrl/files.go b/server/ctrl/files.go
index eb498305..bde5d465 100644
--- a/server/ctrl/files.go
+++ b/server/ctrl/files.go
@@ -106,7 +106,7 @@ func FileCat(ctx App, res http.ResponseWriter, req *http.Request) {
Path: "/",
})
if model.CanRead(&ctx) == false {
- SendErrorResult(res, NewError("Permission denied", 403))
+ SendErrorResult(res, ErrPermissionDenied)
return
}
diff --git a/server/ctrl/share.go b/server/ctrl/share.go
index 4ad0de4b..d7e929d4 100644
--- a/server/ctrl/share.go
+++ b/server/ctrl/share.go
@@ -151,7 +151,7 @@ func ShareVerifyProof(ctx App, res http.ResponseWriter, req *http.Request) {
Key: fmt.Sprint(ctx.Body["type"]),
Value: fmt.Sprint(ctx.Body["value"]),
}
- verifiedProof = model.ShareProofGetAlreadyVerified(req, &ctx)
+ verifiedProof = model.ShareProofGetAlreadyVerified(req)
requiredProof = model.ShareProofGetRequired(s)
// 2) validate the current context
diff --git a/server/main.go b/server/main.go
index ab253b54..277dda8a 100644
--- a/server/main.go
+++ b/server/main.go
@@ -66,21 +66,27 @@ func Init(a *App) {
// API for File management
files := r.PathPrefix("/api/files").Subrouter()
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SessionStart, LoggedInOnly }
- files.HandleFunc("/ls", NewMiddlewareChain(FileLs, middlewares, *a)).Methods("GET")
- files.HandleFunc("/cat", NewMiddlewareChain(FileCat, middlewares, *a)).Methods("GET")
- files.HandleFunc("/cat", NewMiddlewareChain(FileSave, middlewares, *a)).Methods("POST")
- files.HandleFunc("/mv", NewMiddlewareChain(FileMv, middlewares, *a)).Methods("GET")
- files.HandleFunc("/rm", NewMiddlewareChain(FileRm, middlewares, *a)).Methods("GET")
- files.HandleFunc("/mkdir", NewMiddlewareChain(FileMkdir, middlewares, *a)).Methods("GET")
- files.HandleFunc("/touch", NewMiddlewareChain(FileTouch, middlewares, *a)).Methods("GET")
+ files.HandleFunc("/ls", NewMiddlewareChain(FileLs, middlewares, *a)).Methods("GET")
+ files.HandleFunc("/cat", NewMiddlewareChain(FileCat, middlewares, *a)).Methods("GET")
+ files.HandleFunc("/cat", NewMiddlewareChain(FileSave, middlewares, *a)).Methods("POST")
+ files.HandleFunc("/mv", NewMiddlewareChain(FileMv, middlewares, *a)).Methods("GET")
+ files.HandleFunc("/rm", NewMiddlewareChain(FileRm, middlewares, *a)).Methods("GET")
+ files.HandleFunc("/mkdir", NewMiddlewareChain(FileMkdir, middlewares, *a)).Methods("GET")
+ files.HandleFunc("/touch", NewMiddlewareChain(FileTouch, middlewares, *a)).Methods("GET")
+
+ // API for exporter
+ middlewares = []Middleware{ ApiHeaders, SecureHeaders, RedirectSharedLoginIfNeeded, SessionStart, LoggedInOnly }
+ r.PathPrefix("/api/export/{share}/{mtype0}/{mtype1}").Handler(NewMiddlewareChain(FileExport, middlewares, *a))
+
// API for Shared link
share := r.PathPrefix("/api/share").Subrouter()
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SessionStart, LoggedInOnly }
share.HandleFunc("", NewMiddlewareChain(ShareList, middlewares, *a)).Methods("GET")
share.HandleFunc("/{share}", NewMiddlewareChain(ShareDelete, middlewares, *a)).Methods("DELETE")
- middlewares = []Middleware{ ApiHeaders, SecureHeaders, SessionStart, BodyParser, LoggedInOnly }
+ middlewares = []Middleware{ ApiHeaders, SecureHeaders, SessionStart, LoggedInOnly, BodyParser }
share.HandleFunc("/{share}", NewMiddlewareChain(ShareUpsert, middlewares, *a)).Methods("POST")
+ middlewares = []Middleware{ ApiHeaders, SecureHeaders, BodyParser }
share.HandleFunc("/{share}/proof", NewMiddlewareChain(ShareVerifyProof, middlewares, *a)).Methods("POST")
// Webdav server / Shared Link
diff --git a/server/middleware/session.go b/server/middleware/session.go
index 293fd1d6..2c9ea8ec 100644
--- a/server/middleware/session.go
+++ b/server/middleware/session.go
@@ -2,6 +2,7 @@ package middleware
import (
"encoding/json"
+ "fmt"
. "github.com/mickael-kerjean/filestash/server/common"
"github.com/mickael-kerjean/filestash/server/model"
"github.com/gorilla/mux"
@@ -46,45 +47,18 @@ func AdminOnly(fn func(App, http.ResponseWriter, *http.Request)) func(ctx App, r
}
func SessionStart (fn func(App, http.ResponseWriter, *http.Request)) func(ctx App, res http.ResponseWriter, req *http.Request) {
- extractShare := func(req *http.Request, ctx *App, share_id string) (Share, error) {
- if share_id == "" {
- return Share{}, nil
- }
-
- if Config.Get("features.share.enable").Bool() == false {
- Log.Debug("Share feature isn't enable, contact your administrator")
- return Share{}, NewError("Feature isn't enable, contact your administrator", 405)
- }
-
- s, err := model.ShareGet(share_id)
- if err != nil {
- return Share{}, nil
- }
- if err = s.IsValid(); err != nil {
- return Share{}, err
- }
- return s, nil
- }
extractSession := func(req *http.Request, ctx *App) (map[string]string, error) {
var str string
var err error
var res map[string]string = make(map[string]string)
if ctx.Share.Id != "" {
- var verifiedProof []model.Proof = model.ShareProofGetAlreadyVerified(req, ctx)
- var requiredProof []model.Proof = model.ShareProofGetRequired(ctx.Share)
- var remainingProof []model.Proof = model.ShareProofCalculateRemainings(requiredProof, verifiedProof)
- if len(remainingProof) != 0 {
- return res, NewError("Unauthorized Shared space", 400)
- }
- str = ctx.Share.Auth
- str, err = DecryptString(SECRET_KEY, str)
+ str, err = DecryptString(SECRET_KEY, ctx.Share.Auth)
if err != nil {
// This typically happen when changing the secret key
return res, nil
}
err = json.Unmarshal([]byte(str), &res)
-
if ctx.Share.Path[len(ctx.Share.Path)-1:] == "/" {
res["path"] = ctx.Share.Path
} else {
@@ -116,14 +90,7 @@ func SessionStart (fn func(App, http.ResponseWriter, *http.Request)) func(ctx Ap
return func(ctx App, res http.ResponseWriter, req *http.Request) {
var err error
- share_id := func() string {
- if len(req.URL.Path) > 3 && req.URL.Path[:3] == "/s/" {
- // this runs while using a link as a webdav server
- return mux.Vars(req)["share"]
- }
- return req.URL.Query().Get("share")
- }()
- if ctx.Share, err = extractShare(req, &ctx, share_id); err != nil {
+ if ctx.Share, err = _findShare(req, _extractShareId(req)); err != nil {
SendErrorResult(res, err)
return
}
@@ -138,3 +105,60 @@ func SessionStart (fn func(App, http.ResponseWriter, *http.Request)) func(ctx Ap
fn(ctx, res, req)
}
}
+
+func RedirectSharedLoginIfNeeded(fn func(App, http.ResponseWriter, *http.Request)) func(ctx App, res http.ResponseWriter, req *http.Request) {
+ return func(ctx App, res http.ResponseWriter, req *http.Request) {
+ share_id := _extractShareId(req)
+ if share_id == "" {
+ SendErrorResult(res, ErrNotValid)
+ return
+ }
+
+ share, err := _findShare(req, share_id);
+ if err != nil || share_id != share.Id {
+ http.Redirect(res, req, fmt.Sprintf("/s/%s?next=%s", share_id, req.URL.Path), http.StatusTemporaryRedirect)
+ return
+ }
+ fn(ctx, res, req)
+ }
+}
+
+func _extractShareId(req *http.Request) string {
+ share := req.URL.Query().Get("share")
+ if share != "" {
+ return share
+ }
+ m := mux.Vars(req)["share"]
+ if m == "me" {
+ return ""
+ }
+ return m
+}
+
+func _findShare(req *http.Request, share_id string) (Share, error) {
+ var err error
+ if share_id == "" {
+ return Share{}, nil
+ }
+
+ if Config.Get("features.share.enable").Bool() == false {
+ Log.Debug("Share feature isn't enable, contact your administrator")
+ return Share{}, NewError("Feature isn't enable, contact your administrator", 405)
+ }
+
+ s, err := model.ShareGet(share_id)
+ if err != nil {
+ return Share{}, nil
+ }
+ if err = s.IsValid(); err != nil {
+ return Share{}, err
+ }
+
+ var verifiedProof []model.Proof = model.ShareProofGetAlreadyVerified(req)
+ var requiredProof []model.Proof = model.ShareProofGetRequired(s)
+ var remainingProof []model.Proof = model.ShareProofCalculateRemainings(requiredProof, verifiedProof)
+ if len(remainingProof) != 0 {
+ return Share{}, NewError("Unauthorized Shared space", 400)
+ }
+ return s, nil
+}
diff --git a/server/model/share.go b/server/model/share.go
index 3845fc0f..f173741f 100644
--- a/server/model/share.go
+++ b/server/model/share.go
@@ -249,7 +249,7 @@ func ShareProofVerifier(ctx *App, s Share, proof Proof) (Proof, error) {
return p, nil
}
-func ShareProofGetAlreadyVerified(req *http.Request, ctx *App) []Proof {
+func ShareProofGetAlreadyVerified(req *http.Request) []Proof {
var p []Proof
var cookieValue string
diff --git a/server/plugin/plg_image_light/index.go b/server/plugin/plg_image_light/index.go
index 579212ef..5b205c13 100644
--- a/server/plugin/plg_image_light/index.go
+++ b/server/plugin/plg_image_light/index.go
@@ -165,7 +165,7 @@ func Init(conf *Configuration) {
// => lower RAM usage while processing
file, err := os.OpenFile(transform.Temporary, os.O_WRONLY|os.O_CREATE, os.ModePerm)
if err != nil {
- return reader, NewError("Can't use filesystem", 500)
+ return reader, ErrFilesystemError
}
io.Copy(file, reader)
file.Close()