mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-06 08:22:24 +01:00
feature (readonly): respect readonly restriction on the editor
This commit is contained in:
parent
50506dcff9
commit
3b65cdf417
8 changed files with 64 additions and 7 deletions
|
|
@ -90,6 +90,29 @@ export function http_delete(url){
|
|||
});
|
||||
}
|
||||
|
||||
export function http_options(url){
|
||||
return new Promise((done, err) => {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("OPTIONS", url, true);
|
||||
xhr.withCredentials = true;
|
||||
xhr.onload = function(){
|
||||
if(xhr.readyState === XMLHttpRequest.DONE){
|
||||
if(xhr.status !== 200){
|
||||
handle_error_response(xhr, err);
|
||||
return
|
||||
}
|
||||
done(xhr.getAllResponseHeaders()
|
||||
.split("\n")
|
||||
.reduce((acc, r) => {
|
||||
const a = r.split(": ");
|
||||
acc[a[0]] = a[1];
|
||||
return acc;
|
||||
}, {}));
|
||||
}
|
||||
}
|
||||
xhr.send(null);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function handle_error_response(xhr, err){
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export { cache } from './cache';
|
|||
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';
|
||||
export { invalidate, http_get, http_post, http_delete, http_options } from './ajax';
|
||||
export { prompt, alert, confirm } from './popup';
|
||||
export { notify } from './notify';
|
||||
export { gid, randomString } from './random';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
import { http_get, http_post, prepare, basename, dirname, pathBuilder } from '../helpers/';
|
||||
import { http_get, http_post, http_options, prepare, basename, dirname, pathBuilder } from '../helpers/';
|
||||
import { filetype, currentShare, appendShareToUrl } from '../helpers/';
|
||||
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
|
@ -190,6 +190,12 @@ class FileSystem{
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
options(path){
|
||||
const url = appendShareToUrl('/api/files/cat?path='+prepare(path));
|
||||
return http_options(url);
|
||||
}
|
||||
|
||||
url(path){
|
||||
const url = appendShareToUrl('/api/files/cat?path='+prepare(path));
|
||||
return Promise.resolve(url);
|
||||
|
|
|
|||
|
|
@ -62,16 +62,26 @@ export class ViewerPage extends React.Component {
|
|||
};
|
||||
const data_fetch = (app) => {
|
||||
if(app === 'editor'){
|
||||
Files.cat(this.state.path).then((content) => {
|
||||
this.setState({content: content, loading: false});
|
||||
}).catch(err => {
|
||||
return Promise.all([
|
||||
Files.cat(this.state.path),
|
||||
Files.options(this.state.path)
|
||||
]).then((d) => {
|
||||
const [content, options] = d;
|
||||
console.log(options);
|
||||
options.allowed
|
||||
this.setState({
|
||||
content: content,
|
||||
loading: false,
|
||||
acl: options["allow"]
|
||||
});
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
if(err && err.code === 'BINARY_FILE'){
|
||||
this.setState({opener: 'download', loading: false});
|
||||
}else{
|
||||
this.props.error(err);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.setState({loading: false});
|
||||
};
|
||||
|
|
@ -134,6 +144,7 @@ export class ViewerPage extends React.Component {
|
|||
content={this.state.content || ""}
|
||||
url={this.state.url}
|
||||
path={this.state.path}
|
||||
acl={this.state.acl}
|
||||
filename={this.state.filename}/>
|
||||
</NgIf>
|
||||
<NgIf cond={this.state.opener === 'image'}>
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ export class Editor extends React.Component {
|
|||
mode: mode,
|
||||
keyMap: CONFIG["editor"],
|
||||
lineWrapping: true,
|
||||
readOnly: !this.props.readonly,
|
||||
foldOptions: {
|
||||
widget: "..."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ export class IDE extends React.Component {
|
|||
<ReactCSSTransitionGroup transitionName="editor" transitionAppear={true} transitionEnter={false} transitionLeave={false} transitionAppearTimeout={300} className="editor_container">
|
||||
<Editor onSave={this.save.bind(this)} filename={this.props.filename}
|
||||
content={this.state.contentToSave}
|
||||
readonly={/PUT/.test(this.props.acl)}
|
||||
event={this.state.event.asObservable()}
|
||||
onModeChange={this.onUpdate.bind(this, 'mode', false)}
|
||||
onFoldChange={this.onUpdate.bind(this, 'folding', false)}
|
||||
|
|
|
|||
|
|
@ -138,6 +138,21 @@ func FileCat(ctx App, res http.ResponseWriter, req *http.Request) {
|
|||
io.Copy(res, file)
|
||||
}
|
||||
|
||||
func FileAccess(ctx App, res http.ResponseWriter, req *http.Request) {
|
||||
allowed := []string{}
|
||||
if model.CanRead(&ctx){
|
||||
allowed = append(allowed, "GET")
|
||||
}
|
||||
if model.CanEdit(&ctx){
|
||||
allowed = append(allowed, "PUT")
|
||||
}
|
||||
if model.CanUpload(&ctx){
|
||||
allowed = append(allowed, "POST")
|
||||
}
|
||||
res.Header().Set("Allow", strings.Join(allowed, ", "))
|
||||
SendSuccessResult(res, nil)
|
||||
}
|
||||
|
||||
func FileSave(ctx App, res http.ResponseWriter, req *http.Request) {
|
||||
if model.CanEdit(&ctx) == false {
|
||||
SendErrorResult(res, NewError("Permission denied", 403))
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ func Init(a *App) {
|
|||
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(FileAccess, middlewares, *a)).Methods("OPTIONS")
|
||||
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")
|
||||
|
|
@ -78,7 +79,6 @@ func Init(a *App) {
|
|||
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 }
|
||||
|
|
|
|||
Loading…
Reference in a new issue