From 691f0e75b942e34eeb13d14f374c52133cdf786d Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 10 May 2021 08:41:57 +0200 Subject: [PATCH] add test for notice creation role check updates #176 --- web/handlers/notices_test.go | 74 ++++++++++++++++++++++++++++++++++++ web/handlers/setup_test.go | 10 ++++- web/utils.go | 3 ++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/web/handlers/notices_test.go b/web/handlers/notices_test.go index fc6ef27..23362ec 100644 --- a/web/handlers/notices_test.go +++ b/web/handlers/notices_test.go @@ -7,6 +7,7 @@ import ( "github.com/ssb-ngi-pointer/go-ssb-room/roomdb" "github.com/ssb-ngi-pointer/go-ssb-room/web/router" + "github.com/ssb-ngi-pointer/go-ssb-room/web/webassert" "github.com/stretchr/testify/assert" ) @@ -131,3 +132,76 @@ func TestNoticesEditButtonVisible(t *testing.T) { a.EqualValues(1, doc.Find(editButtonSelector).Length()) } + +func TestNoticesCreateOnlyModsAndHigher(t *testing.T) { + ts := setup(t) + a := assert.New(t) + + ts.ConfigDB.GetPrivacyModeReturns(roomdb.ModeCommunity, nil) + + // first, we confirm that we can't access the page when not logged in + draftNotice := ts.URLTo(router.AdminNoticeDraftTranslation, "name", roomdb.NoticeNews) + + doc, resp := ts.Client.GetHTML(draftNotice) + a.Equal(http.StatusForbidden, resp.Code) + + // start preparing the ~login dance~ + // TODO: make this code reusable and share it with the login => /dashboard http:200 test + // TODO: refactor login dance for re-use in testing / across tests + + // when dealing with cookies we also need to have an Host and URL-Scheme + // for the jar to save and load them correctly + formEndpoint := ts.URLTo(router.AuthFallbackLogin) + + doc, resp = ts.Client.GetHTML(formEndpoint) + a.Equal(http.StatusOK, resp.Code) + + csrfCookie := resp.Result().Cookies() + a.True(len(csrfCookie) > 0, "should have one cookie for CSRF protection validation") + + csrfTokenElem := doc.Find(`form#password-fallback input[type="hidden"]`) + a.Equal(1, csrfTokenElem.Length()) + + csrfName, has := csrfTokenElem.Attr("name") + a.True(has, "should have a name attribute") + + csrfValue, has := csrfTokenElem.Attr("value") + a.True(has, "should have value attribute") + + loginVals := url.Values{ + "user": []string{"test"}, + "pass": []string{"test"}, + + csrfName: []string{csrfValue}, + } + + // have the database return okay for any user + testUser := roomdb.Member{ID: 123, Role: roomdb.RoleMember} + ts.AuthFallbackDB.CheckReturns(testUser.ID, nil) + ts.MembersDB.GetByIDReturns(testUser, nil) + + postEndpoint := ts.URLTo(router.AuthFallbackFinalize) + + // construct HTTP Header with Referer and Cookie + var refererHeader = make(http.Header) + refererHeader.Set("Referer", "https://localhost") + ts.Client.SetHeaders(refererHeader) + + resp = ts.Client.PostForm(postEndpoint, loginVals) + a.Equal(http.StatusSeeOther, resp.Code, "wrong HTTP status code for sign in") + + cnt := ts.MembersDB.GetByIDCallCount() + + // now we are logged in, but we shouldn't be able to get the draft page + doc, resp = ts.Client.GetHTML(draftNotice) + a.Equal(http.StatusTemporaryRedirect, resp.Code) + + dashboardURL := ts.URLTo(router.AdminDashboard) + a.Equal(dashboardURL.Path, resp.Header().Get("Location")) + a.True(len(resp.Result().Cookies()) > 0, "got a cookie") + + webassert.HasFlashMessages(t, ts.Client, dashboardURL, "AdminMemberDetailsAliasRevoked") + + a.Equal(cnt+1, ts.MembersDB.GetByIDCallCount()) + +} diff --git a/web/handlers/setup_test.go b/web/handlers/setup_test.go index fba8047..da9b004 100644 --- a/web/handlers/setup_test.go +++ b/web/handlers/setup_test.go @@ -5,6 +5,7 @@ package handlers import ( "bytes" "net/http" + "net/url" "os" "path/filepath" "testing" @@ -99,7 +100,14 @@ func setup(t *testing.T) *testSession { // instantiate the urlTo helper (constructs urls for us!) // the cookiejar in our custom http/tester needs a non-empty domain and scheme - ts.URLTo = web.NewURLTo(router.CompleteApp(), ts.NetworkInfo) + mkUrl := web.NewURLTo(router.CompleteApp(), ts.NetworkInfo) + ts.URLTo = func(name string, vals ...interface{}) *url.URL { + u := mkUrl(name, vals...) + if u.Path == "" || u.Host == "" { + t.Fatal("failed to make URL for: ", name, vals) + } + return u + } ts.SignalBridge = signinwithssb.NewSignalBridge() diff --git a/web/utils.go b/web/utils.go index 8757516..47a6774 100644 --- a/web/utils.go +++ b/web/utils.go @@ -21,6 +21,7 @@ import ( "github.com/ssb-ngi-pointer/go-ssb-room/internal/network" "github.com/ssb-ngi-pointer/go-ssb-room/internal/repo" + "github.com/ssb-ngi-pointer/go-ssb-room/roomdb" refs "go.mindeco.de/ssb-refs" ) @@ -69,6 +70,8 @@ func NewURLTo(appRouter *mux.Router, netInfo network.ServerEndpointDetails) URLM params = append(params, strconv.FormatInt(v, 10)) case refs.FeedRef: params = append(params, v.Ref()) + case roomdb.PinnedNoticeName: + params = append(params, string(v)) default: level.Error(l).Log("msg", "invalid param type", "param", fmt.Sprintf("%T", p), "route", routeName) return &url.URL{}