mirror of
https://github.com/balzack/databag.git
synced 2025-02-11 19:19:16 +00:00
changing default asset path
This commit is contained in:
parent
54b9737cd6
commit
7e824d19b3
@ -273,13 +273,6 @@ paths:
|
||||
- account
|
||||
description: Check if any public accounts are available
|
||||
operationId: get-account-available
|
||||
parameters:
|
||||
- name: public
|
||||
in: query
|
||||
description: for open access accounts
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
responses:
|
||||
'200':
|
||||
description: available public accounts
|
||||
|
@ -2,6 +2,7 @@ package databag
|
||||
|
||||
import (
|
||||
"os"
|
||||
"errors"
|
||||
"net/http"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
@ -10,11 +11,23 @@ import (
|
||||
)
|
||||
|
||||
func AddAccount(w http.ResponseWriter, r *http.Request) {
|
||||
var token *store.AccountToken
|
||||
|
||||
token, res := BearerAccountToken(r);
|
||||
if res != nil || token.TokenType != APP_TOKENCREATE {
|
||||
ErrResponse(w, http.StatusUnauthorized, res)
|
||||
return
|
||||
if r.Header.Get("Authorization") == "" {
|
||||
if available, err := getAvailableAccounts(); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
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);
|
||||
@ -23,6 +36,17 @@ func AddAccount(w http.ResponseWriter, r *http.Request) {
|
||||
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
|
||||
privateKey, publicKey, keyType, err := GenerateRsaKeyPair()
|
||||
if err != nil {
|
||||
@ -42,7 +66,7 @@ func AddAccount(w http.ResponseWriter, r *http.Request) {
|
||||
fingerprint := hex.EncodeToString(hash[:])
|
||||
|
||||
// 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 {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
}
|
||||
@ -68,8 +92,10 @@ func AddAccount(w http.ResponseWriter, r *http.Request) {
|
||||
if res := tx.Create(&account).Error; res != nil {
|
||||
return res;
|
||||
}
|
||||
if res := tx.Delete(token).Error; res != nil {
|
||||
return res;
|
||||
if token != nil {
|
||||
if res := tx.Delete(token).Error; res != nil {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
});
|
||||
|
@ -70,7 +70,7 @@ func AddChannelTopicAsset(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// save new file
|
||||
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 {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
|
@ -7,21 +7,28 @@ import (
|
||||
|
||||
func GetAccountAvailable(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
public := r.FormValue("public") == "true"
|
||||
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 {
|
||||
available, err := getAvailableAccounts()
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
var available int64
|
||||
if (!public || open) && limit > count {
|
||||
available = limit - count
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
)
|
||||
@ -10,23 +11,33 @@ type accountUsername struct {
|
||||
}
|
||||
|
||||
func GetAccountUsername(w http.ResponseWriter, r *http.Request) {
|
||||
var token *store.AccountToken
|
||||
|
||||
token, err := BearerAccountToken(r);
|
||||
if err != nil || (token.TokenType != "create" && token.TokenType != "reset") {
|
||||
LogMsg("invalid token")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
if r.Header.Get("Authorization") == "" {
|
||||
if available, err := getAvailableAccounts(); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
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")
|
||||
if username == "" {
|
||||
LogMsg("invalid username")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
ErrResponse(w, http.StatusBadRequest, errors.New("specify a username"))
|
||||
return
|
||||
}
|
||||
|
||||
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 {
|
||||
LogMsg("failed to query accounts")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
@ -42,7 +42,7 @@ func GetChannelTopicAsset(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ func RemoveAccount(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// delete asset files
|
||||
path := getStrConfigValue(CONFIG_ASSETPATH, ".") + "/" + account.Guid
|
||||
path := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH) + "/" + account.Guid
|
||||
if err = os.RemoveAll(path); err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ func RemoveNodeAccount(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// delete asset files
|
||||
path := getStrConfigValue(CONFIG_ASSETPATH, ".") + "/" + account.Guid
|
||||
path := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH) + "/" + account.Guid
|
||||
if err = os.RemoveAll(path); err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ const APP_QUEUEAUDIO = "audio"
|
||||
const APP_QUEUEVIDEO = "video"
|
||||
const APP_QUEUEPHOTO = "photo"
|
||||
const APP_QUEUEDEFAULT = ""
|
||||
const APP_DEFAULTPATH = "./asset"
|
||||
|
||||
func AppCardStatus(status string) bool {
|
||||
if status == APP_CARDPENDING {
|
||||
|
@ -60,7 +60,7 @@ func AccountLogin(r *http.Request) (*store.Account, error) {
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func BearerAccountToken(r *http.Request) (store.AccountToken, error) {
|
||||
func BearerAccountToken(r *http.Request) (*store.AccountToken, error) {
|
||||
|
||||
// parse bearer authentication
|
||||
auth := r.Header.Get("Authorization")
|
||||
@ -69,12 +69,12 @@ func BearerAccountToken(r *http.Request) (store.AccountToken, error) {
|
||||
// find token record
|
||||
var accountToken store.AccountToken
|
||||
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() {
|
||||
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) {
|
||||
|
@ -13,7 +13,7 @@ func garbageCollect(act *store.Account) {
|
||||
defer garbageSync.Unlock()
|
||||
|
||||
// get all asset files
|
||||
dir := getStrConfigValue(CONFIG_ASSETPATH, ".") + "/" + act.Guid
|
||||
dir := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH) + "/" + act.Guid
|
||||
files, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
ErrMsg(err)
|
||||
|
@ -89,7 +89,7 @@ func transcodeDefault() {
|
||||
func transcodeAsset(asset *store.Asset) {
|
||||
|
||||
// prepare script path
|
||||
data := getStrConfigValue(CONFIG_ASSETPATH, ".")
|
||||
data := getStrConfigValue(CONFIG_ASSETPATH, APP_DEFAULTPATH)
|
||||
script := getStrConfigValue(CONFIG_SCRIPTPATH, ".")
|
||||
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 { Input, Button } from 'antd';
|
||||
import { UserOutlined, LockOutlined } from '@ant-design/icons';
|
||||
|
||||
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() {
|
||||
const [available, setAvailable] = useState(0)
|
||||
const [username, setUsername] = 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 = () => {
|
||||
console.log(username)
|
||||
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' }} />
|
||||
<Button type="primary" onClick={onLogin} style={{ alignSelf: 'center', marginTop: '16px', width: '33%' }}>Sign In</Button>
|
||||
</div>
|
||||
<Button type="link" onClick={onCreate} style={{ marginTop: '4px', color: '#000044' }}>Create Account</Button>
|
||||
<Create />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user