mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
changing default asset path
This commit is contained in:
parent
54b9737cd6
commit
7e824d19b3
@ -273,13 +273,6 @@ paths:
|
|||||||
- account
|
- account
|
||||||
description: Check if any public accounts are available
|
description: Check if any public accounts are available
|
||||||
operationId: get-account-available
|
operationId: get-account-available
|
||||||
parameters:
|
|
||||||
- name: public
|
|
||||||
in: query
|
|
||||||
description: for open access accounts
|
|
||||||
required: false
|
|
||||||
schema:
|
|
||||||
type: boolean
|
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: available public accounts
|
description: available public accounts
|
||||||
|
@ -2,6 +2,7 @@ package databag
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
@ -10,11 +11,23 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func AddAccount(w http.ResponseWriter, r *http.Request) {
|
func AddAccount(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var token *store.AccountToken
|
||||||
|
|
||||||
token, res := BearerAccountToken(r);
|
if r.Header.Get("Authorization") == "" {
|
||||||
if res != nil || token.TokenType != APP_TOKENCREATE {
|
if available, err := getAvailableAccounts(); err != nil {
|
||||||
ErrResponse(w, http.StatusUnauthorized, res)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
|
} else if available == 0 {
|
||||||
|
ErrResponse(w, http.StatusForbidden, errors.New("no open accounts available"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
token, err = BearerAccountToken(r);
|
||||||
|
if err != nil || token.TokenType != APP_TOKENCREATE {
|
||||||
|
ErrResponse(w, http.StatusUnauthorized, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
username, password, ret := BasicCredentials(r);
|
username, password, ret := BasicCredentials(r);
|
||||||
@ -23,6 +36,17 @@ func AddAccount(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if username is taken
|
||||||
|
var count int64
|
||||||
|
if err := store.DB.Model(&store.Account{}).Where("username = ?", username).Count(&count).Error; err != nil {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, err);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if count != 0 {
|
||||||
|
ErrResponse(w, http.StatusConflict, errors.New("username already taken"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// generate account key
|
// generate account key
|
||||||
privateKey, publicKey, keyType, err := GenerateRsaKeyPair()
|
privateKey, publicKey, keyType, err := GenerateRsaKeyPair()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -42,7 +66,7 @@ func AddAccount(w http.ResponseWriter, r *http.Request) {
|
|||||||
fingerprint := hex.EncodeToString(hash[:])
|
fingerprint := hex.EncodeToString(hash[:])
|
||||||
|
|
||||||
// create path for account data
|
// create path for account data
|
||||||
path := getStrConfigValue(CONFIG_ASSETPATH, ".") + "/" + fingerprint
|
path := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH) + "/" + fingerprint
|
||||||
if err := os.Mkdir(path, os.ModePerm); err != nil {
|
if err := os.Mkdir(path, os.ModePerm); err != nil {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
@ -68,9 +92,11 @@ func AddAccount(w http.ResponseWriter, r *http.Request) {
|
|||||||
if res := tx.Create(&account).Error; res != nil {
|
if res := tx.Create(&account).Error; res != nil {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
if token != nil {
|
||||||
if res := tx.Delete(token).Error; res != nil {
|
if res := tx.Delete(token).Error; res != nil {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil;
|
return nil;
|
||||||
});
|
});
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -70,7 +70,7 @@ func AddChannelTopicAsset(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// save new file
|
// save new file
|
||||||
id := uuid.New().String()
|
id := uuid.New().String()
|
||||||
path := getStrConfigValue(CONFIG_ASSETPATH, ".") + "/" + channelSlot.Account.Guid + "/" + id
|
path := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH) + "/" + channelSlot.Account.Guid + "/" + id
|
||||||
if err := r.ParseMultipartForm(32 << 20); err != nil {
|
if err := r.ParseMultipartForm(32 << 20); err != nil {
|
||||||
ErrResponse(w, http.StatusBadRequest, err)
|
ErrResponse(w, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
|
@ -7,21 +7,28 @@ import (
|
|||||||
|
|
||||||
func GetAccountAvailable(w http.ResponseWriter, r *http.Request) {
|
func GetAccountAvailable(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
public := r.FormValue("public") == "true"
|
available, err := getAvailableAccounts()
|
||||||
open := getBoolConfigValue(CONFIG_OPENACCESS, true)
|
if err != nil {
|
||||||
limit := getNumConfigValue(CONFIG_ACCOUNTLIMIT, 16)
|
|
||||||
|
|
||||||
var count int64
|
|
||||||
if err := store.DB.Model(&store.Account{}).Count(&count).Error; err != nil {
|
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var available int64
|
|
||||||
if (!public || open) && limit > count {
|
|
||||||
available = limit - count
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteResponse(w, &available)
|
WriteResponse(w, &available)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAvailableAccounts() (available int64, err error) {
|
||||||
|
|
||||||
|
open := getBoolConfigValue(CONFIG_OPENACCESS, true)
|
||||||
|
limit := getNumConfigValue(CONFIG_ACCOUNTLIMIT, 16)
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
if err = store.DB.Model(&store.Account{}).Count(&count).Error; err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if open && limit > count {
|
||||||
|
available = limit - count
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package databag
|
package databag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"databag/internal/store"
|
"databag/internal/store"
|
||||||
)
|
)
|
||||||
@ -10,23 +11,33 @@ type accountUsername struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetAccountUsername(w http.ResponseWriter, r *http.Request) {
|
func GetAccountUsername(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var token *store.AccountToken
|
||||||
|
|
||||||
token, err := BearerAccountToken(r);
|
if r.Header.Get("Authorization") == "" {
|
||||||
if err != nil || (token.TokenType != "create" && token.TokenType != "reset") {
|
if available, err := getAvailableAccounts(); err != nil {
|
||||||
LogMsg("invalid token")
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
return
|
return
|
||||||
|
} else if available == 0 {
|
||||||
|
ErrResponse(w, http.StatusUnauthorized, errors.New("no open accounts available"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
token, err = BearerAccountToken(r);
|
||||||
|
if err != nil || token.TokenType != APP_TOKENCREATE {
|
||||||
|
ErrResponse(w, http.StatusUnauthorized, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
username := r.URL.Query().Get("username")
|
username := r.URL.Query().Get("username")
|
||||||
if username == "" {
|
if username == "" {
|
||||||
LogMsg("invalid username")
|
ErrResponse(w, http.StatusBadRequest, errors.New("specify a username"))
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var accounts []accountUsername;
|
var accounts []accountUsername;
|
||||||
err = store.DB.Model(&store.Account{}).Where("username = ?", username).Find(&accounts).Error
|
err := store.DB.Model(&store.Account{}).Where("username = ?", username).Find(&accounts).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogMsg("failed to query accounts")
|
LogMsg("failed to query accounts")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
@ -42,7 +42,7 @@ func GetChannelTopicAsset(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// construct file path
|
// construct file path
|
||||||
path := getStrConfigValue(CONFIG_ASSETPATH, ".") + "/" + act.Guid + "/" + asset.AssetId
|
path := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH) + "/" + act.Guid + "/" + asset.AssetId
|
||||||
http.ServeFile(w, r, path)
|
http.ServeFile(w, r, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ func RemoveAccount(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delete asset files
|
// delete asset files
|
||||||
path := getStrConfigValue(CONFIG_ASSETPATH, ".") + "/" + account.Guid
|
path := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH) + "/" + account.Guid
|
||||||
if err = os.RemoveAll(path); err != nil {
|
if err = os.RemoveAll(path); err != nil {
|
||||||
ErrMsg(err)
|
ErrMsg(err)
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ func RemoveNodeAccount(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delete asset files
|
// delete asset files
|
||||||
path := getStrConfigValue(CONFIG_ASSETPATH, ".") + "/" + account.Guid
|
path := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH) + "/" + account.Guid
|
||||||
if err = os.RemoveAll(path); err != nil {
|
if err = os.RemoveAll(path); err != nil {
|
||||||
ErrMsg(err)
|
ErrMsg(err)
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ const APP_QUEUEAUDIO = "audio"
|
|||||||
const APP_QUEUEVIDEO = "video"
|
const APP_QUEUEVIDEO = "video"
|
||||||
const APP_QUEUEPHOTO = "photo"
|
const APP_QUEUEPHOTO = "photo"
|
||||||
const APP_QUEUEDEFAULT = ""
|
const APP_QUEUEDEFAULT = ""
|
||||||
|
const APP_DEFAULTPATH = "./asset"
|
||||||
|
|
||||||
func AppCardStatus(status string) bool {
|
func AppCardStatus(status string) bool {
|
||||||
if status == APP_CARDPENDING {
|
if status == APP_CARDPENDING {
|
||||||
|
@ -60,7 +60,7 @@ func AccountLogin(r *http.Request) (*store.Account, error) {
|
|||||||
return account, nil
|
return account, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BearerAccountToken(r *http.Request) (store.AccountToken, error) {
|
func BearerAccountToken(r *http.Request) (*store.AccountToken, error) {
|
||||||
|
|
||||||
// parse bearer authentication
|
// parse bearer authentication
|
||||||
auth := r.Header.Get("Authorization")
|
auth := r.Header.Get("Authorization")
|
||||||
@ -69,12 +69,12 @@ func BearerAccountToken(r *http.Request) (store.AccountToken, error) {
|
|||||||
// find token record
|
// find token record
|
||||||
var accountToken store.AccountToken
|
var accountToken store.AccountToken
|
||||||
if err := store.DB.Preload("Account").Where("token = ?", token).First(&accountToken).Error; err != nil {
|
if err := store.DB.Preload("Account").Where("token = ?", token).First(&accountToken).Error; err != nil {
|
||||||
return accountToken, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if accountToken.Expires < time.Now().Unix() {
|
if accountToken.Expires < time.Now().Unix() {
|
||||||
return accountToken, errors.New("expired token")
|
return nil, errors.New("expired token")
|
||||||
}
|
}
|
||||||
return accountToken, nil
|
return &accountToken, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BearerAppToken(r *http.Request, detail bool) (*store.Account, int, error) {
|
func BearerAppToken(r *http.Request, detail bool) (*store.Account, int, error) {
|
||||||
|
@ -13,7 +13,7 @@ func garbageCollect(act *store.Account) {
|
|||||||
defer garbageSync.Unlock()
|
defer garbageSync.Unlock()
|
||||||
|
|
||||||
// get all asset files
|
// get all asset files
|
||||||
dir := getStrConfigValue(CONFIG_ASSETPATH, ".") + "/" + act.Guid
|
dir := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH) + "/" + act.Guid
|
||||||
files, err := os.ReadDir(dir)
|
files, err := os.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrMsg(err)
|
ErrMsg(err)
|
||||||
|
@ -89,7 +89,7 @@ func transcodeDefault() {
|
|||||||
func transcodeAsset(asset *store.Asset) {
|
func transcodeAsset(asset *store.Asset) {
|
||||||
|
|
||||||
// prepare script path
|
// prepare script path
|
||||||
data := getStrConfigValue(CONFIG_ASSETPATH, ".")
|
data := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH)
|
||||||
script := getStrConfigValue(CONFIG_SCRIPTPATH, ".")
|
script := getStrConfigValue(CONFIG_SCRIPTPATH, ".")
|
||||||
re := regexp.MustCompile("^[a-zA-Z0-9_]*$")
|
re := regexp.MustCompile("^[a-zA-Z0-9_]*$")
|
||||||
|
|
||||||
|
@ -1,14 +1,54 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import login from './login.png';
|
import login from './login.png';
|
||||||
import { Input, Button } from 'antd';
|
import { Input, Button } from 'antd';
|
||||||
import { UserOutlined, LockOutlined } from '@ant-design/icons';
|
import { UserOutlined, LockOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
import 'antd/dist/antd.css';
|
import 'antd/dist/antd.css';
|
||||||
|
|
||||||
|
const FETCH_TIMEOUT = 15000;
|
||||||
|
|
||||||
|
function checkResponse(response) {
|
||||||
|
if(response.status >= 400 && response.status < 600) {
|
||||||
|
throw new Error(response.url + " failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchWithTimeout(url, options) {
|
||||||
|
return Promise.race([
|
||||||
|
fetch(url, options).catch(err => { throw new Error(url + ' failed'); }),
|
||||||
|
new Promise((_, reject) => setTimeout(() => reject(new Error(url + ' timeout')), FETCH_TIMEOUT))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAvailable() {
|
||||||
|
let available = await fetchWithTimeout("/account/available", { method: 'GET', timeout: FETCH_TIMEOUT } );
|
||||||
|
checkResponse(available);
|
||||||
|
return await available.json()
|
||||||
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
const [available, setAvailable] = useState(0)
|
||||||
const [username, setUsername] = useState('')
|
const [username, setUsername] = useState('')
|
||||||
const [password, setPassword] = useState('')
|
const [password, setPassword] = useState('')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
getAvailable().then(a => {
|
||||||
|
setAvailable(a)
|
||||||
|
console.log(a)
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const Create = () => {
|
||||||
|
if (available > 0) {
|
||||||
|
return <Button type="link" onClick={onCreate} style={{ marginTop: '4px', color: '#000044' }}>Create Account</Button>
|
||||||
|
}
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
const onLogin = () => {
|
const onLogin = () => {
|
||||||
console.log(username)
|
console.log(username)
|
||||||
console.log(password)
|
console.log(password)
|
||||||
@ -31,7 +71,7 @@ function App() {
|
|||||||
<Input.Password size="large" onChange={(e) => setPassword(e.target.value)} placeholder="password" prefix={<LockOutlined />} style={{ marginTop: '16px' }} />
|
<Input.Password size="large" onChange={(e) => setPassword(e.target.value)} placeholder="password" prefix={<LockOutlined />} style={{ marginTop: '16px' }} />
|
||||||
<Button type="primary" onClick={onLogin} style={{ alignSelf: 'center', marginTop: '16px', width: '33%' }}>Sign In</Button>
|
<Button type="primary" onClick={onLogin} style={{ alignSelf: 'center', marginTop: '16px', width: '33%' }}>Sign In</Button>
|
||||||
</div>
|
</div>
|
||||||
<Button type="link" onClick={onCreate} style={{ marginTop: '4px', color: '#000044' }}>Create Account</Button>
|
<Create />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user