mirror of
https://github.com/balzack/databag.git
synced 2025-03-13 00:50:03 +00:00
extending add account test
This commit is contained in:
parent
17602f169a
commit
a5a02d7abb
@ -1,7 +1,6 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
"net/http/httptest"
|
||||
"encoding/base64"
|
||||
@ -22,6 +21,7 @@ func TestAccount(t *testing.T) {
|
||||
dec.Decode(&token);
|
||||
if resp.StatusCode != 200 {
|
||||
t.Errorf("failed to create account")
|
||||
return
|
||||
}
|
||||
|
||||
// validate account token
|
||||
@ -32,13 +32,32 @@ func TestAccount(t *testing.T) {
|
||||
resp = w.Result();
|
||||
if resp.StatusCode != 200 {
|
||||
t.Errorf("invalid token value")
|
||||
return
|
||||
}
|
||||
dec = json.NewDecoder(resp.Body);
|
||||
var tokenType string;
|
||||
dec.Decode(&tokenType);
|
||||
if tokenType != "create" {
|
||||
t.Errorf("invalid token type")
|
||||
return
|
||||
}
|
||||
|
||||
// check if username is available
|
||||
r = httptest.NewRequest("GET", "/account/claimable?username=databag", nil)
|
||||
r.Header.Add("Authorization","Bearer " + token)
|
||||
w = httptest.NewRecorder()
|
||||
GetAccountUsername(w, r);
|
||||
resp = w.Result();
|
||||
if resp.StatusCode != 200 {
|
||||
t.Errorf("invalid token value")
|
||||
return
|
||||
}
|
||||
dec = json.NewDecoder(resp.Body);
|
||||
var available bool;
|
||||
dec.Decode(&available);
|
||||
if !available {
|
||||
t.Errorf("username not available")
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("TestAccount: done");
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"log"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
"github.com/theckman/go-securerandom"
|
||||
@ -10,35 +8,26 @@ import (
|
||||
|
||||
func AddNodeAccount(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// validate login
|
||||
if !adminLogin(r) {
|
||||
log.Printf("AddNodeAccount - invalid admin credentials");
|
||||
LogMsg("invalid admin credentials");
|
||||
w.WriteHeader(http.StatusUnauthorized);
|
||||
return
|
||||
}
|
||||
|
||||
data, err := securerandom.Base64OfBytes(32)
|
||||
if err != nil {
|
||||
log.Println("AddNodeAccount - failed to generate token");
|
||||
LogMsg("failed to generate token");
|
||||
w.WriteHeader(http.StatusInternalServerError);
|
||||
return
|
||||
}
|
||||
|
||||
token := store.AccountToken{TokenType: "create", Token: data };
|
||||
if res := store.DB.Create(&token).Error; res != nil {
|
||||
log.Println("AddNodeAccount - failed to store token");
|
||||
LogMsg("failed to store token");
|
||||
w.WriteHeader(http.StatusInternalServerError);
|
||||
return
|
||||
}
|
||||
|
||||
body, err := json.Marshal(data);
|
||||
if err != nil {
|
||||
log.Println("GetNodeConfig - failed to marshal response");
|
||||
w.WriteHeader(http.StatusInternalServerError);
|
||||
return
|
||||
}
|
||||
w.Write(body)
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
WriteResponse(w, data);
|
||||
}
|
||||
|
||||
|
@ -1,37 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func adminLogin(r *http.Request) bool {
|
||||
|
||||
// extract request auth
|
||||
username, password, ok := r.BasicAuth();
|
||||
if !ok || username == "" || password == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// nothing to do if not configured
|
||||
if !getBoolConfigValue(CONFIG_CONFIGURED, false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// compare username
|
||||
if getStrConfigValue(CONFIG_USERNAME, "") != username {
|
||||
return false
|
||||
}
|
||||
|
||||
// compare password
|
||||
p := getBinConfigValue(CONFIG_PASSWORD, nil);
|
||||
if bcrypt.CompareHashAndPassword(p, []byte(password)) != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
func bearerAuth(r *http.Request) string {
|
||||
return "";
|
||||
}
|
@ -63,11 +63,6 @@ func GetAccountStatus(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetAccountUsername(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetPublicClaimable(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
@ -49,13 +49,13 @@ func Status(w http.ResponseWriter, r *http.Request) {
|
||||
var act uint = 0
|
||||
|
||||
// get revisions for the account
|
||||
var ar accountRevision
|
||||
err = store.DB.Model(&Revision{}).Where("ID = ?", act).First(&ar).Error
|
||||
var account accountRevision
|
||||
err = store.DB.Model(&store.Account{}).Where("ID = ?", act).First(&account).Error
|
||||
if err != nil {
|
||||
log.Println("Status - failed to get account revision")
|
||||
// return
|
||||
}
|
||||
rev := getRevision(ar)
|
||||
rev := getRevision(account)
|
||||
|
||||
// send current version
|
||||
var msg []byte
|
||||
|
@ -1,45 +1,19 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
"errors"
|
||||
"net/http"
|
||||
"encoding/json"
|
||||
"gorm.io/gorm"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetAccountToken(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// extract token
|
||||
auth := r.Header.Get("Authorization")
|
||||
token := strings.TrimSpace(strings.TrimPrefix(auth, "Bearer"))
|
||||
|
||||
// lookup token
|
||||
var accountToken store.AccountToken
|
||||
err := store.DB.Where("token = ?", token).First(&accountToken).Error
|
||||
accountToken, err := bearerAccountToken(r);
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
log.Println("GetAccountToken - token not found");
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
} else {
|
||||
log.Println("GetAccountToken - failed to retrieve token");
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
LogMsg("token not found");
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
// return token type
|
||||
body, err := json.Marshal(accountToken.TokenType);
|
||||
if err != nil {
|
||||
log.Println("GetNodeConfig - failed to marshal response");
|
||||
w.WriteHeader(http.StatusInternalServerError);
|
||||
return
|
||||
}
|
||||
w.Write(body);
|
||||
w.Header().Set("Content-Type", "application/json charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
WriteResponse(w, accountToken.TokenType);
|
||||
}
|
||||
|
||||
|
||||
|
42
net/server/internal/getAccountUsername_endpoint.go
Normal file
42
net/server/internal/getAccountUsername_endpoint.go
Normal file
@ -0,0 +1,42 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
type accountUsername struct {
|
||||
Username string
|
||||
}
|
||||
|
||||
func GetAccountUsername(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
_, err := bearerAccountToken(r);
|
||||
if err != nil {
|
||||
LogMsg("authentication failed")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
username := r.URL.Query().Get("username")
|
||||
if username == "" {
|
||||
LogMsg("invalid username")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var accounts []accountUsername;
|
||||
err = store.DB.Model(&store.Account{}).Where("username = ?", username).Find(&accounts).Error
|
||||
if err != nil {
|
||||
LogMsg("failed to query accounts")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if len(accounts) == 0 {
|
||||
WriteResponse(w, true)
|
||||
} else {
|
||||
WriteResponse(w, false)
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,23 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"log"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetNodeClaimable(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
c := getBoolConfigValue(CONFIG_CONFIGURED, false);
|
||||
body, err := json.Marshal(!c);
|
||||
var config store.Config
|
||||
err := store.DB.Where("config_id = ?", CONFIG_CONFIGURED).First(&config).Error
|
||||
if err != nil {
|
||||
log.Println("GetNodeClaimable - failed to marshal response");
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
WriteResponse(w, true)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusInternalServerError);
|
||||
}
|
||||
return
|
||||
}
|
||||
w.Write(body);
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
WriteResponse(w, false);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"log"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@ -10,7 +8,7 @@ func GetNodeConfig(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// validate login
|
||||
if !adminLogin(r) {
|
||||
log.Printf("SetNodeConfig - invalid admin credentials");
|
||||
LogMsg("SetNodeConfig - invalid admin credentials");
|
||||
w.WriteHeader(http.StatusUnauthorized);
|
||||
return
|
||||
}
|
||||
@ -21,12 +19,6 @@ func GetNodeConfig(w http.ResponseWriter, r *http.Request) {
|
||||
config.PublicLimit = getNumConfigValue(CONFIG_PUBLICLIMIT, 0);
|
||||
config.AccountStorage = getNumConfigValue(CONFIG_STORAGE, 0);
|
||||
|
||||
body, err := json.Marshal(config);
|
||||
if err != nil {
|
||||
log.Println("GetNodeConfig - failed to marshal response");
|
||||
}
|
||||
w.Write(body);
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
WriteResponse(w, config);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,9 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Logger(inner http.Handler, name string) http.Handler {
|
||||
@ -30,3 +33,9 @@ func Logger(inner http.Handler, name string) http.Handler {
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func LogMsg(msg string) {
|
||||
_, file, line, _ := runtime.Caller(1)
|
||||
p, _ := os.Getwd()
|
||||
log.Printf("%s:%d %s", strings.TrimPrefix(file, p), line, msg)
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ func Claim() {
|
||||
w := httptest.NewRecorder()
|
||||
SetNodeClaim(w, r)
|
||||
if w.Code != 200 {
|
||||
LogMsg("HERE");
|
||||
panic("server not initially claimable")
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"log"
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"databag/internal/store"
|
||||
@ -10,27 +10,30 @@ import (
|
||||
|
||||
func SetNodeClaim(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// confirm node hasn't been configured
|
||||
if getBoolConfigValue(CONFIG_CONFIGURED, false) {
|
||||
var config store.Config
|
||||
err := store.DB.Where("config_id = ?", CONFIG_CONFIGURED).First(&config).Error
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if config.BoolValue {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
// extract credentials
|
||||
username, password, ok := r.BasicAuth();
|
||||
if !ok || username == "" || password == "" {
|
||||
log.Printf("SetNodeClaim - invalid credenitals");
|
||||
LogMsg("SetNodeClaim - invalid credenitals");
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
log.Printf("SetNodeClaim - failed to hash password");
|
||||
LogMsg("SetNodeClaim - failed to hash password");
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// store credentials
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Create(&store.Config{ConfigId: CONFIG_USERNAME, StrValue: username}).Error; res != nil {
|
||||
return res
|
||||
@ -44,7 +47,7 @@ func SetNodeClaim(w http.ResponseWriter, r *http.Request) {
|
||||
return nil;
|
||||
})
|
||||
if(err != nil) {
|
||||
log.Printf("SetNodeCalim - failed to store credentials");
|
||||
LogMsg("SetNodeCalim - failed to store credentials");
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
@ -46,10 +46,10 @@ type AccountToken struct {
|
||||
|
||||
type Account struct {
|
||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||
PublicKey []byte `gorm:"not null"`
|
||||
PrivateKey []byte `gorm:"not null"`
|
||||
KeyType []byte `gorm:"not null"`
|
||||
ProfileId string `gorm:"not null;uniqueIndex"`
|
||||
PublicKey []byte `gorm:"not null"`
|
||||
PrivateKey []byte `gorm:"not null"`
|
||||
KeyType []byte `gorm:"not null"`
|
||||
ProfileId string `gorm:"not null;uniqueIndex"`
|
||||
Username string `gorm:"not null;uniqueIndex"`
|
||||
Password []byte `gorm:"not null"`
|
||||
Name string
|
||||
|
18
net/server/internal/writeResponse.go
Normal file
18
net/server/internal/writeResponse.go
Normal file
@ -0,0 +1,18 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func WriteResponse(w http.ResponseWriter, v interface{}) {
|
||||
body, err := json.Marshal(v);
|
||||
if err != nil {
|
||||
LogMsg("marshal failed")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
} else {
|
||||
w.Write(body);
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user