mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-06 08:22:24 +01:00
feature (framework): create the basis for the development custom backends
This commit is contained in:
parent
696b852186
commit
bfacd4bcc5
12 changed files with 117 additions and 16 deletions
11
Makefile
11
Makefile
|
|
@ -10,4 +10,13 @@ build_frontend:
|
|||
NODE_ENV=production npm run build
|
||||
|
||||
build_backend:
|
||||
CGO_CFLAGS_ALLOW='-fopenmp' go build -o dist/nuage server/main.go
|
||||
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ CGO_CFLAGS_ALLOW='-fopenmp' go build -o dist/nuage server/main.go
|
||||
|
||||
package:
|
||||
rm -rf dist/
|
||||
make build_backend
|
||||
make build_frontend
|
||||
cp -R config dist/data/config
|
||||
mv dist nuage
|
||||
tar -zcvf nuage.tar.gz nuage
|
||||
rm -rf nuage
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ Data.prototype.fetchAll = function(fn, type = this.FILE_PATH, key = "/"){
|
|||
const tx = db.transaction([type], "readonly");
|
||||
const store = tx.objectStore(type);
|
||||
const index = store.index("idx_path");
|
||||
const request = index.openCursor(IDBKeyRange.lowerBound(key));
|
||||
const request = index.openCursor(IDBKeyRange.bound(key, key+("z".repeat(5000))));
|
||||
|
||||
return new Promise((done, error) => {
|
||||
request.onsuccess = function(event) {
|
||||
|
|
|
|||
|
|
@ -16,8 +16,12 @@ class SessionManager{
|
|||
let url = '/api/session/auth/gdrive';
|
||||
return http_get(url)
|
||||
.then(data => data.result);
|
||||
}else if(type === 'custombackend'){
|
||||
let url = '/api/session/auth/custombackend';
|
||||
return http_get(url)
|
||||
.then(data => data.result);
|
||||
}else{
|
||||
return Promise.error({message: 'not authorization backend for: '+type, code: 'UNKNOWN_PROVIDER'})
|
||||
return Promise.reject({message: 'no authorization backend', code: 'UNKNOWN_PROVIDER'});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ export class ConnectPage extends React.Component {
|
|||
}else if(state === "googledrive"){
|
||||
this.setState({doing_a_third_party_login: true});
|
||||
this.authenticate({code: getParam('code'), type: 'gdrive'});
|
||||
}else if(state === "custombackend"){
|
||||
this.setState({doing_a_third_party_login: true});
|
||||
this.authenticate({code: getParam('code'), type: 'custombackend'});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -76,6 +79,13 @@ export class ConnectPage extends React.Component {
|
|||
this.setState({loading: false});
|
||||
notify.send(err, 'error');
|
||||
});
|
||||
}else if(source === 'custombackend'){
|
||||
Session.url('custombackend').then((url) => {
|
||||
window.location.href = url;
|
||||
}).catch((err) => {
|
||||
this.setState({loading: false});
|
||||
notify.send(err, 'error');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export class Form extends React.Component {
|
|||
};
|
||||
|
||||
const select = settings_get("login_tab");
|
||||
if(select !== null){ this.state.select = select; }
|
||||
if(select !== null && select < CONFIG["connections"].length){ this.state.select = select; }
|
||||
this.rerender = this.rerender.bind(this);
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ export class Form extends React.Component {
|
|||
{
|
||||
this.state.backends.map((backend, i) => {
|
||||
return (
|
||||
<Button key={"menu-"+i} className={i == this.state.select ? "active primary" : ""} onClick={this.onTypeChange.bind(this, i)}>
|
||||
<Button key={"menu-"+i} className={i === this.state.select ? "active primary" : ""} onClick={this.onTypeChange.bind(this, i)}>
|
||||
{backend.label}
|
||||
</Button>
|
||||
);
|
||||
|
|
@ -107,7 +107,7 @@ export class Form extends React.Component {
|
|||
{
|
||||
this.state.backends.map((conn, i) => {
|
||||
return (
|
||||
<NgIf key={"form-"+i} cond={this.state.select == i}>
|
||||
<NgIf key={"form-"+i} cond={this.state.select === i}>
|
||||
<NgIf cond={conn.type === "webdav"}>
|
||||
<WebDavForm values={conn} config={CONFIG["connections"][i]} onChange={this.onFormUpdate.bind(this, i)} />
|
||||
</NgIf>
|
||||
|
|
@ -129,6 +129,9 @@ export class Form extends React.Component {
|
|||
<NgIf cond={conn.type === "gdrive"} className="third-party">
|
||||
<GDriveForm values={conn} config={CONFIG["connections"][i]} onThirdPartyLogin={this.redirect.bind(this)} />
|
||||
</NgIf>
|
||||
<NgIf cond={conn.type === "custombackend"} className="third-party">
|
||||
<CustomForm values={conn} config={CONFIG["connections"][i]} onThirdPartyLogin={this.redirect.bind(this)} />
|
||||
</NgIf>
|
||||
</NgIf>
|
||||
);
|
||||
})
|
||||
|
|
@ -142,7 +145,7 @@ export class Form extends React.Component {
|
|||
|
||||
const WebDavForm = formHelper(function(props){
|
||||
const onAdvanced = (value) => {
|
||||
if(value == true){
|
||||
if(value === true){
|
||||
props.values.path = "";
|
||||
}else{
|
||||
delete props.values.path;
|
||||
|
|
@ -179,7 +182,7 @@ const WebDavForm = formHelper(function(props){
|
|||
|
||||
const FtpForm = formHelper(function(props){
|
||||
const onAdvanced = (value) => {
|
||||
if(value == true){
|
||||
if(value === true){
|
||||
props.values.path = "";
|
||||
props.values.port = "";
|
||||
}else{
|
||||
|
|
@ -227,7 +230,7 @@ const FtpForm = formHelper(function(props){
|
|||
|
||||
const SftpForm = formHelper(function(props){
|
||||
const onAdvanced = (value) => {
|
||||
if(value == true){
|
||||
if(value === true){
|
||||
props.values.path = "";
|
||||
props.values.port = "";
|
||||
props.values.passphrase = "";
|
||||
|
|
@ -279,7 +282,7 @@ const SftpForm = formHelper(function(props){
|
|||
|
||||
const GitForm = formHelper(function(props){
|
||||
const onAdvanced = (value) => {
|
||||
if(value == true){
|
||||
if(value === true){
|
||||
props.values.path = "";
|
||||
props.values.passphrase = "";
|
||||
props.values.commit = "";
|
||||
|
|
@ -361,7 +364,7 @@ const GitForm = formHelper(function(props){
|
|||
|
||||
const S3Form = formHelper(function(props){
|
||||
const onAdvanced = (value) => {
|
||||
if(value == true){
|
||||
if(value === true){
|
||||
props.values.path = "";
|
||||
props.values.endpoint = "";
|
||||
props.values.region = "";
|
||||
|
|
@ -417,6 +420,9 @@ const DropboxForm = formHelper(function(props){
|
|||
const redirect = () => {
|
||||
return props.onThirdPartyLogin("dropbox");
|
||||
};
|
||||
if(CONFIG.connections.length === 1){
|
||||
redirect();
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div onClick={redirect}>
|
||||
|
|
@ -431,6 +437,9 @@ const GDriveForm = formHelper(function(props){
|
|||
const redirect = () => {
|
||||
return props.onThirdPartyLogin("google");
|
||||
};
|
||||
if(CONFIG.connections.length === 1){
|
||||
redirect();
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div onClick={redirect}>
|
||||
|
|
@ -441,6 +450,22 @@ const GDriveForm = formHelper(function(props){
|
|||
);
|
||||
});
|
||||
|
||||
const CustomForm = formHelper(function(props){
|
||||
const redirect = () => {
|
||||
return props.onThirdPartyLogin("custombackend");
|
||||
};
|
||||
|
||||
if(CONFIG.connections.length === 1 && CONFIG.auto_connect === true){
|
||||
redirect();
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Button type="button" onClick={redirect} theme="emphasis">LOGIN</Button>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
function formHelper(WrappedComponent){
|
||||
return (props) => {
|
||||
const helpers = {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
display: flex;
|
||||
margin: -10px -11px 10px;
|
||||
padding: 0px 0px 6px 0;
|
||||
overflow-x: auto;
|
||||
button{
|
||||
min-width: 80px;
|
||||
border-top-left-radius: 0;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ self.onmessage = function(message){
|
|||
}, null, () => {
|
||||
self.postMessage({type: "search::completed"})
|
||||
});
|
||||
}else if(message.data.action === "search::index"){
|
||||
Indexing(message.data.config);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
"fork_button": true,
|
||||
"display_hidden": false,
|
||||
"client_search_enable": true,
|
||||
"client_search_per_min": 20
|
||||
"client_search_per_min": 20,
|
||||
"auto_connect": false
|
||||
},
|
||||
"log": {
|
||||
"enable": true,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ type Config struct {
|
|||
Editor string `json:"editor"`
|
||||
ForkButton bool `json:"fork_button"`
|
||||
DisplayHidden bool `json:"display_hidden"`
|
||||
AutoConnect bool `json:"auto_connect"`
|
||||
} `json:"general"`
|
||||
Log struct {
|
||||
Enable bool `json:"enable"`
|
||||
|
|
@ -41,6 +42,10 @@ type Config struct {
|
|||
ClientID string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
} `json:"gdrive"`
|
||||
Custom struct {
|
||||
ClientID string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
} `json:"custom"`
|
||||
} `json:"oauth"`
|
||||
Connections []struct {
|
||||
Type string `json:"type"`
|
||||
|
|
@ -67,8 +72,8 @@ type Config struct {
|
|||
Dirname string
|
||||
ConfigPath string
|
||||
FirstSetup bool
|
||||
} `-`
|
||||
MimeTypes map[string]string `json:"mimetypes,omitempty"`
|
||||
} `json:"-"`
|
||||
MimeTypes map[string]string `json:"-"`
|
||||
}
|
||||
|
||||
func (c *Config) Initialise() {
|
||||
|
|
@ -161,12 +166,14 @@ func (c *Config) Export() (string, error) {
|
|||
Editor string `json:"editor"`
|
||||
ForkButton bool `json:"fork_button"`
|
||||
DisplayHidden bool `json:"display_hidden"`
|
||||
AutoConnect bool `json:"auto_connect"`
|
||||
Connections interface{} `json:"connections"`
|
||||
MimeTypes map[string]string `json:"mime"`
|
||||
}{
|
||||
Editor: c.General.Editor,
|
||||
ForkButton: c.General.ForkButton,
|
||||
DisplayHidden: c.General.DisplayHidden,
|
||||
AutoConnect: c.General.AutoConnect,
|
||||
Connections: c.Connections,
|
||||
MimeTypes: c.MimeTypes,
|
||||
}
|
||||
|
|
|
|||
42
server/model/backend/custombackend.go
Normal file
42
server/model/backend/custombackend.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package backend
|
||||
|
||||
import (
|
||||
. "github.com/mickael-kerjean/nuage/server/common"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type CustomBackend struct {
|
||||
}
|
||||
|
||||
func NewCustomBackend(params map[string]string, app *App) (*CustomBackend, error) {
|
||||
return &CustomBackend{}, nil
|
||||
}
|
||||
|
||||
func (b CustomBackend) Info() string {
|
||||
return "N/A"
|
||||
}
|
||||
|
||||
func (b CustomBackend) Ls(path string) ([]os.FileInfo, error) {
|
||||
return nil, NewError("", 401)
|
||||
}
|
||||
|
||||
func (b CustomBackend) Cat(path string) (io.Reader, error) {
|
||||
return strings.NewReader(""), NewError("", 401)
|
||||
}
|
||||
func (b CustomBackend) Mkdir(path string) error {
|
||||
return NewError("", 401)
|
||||
}
|
||||
func (b CustomBackend) Rm(path string) error {
|
||||
return NewError("", 401)
|
||||
}
|
||||
func (b CustomBackend) Mv(from string, to string) error {
|
||||
return NewError("", 401)
|
||||
}
|
||||
func (b CustomBackend) Touch(path string) error {
|
||||
return NewError("", 401)
|
||||
}
|
||||
func (b CustomBackend) Save(path string, file io.Reader) error {
|
||||
return NewError("", 401)
|
||||
}
|
||||
|
|
@ -21,6 +21,8 @@ func NewBackend(ctx *App, conn map[string]string) (IBackend, error) {
|
|||
return backend.NewDropbox(conn, ctx)
|
||||
case "gdrive":
|
||||
return backend.NewGDrive(conn, ctx)
|
||||
case "custombackend":
|
||||
return backend.NewCustomBackend(conn, ctx)
|
||||
default:
|
||||
return backend.NewNothing(conn, ctx)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,10 +45,12 @@ func SessionAuthenticate(ctx App, res http.ResponseWriter, req *http.Request) {
|
|||
err := obj.OAuthToken(&ctx.Body)
|
||||
if err != nil {
|
||||
sendErrorResult(res, NewError("Can't authenticate (OAuth error)", 401))
|
||||
return
|
||||
}
|
||||
backend, err = model.NewBackend(&ctx, ctx.Body)
|
||||
if err != nil {
|
||||
sendErrorResult(res, NewError("Can't authenticate", 401))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue