adding http utility functions

This commit is contained in:
Roland Osborne 2022-01-17 13:27:48 -08:00
parent c5cf72000f
commit 491b86fba9
6 changed files with 114 additions and 122 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@
*.dll *.dll
*.so *.so
*.dylib *.dylib
*.swp
# Test binary, built with `go test -c` # Test binary, built with `go test -c`
*.test *.test

View File

@ -4,7 +4,6 @@ import (
"testing" "testing"
"net/http/httptest" "net/http/httptest"
"encoding/base64" "encoding/base64"
"encoding/json"
) )
func TestAddAccount(t *testing.T) { func TestAddAccount(t *testing.T) {
@ -15,12 +14,9 @@ func TestAddAccount(t *testing.T) {
r.Header.Add("Authorization","Basic " + auth) r.Header.Add("Authorization","Basic " + auth)
w := httptest.NewRecorder() w := httptest.NewRecorder()
AddNodeAccount(w, r) AddNodeAccount(w, r)
resp := w.Result()
dec := json.NewDecoder(resp.Body)
var token string var token string
dec.Decode(&token) if ReadResponse(w, &token) != nil {
if resp.StatusCode != 200 { t.Errorf("failed to create token");
t.Errorf("failed to create account")
return return
} }
@ -29,16 +25,9 @@ func TestAddAccount(t *testing.T) {
r.Header.Add("Authorization","Bearer " + token) r.Header.Add("Authorization","Bearer " + token)
w = httptest.NewRecorder() w = httptest.NewRecorder()
GetAccountToken(w, r) GetAccountToken(w, r)
resp = w.Result()
if resp.StatusCode != 200 {
t.Errorf("invalid token value")
return
}
dec = json.NewDecoder(resp.Body)
var tokenType string var tokenType string
dec.Decode(&tokenType) if ReadResponse(w, &tokenType) != nil {
if tokenType != "create" { t.Errorf("failed to validate token")
t.Errorf("invalid token type")
return return
} }
@ -47,14 +36,11 @@ func TestAddAccount(t *testing.T) {
r.Header.Add("Authorization","Bearer " + token) r.Header.Add("Authorization","Bearer " + token)
w = httptest.NewRecorder() w = httptest.NewRecorder()
GetAccountUsername(w, r) GetAccountUsername(w, r)
resp = w.Result() var available bool
if resp.StatusCode != 200 { if ReadResponse(w, &available) != nil {
t.Errorf("invalid token value") t.Errorf("failed to check username")
return return
} }
dec = json.NewDecoder(resp.Body)
var available bool
dec.Decode(&available)
if !available { if !available {
t.Errorf("username not available") t.Errorf("username not available")
return return
@ -67,16 +53,9 @@ func TestAddAccount(t *testing.T) {
r.Header.Add("Authorization","Bearer " + token) r.Header.Add("Authorization","Bearer " + token)
w = httptest.NewRecorder() w = httptest.NewRecorder()
AddAccount(w, r) AddAccount(w, r)
resp = w.Result()
if resp.StatusCode != 200 {
t.Errorf("invalid token value")
return
}
dec = json.NewDecoder(resp.Body)
var profile Profile var profile Profile
dec.Decode(&profile) if ReadResponse(w, &profile) != nil {
if profile.Handle != "user" { t.Errorf("failed to create account")
t.Errorf("invalid profile")
return return
} }
@ -86,40 +65,33 @@ func TestAddAccount(t *testing.T) {
r.Header.Add("Authorization","Basic " + auth) r.Header.Add("Authorization","Basic " + auth)
w = httptest.NewRecorder() w = httptest.NewRecorder()
AddNodeAccount(w, r) AddNodeAccount(w, r)
resp = w.Result() if ReadResponse(w, &token) != nil {
dec = json.NewDecoder(resp.Body) t.Errorf("failed to create token")
dec.Decode(&token)
if resp.StatusCode != 200 {
t.Errorf("failed to create account")
return return
} }
// check if username is available // check if dup is available
r = httptest.NewRequest("GET", "/account/claimable?username=user", nil) r = httptest.NewRequest("GET", "/account/claimable?username=user", nil)
r.Header.Add("Authorization","Bearer " + token) r.Header.Add("Authorization","Bearer " + token)
w = httptest.NewRecorder() w = httptest.NewRecorder()
GetAccountUsername(w, r) GetAccountUsername(w, r)
resp = w.Result() if ReadResponse(w, &available) != nil {
if resp.StatusCode != 200 { t.Errorf("failed to check username")
t.Errorf("invalid token value")
return return
} }
dec = json.NewDecoder(resp.Body)
dec.Decode(&available)
if available { if available {
t.Errorf("username duplicate available") t.Errorf("username duplicate available")
return return
} }
// create account // create dup account
auth = base64.StdEncoding.EncodeToString([]byte("user:pass")) auth = base64.StdEncoding.EncodeToString([]byte("user:pass"))
r = httptest.NewRequest("GET", "/account/profile", nil) r = httptest.NewRequest("GET", "/account/profile", nil)
r.Header.Add("Credentials","Basic " + auth) r.Header.Add("Credentials","Basic " + auth)
r.Header.Add("Authorization","Bearer " + token) r.Header.Add("Authorization","Bearer " + token)
w = httptest.NewRecorder() w = httptest.NewRecorder()
AddAccount(w, r) AddAccount(w, r)
resp = w.Result() if ReadResponse(w, &profile) == nil {
if resp.StatusCode == 200 {
t.Errorf("duplicate handle set") t.Errorf("duplicate handle set")
return return
} }

View File

@ -0,0 +1,64 @@
package databag
import (
"strings"
"errors"
"encoding/json"
"encoding/base64"
"net/http"
"net/http/httptest"
)
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)
}
}
func ReadResponse(w *httptest.ResponseRecorder, v interface{}) error {
resp := w.Result()
if resp.StatusCode != 200 {
return errors.New("response failed");
}
if v == nil {
return nil
}
dec := json.NewDecoder(resp.Body)
dec.Decode(v)
return nil
}
func NewRequest(rest string, path string, obj interface{}) (*http.Request, *httptest.ResponseRecorder, error) {
w := httptest.NewRecorder()
if(obj != nil) {
body, err := json.Marshal(obj)
if err != nil {
return nil, nil, err
}
reader := strings.NewReader(string(body))
return httptest.NewRequest(rest, path, reader), w, nil
}
return httptest.NewRequest(rest, path, nil), w, nil
}
func SetBasicAuth(r *http.Request, login string) {
auth := base64.StdEncoding.EncodeToString([]byte(login))
r.Header.Add("Authorization", "Basic " + auth)
}
func SetBearerAuth(r *http.Request, token string) {
r.Header.Add("Authorization", "Bearer " + token)
}
func SetCredentials(r *http.Request, login string) {
auth := base64.StdEncoding.EncodeToString([]byte(login))
r.Header.Add("Credentials", "Basic " + auth)
}

View File

@ -19,6 +19,8 @@ import (
"github.com/kr/pretty" "github.com/kr/pretty"
) )
var hideLog bool = false
func Logger(inner http.Handler, name string) http.Handler { func Logger(inner http.Handler, name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now() start := time.Now()
@ -36,9 +38,11 @@ func Logger(inner http.Handler, name string) http.Handler {
} }
func LogMsg(msg string) { func LogMsg(msg string) {
_, file, line, _ := runtime.Caller(1) if !hideLog {
p, _ := os.Getwd() _, file, line, _ := runtime.Caller(1)
log.Printf("%s:%d %s", strings.TrimPrefix(file, p), line, msg) p, _ := os.Getwd()
log.Printf("%s:%d %s", strings.TrimPrefix(file, p), line, msg)
}
} }
func PrintMsg(obj interface{}) { func PrintMsg(obj interface{}) {

View File

@ -1,16 +1,13 @@
package databag package databag
import ( import (
"strings"
"testing" "testing"
"net/http/httptest"
"encoding/base64"
"encoding/json"
"databag/internal/store" "databag/internal/store"
) )
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
hideLog = true
store.SetPath("file::memory:?cache=shared"); store.SetPath("file::memory:?cache=shared");
//store.SetPath("databag.db"); //store.SetPath("databag.db");
@ -24,59 +21,39 @@ func TestMain(m *testing.M) {
} }
func Claimable() { func Claimable() {
r := httptest.NewRequest("GET", "/admin/claimable", nil) r, w, _ := NewRequest("GET", "/admin/claimable", nil)
w := httptest.NewRecorder()
GetNodeClaimable(w, r) GetNodeClaimable(w, r)
var available bool
//body, _ := ioutil.ReadAll(resp.Body) if ReadResponse(w, &available) != nil {
resp := w.Result() panic("server not claimable")
dec := json.NewDecoder(resp.Body);
var res bool
err := dec.Decode(&res)
if err != nil {
panic("failed to get claimable response")
}
if resp.StatusCode != 200 {
panic("server not initially claimable")
} }
} }
func Claim() { func Claim() {
auth := base64.StdEncoding.EncodeToString([]byte("admin:pass")) r, w, _ := NewRequest("PUT", "/admin/claim", nil)
r := httptest.NewRequest("PUT", "/admin/claim", nil) SetCredentials(r, "admin:pass");
r.Header.Add("Credentials","Basic " + auth)
w := httptest.NewRecorder()
SetNodeClaim(w, r) SetNodeClaim(w, r)
if w.Code != 200 { if ReadResponse(w, nil) != nil {
panic("server not initially claimable") panic("failed to claim server")
} }
} }
func SetConfig() { func SetConfig() {
config := NodeConfig{Domain: "example.com", PublicLimit: 1024, AccountStorage: 4096} config := NodeConfig{Domain: "example.com", PublicLimit: 1024, AccountStorage: 4096}
auth := base64.StdEncoding.EncodeToString([]byte("admin:pass")) r, w, _ := NewRequest("PUT", "/admin/config", &config)
body,_ := json.Marshal(config) SetBasicAuth(r, "admin:pass")
r := httptest.NewRequest("PUT", "/admin/config", strings.NewReader(string(body))) SetNodeConfig(w, r)
r.Header.Add("Authorization","Basic " + auth) if ReadResponse(w, nil) != nil {
w := httptest.NewRecorder() panic("failed to set config")
SetNodeConfig(w, r);
if w.Code != 200 {
panic("failed to set node config")
} }
} }
func GetConfig() { func GetConfig() {
auth := base64.StdEncoding.EncodeToString([]byte("admin:pass")) r, w, _ := NewRequest("GET", "/admin/config", nil)
r := httptest.NewRequest("GET", "/admin/config", nil) SetBasicAuth(r, "admin:pass")
r.Header.Add("Authorization","Basic " + auth) GetNodeConfig(w, r)
w := httptest.NewRecorder() var config NodeConfig
GetNodeConfig(w, r); if ReadResponse(w, &config) != nil {
resp := w.Result();
dec := json.NewDecoder(resp.Body);
var config NodeConfig;
dec.Decode(&config);
if resp.StatusCode != 200 {
panic("failed to get node config") panic("failed to get node config")
} }
if config.Domain != "example.com" { if config.Domain != "example.com" {
@ -91,30 +68,22 @@ func GetConfig() {
} }
func SetToken() string { func SetToken() string {
auth := base64.StdEncoding.EncodeToString([]byte("admin:pass")) r, w, _ := NewRequest("POST", "/admin/accounts", nil)
r := httptest.NewRequest("POST", "/admin/accounts", nil) SetBasicAuth(r, "admin:pass")
r.Header.Add("Authorization","Basic " + auth)
w := httptest.NewRecorder()
AddNodeAccount(w, r) AddNodeAccount(w, r)
resp := w.Result()
dec := json.NewDecoder(resp.Body)
var token string var token string
dec.Decode(&token) if ReadResponse(w, &token) != nil {
if resp.StatusCode != 200 {
panic("failed to create token") panic("failed to create token")
} }
return token return token
} }
func SetAccount(token string) { func SetAccount(token string) {
auth := base64.StdEncoding.EncodeToString([]byte("test:pass")) r, w, _ := NewRequest("GET", "/account/profile", nil)
r := httptest.NewRequest("GET", "/account/profile", nil) SetBearerAuth(r, token);
r.Header.Add("Credentials","Basic " + auth) SetCredentials(r, "test:pass")
r.Header.Add("Authorization","Bearer " + token)
w := httptest.NewRecorder()
AddAccount(w, r) AddAccount(w, r)
resp := w.Result() if ReadResponse(w, nil) != nil {
if resp.StatusCode != 200 {
panic("failed to create account") panic("failed to create account")
} }
} }

View File

@ -1,18 +0,0 @@
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)
}
}