Adds configuration options and environment variables to manage box owner policies, including settings for refresh counts and expiry.
198 lines
7.2 KiB
Go
198 lines
7.2 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"warpbox/lib/config"
|
|
"warpbox/lib/metastore"
|
|
)
|
|
|
|
func TestAccountSettingsPermissionDenied(t *testing.T) {
|
|
app, _ := setupAccountTestApp(t)
|
|
user, err := app.store.CreateUserWithPassword("regular", "regular@example.test", "secret", nil)
|
|
if err != nil {
|
|
t.Fatalf("CreateUserWithPassword returned error: %v", err)
|
|
}
|
|
router := setupAccountTestRouter(t, app)
|
|
session := createAccountTestSession(t, app, user)
|
|
|
|
request := httptest.NewRequest(http.MethodGet, "/account/settings", nil)
|
|
request.AddCookie(&http.Cookie{Name: accountSessionCookie, Value: session.Token})
|
|
response := httptest.NewRecorder()
|
|
router.ServeHTTP(response, request)
|
|
if response.Code != http.StatusForbidden {
|
|
t.Fatalf("expected permission denied, got %d", response.Code)
|
|
}
|
|
}
|
|
|
|
func TestAccountSettingsPageLoadsForAdmin(t *testing.T) {
|
|
app, user := setupAccountTestApp(t)
|
|
router := setupAccountTestRouter(t, app)
|
|
session := createAccountTestSession(t, app, user)
|
|
|
|
request := httptest.NewRequest(http.MethodGet, "/account/settings", nil)
|
|
request.AddCookie(&http.Cookie{Name: accountSessionCookie, Value: session.Token})
|
|
response := httptest.NewRecorder()
|
|
router.ServeHTTP(response, request)
|
|
if response.Code != http.StatusOK {
|
|
t.Fatalf("expected settings page, got %d body=%s", response.Code, response.Body.String())
|
|
}
|
|
for _, text := range []string{"Uploads", "Downloads", "Box policy", "Save Settings"} {
|
|
if !strings.Contains(response.Body.String(), text) {
|
|
t.Fatalf("expected settings page to contain %q", text)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAccountSettingsValidUpdate(t *testing.T) {
|
|
app, user := setupAccountTestApp(t)
|
|
router := setupAccountTestRouter(t, app)
|
|
session := createAccountTestSession(t, app, user)
|
|
|
|
form := url.Values{}
|
|
form.Set("csrf_token", session.CSRFToken)
|
|
form.Set(config.SettingAPIEnabled, "false")
|
|
response := postAccountSettingsForm(router, session, form)
|
|
if response.Code != http.StatusSeeOther {
|
|
t.Fatalf("expected settings redirect, got %d body=%s", response.Code, response.Body.String())
|
|
}
|
|
if app.config.APIEnabled {
|
|
t.Fatal("expected API setting to be disabled")
|
|
}
|
|
value, ok, err := app.store.GetSetting(config.SettingAPIEnabled)
|
|
if err != nil || !ok || value != "false" {
|
|
t.Fatalf("expected API setting override false, got value=%q ok=%v err=%v", value, ok, err)
|
|
}
|
|
}
|
|
|
|
func TestAccountSettingsInvalidUpdate(t *testing.T) {
|
|
app, user := setupAccountTestApp(t)
|
|
router := setupAccountTestRouter(t, app)
|
|
session := createAccountTestSession(t, app, user)
|
|
|
|
form := url.Values{}
|
|
form.Set("csrf_token", session.CSRFToken)
|
|
form.Set(config.SettingSessionTTLSeconds, "1")
|
|
response := postAccountSettingsForm(router, session, form)
|
|
if response.Code != http.StatusOK {
|
|
t.Fatalf("expected settings form render, got %d", response.Code)
|
|
}
|
|
if !strings.Contains(response.Body.String(), "must be at least 60") {
|
|
t.Fatal("expected validation error in response")
|
|
}
|
|
}
|
|
|
|
func TestAccountSettingsLockedSettingCannotChange(t *testing.T) {
|
|
app, user := setupAccountTestApp(t)
|
|
router := setupAccountTestRouter(t, app)
|
|
session := createAccountTestSession(t, app, user)
|
|
|
|
form := url.Values{}
|
|
form.Set("csrf_token", session.CSRFToken)
|
|
form.Set(config.SettingGlobalMaxFileSizeBytes, "1")
|
|
response := postAccountSettingsForm(router, session, form)
|
|
if response.Code != http.StatusOK {
|
|
t.Fatalf("expected settings form render, got %d", response.Code)
|
|
}
|
|
if !strings.Contains(response.Body.String(), "locked") {
|
|
t.Fatal("expected locked setting error")
|
|
}
|
|
if value, ok, err := app.store.GetSetting(config.SettingGlobalMaxFileSizeBytes); err != nil || ok || value != "" {
|
|
t.Fatalf("expected no locked setting override, got value=%q ok=%v err=%v", value, ok, err)
|
|
}
|
|
}
|
|
|
|
func TestAccountSettingsImportRejectsUnknownOrInvalidSettings(t *testing.T) {
|
|
app, user := setupAccountTestApp(t)
|
|
router := setupAccountTestRouter(t, app)
|
|
session := createAccountTestSession(t, app, user)
|
|
|
|
for _, body := range []string{
|
|
`{"version":1,"settings":{"not_real":"true"}}`,
|
|
`{"version":1,"settings":{"session_ttl_seconds":"1"}}`,
|
|
} {
|
|
response := postAccountSettingsJSON(router, session, body)
|
|
if response.Code != http.StatusBadRequest {
|
|
t.Fatalf("expected bad import for %s, got %d", body, response.Code)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAccountSettingsImportAppliesValidSettings(t *testing.T) {
|
|
app, user := setupAccountTestApp(t)
|
|
router := setupAccountTestRouter(t, app)
|
|
session := createAccountTestSession(t, app, user)
|
|
|
|
response := postAccountSettingsJSON(router, session, `{"version":1,"settings":{"api_enabled":"false","box_owner_max_refresh_count":"7"}}`)
|
|
if response.Code != http.StatusOK {
|
|
t.Fatalf("expected import success, got %d body=%s", response.Code, response.Body.String())
|
|
}
|
|
if app.config.APIEnabled {
|
|
t.Fatal("expected imported API setting to be disabled")
|
|
}
|
|
if app.config.BoxOwnerMaxRefreshCount != 7 {
|
|
t.Fatalf("expected imported box owner refresh count 7, got %d", app.config.BoxOwnerMaxRefreshCount)
|
|
}
|
|
}
|
|
|
|
func TestAccountSettingsExportShape(t *testing.T) {
|
|
app, user := setupAccountTestApp(t)
|
|
router := setupAccountTestRouter(t, app)
|
|
session := createAccountTestSession(t, app, user)
|
|
|
|
request := httptest.NewRequest(http.MethodGet, "/account/settings/export.json", nil)
|
|
request.AddCookie(&http.Cookie{Name: accountSessionCookie, Value: session.Token})
|
|
response := httptest.NewRecorder()
|
|
router.ServeHTTP(response, request)
|
|
if response.Code != http.StatusOK {
|
|
t.Fatalf("expected export success, got %d", response.Code)
|
|
}
|
|
var backup SettingsBackup
|
|
if err := json.Unmarshal(response.Body.Bytes(), &backup); err != nil {
|
|
t.Fatalf("Unmarshal returned error: %v", err)
|
|
}
|
|
if backup.Version != 1 {
|
|
t.Fatalf("expected version 1, got %d", backup.Version)
|
|
}
|
|
if _, ok := backup.Settings[config.SettingBoxOwnerMaxRefreshCount]; !ok {
|
|
t.Fatal("expected export to include box owner policy setting")
|
|
}
|
|
if _, ok := backup.Settings[config.SettingDataDir]; ok {
|
|
t.Fatal("did not expect locked data dir in export settings")
|
|
}
|
|
}
|
|
|
|
func createAccountTestSession(t *testing.T, app *App, user metastore.User) metastore.Session {
|
|
t.Helper()
|
|
session, err := app.store.CreateSession(user.ID, time.Hour)
|
|
if err != nil {
|
|
t.Fatalf("CreateSession returned error: %v", err)
|
|
}
|
|
return session
|
|
}
|
|
|
|
func postAccountSettingsForm(router http.Handler, session metastore.Session, form url.Values) *httptest.ResponseRecorder {
|
|
request := httptest.NewRequest(http.MethodPost, "/account/settings", strings.NewReader(form.Encode()))
|
|
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
request.AddCookie(&http.Cookie{Name: accountSessionCookie, Value: session.Token})
|
|
response := httptest.NewRecorder()
|
|
router.ServeHTTP(response, request)
|
|
return response
|
|
}
|
|
|
|
func postAccountSettingsJSON(router http.Handler, session metastore.Session, body string) *httptest.ResponseRecorder {
|
|
request := httptest.NewRequest(http.MethodPost, "/account/settings/import.json", strings.NewReader(body))
|
|
request.Header.Set("Content-Type", "application/json")
|
|
request.Header.Set("X-CSRF-Token", session.CSRFToken)
|
|
request.AddCookie(&http.Cookie{Name: accountSessionCookie, Value: session.Token})
|
|
response := httptest.NewRecorder()
|
|
router.ServeHTTP(response, request)
|
|
return response
|
|
}
|