Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

separate auth roles for downloading current FV and historic FVs #187

Merged
merged 6 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
PGPASSWORD: for_testing
PGHOST: localhost
PGPORT: 5432
TL_TEST_STORAGE: /tmp/tlserver
TL_TEST_SERVER_DATABASE_URL: postgres://root:for_testing@localhost:5432/tlv2_test_server?sslmode=disable
TL_DATABASE_URL: postgres://root:for_testing@localhost:5432/tlv2_test_server?sslmode=disable
services:
Expand Down
117 changes: 108 additions & 9 deletions server/rest/feed_version_download_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"

"github.com/interline-io/transitland-server/auth/ancheck"
"github.com/interline-io/transitland-server/auth/authn"
"github.com/interline-io/transitland-server/internal/testutil"
)

Expand All @@ -21,31 +22,89 @@ func TestFeedVersionDownloadRequest(t *testing.T) {
if err != nil {
t.Fatal(err)
}
restSrv = ancheck.AdminDefaultMiddleware("test")(restSrv)

t.Run("ok", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feed_versions/d2813c293bcfd7a97dde599527ae6c62c98e66c6/download", nil)
rr := httptest.NewRecorder()
restSrv.ServeHTTP(rr, req)
asAdmin := ancheck.AdminDefaultMiddleware("test")(restSrv)
asAdmin.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 200 {
t.Errorf("got status code %d, expected 200", sc)
}
if sc := len(rr.Body.Bytes()); sc != 59324 {
t.Errorf("got %d bytes, expected 59324", sc)
}
})
t.Run("not authorized", func(t *testing.T) {
t.Run("not authorized as anon", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feed_versions/d2813c293bcfd7a97dde599527ae6c62c98e66c6/download", nil)
rr := httptest.NewRecorder()
asAnon := restSrv
asAnon.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 401 {
t.Errorf("got status code %d, expected 401", sc)
}
})
t.Run("not authorized as user, missing role", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feed_versions/d2813c293bcfd7a97dde599527ae6c62c98e66c6/download", nil)
rr := httptest.NewRecorder()
asUser := ancheck.NewUserDefaultMiddleware(func() authn.User {
return authn.NewCtxUser("testuser", "", "").WithRoles("testrole")
})(restSrv)
asUser.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 401 {
t.Errorf("got status code %d, expected 401", sc)
}
})
t.Run("not authorized as user, only current download role", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feed_versions/d2813c293bcfd7a97dde599527ae6c62c98e66c6/download", nil)
rr := httptest.NewRecorder()
asUser := ancheck.NewUserDefaultMiddleware(func() authn.User {
return authn.NewCtxUser("testuser", "", "").WithRoles("tl_download_fv_current")
})(restSrv)
asUser.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 401 {
t.Errorf("got status code %d, expected 401", sc)
}
})
t.Run("authorized as user", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feed_versions/d2813c293bcfd7a97dde599527ae6c62c98e66c6/download", nil)
rr := httptest.NewRecorder()
asUser := ancheck.NewUserDefaultMiddleware(func() authn.User {
return authn.NewCtxUser("testuser", "", "").WithRoles("tl_download_fv_historic")
})(restSrv)
asUser.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 200 {
t.Errorf("got status code %d, expected 200", sc)
}
if sc := len(rr.Body.Bytes()); sc != 59324 {
t.Errorf("got %d bytes, expected 59324", sc)
}
})
t.Run("not authorized as anon, not redistributable", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feed_versions/dd7aca4a8e4c90908fd3603c097fabee75fea907/download", nil)
rr := httptest.NewRecorder()
restSrv.ServeHTTP(rr, req)
asAnon := restSrv
asAnon.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 401 {
t.Errorf("got status code %d, expected 401", sc)
}
})
t.Run("not authorized as user, not redistributable", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feed_versions/dd7aca4a8e4c90908fd3603c097fabee75fea907/download", nil)
rr := httptest.NewRecorder()
asUser := ancheck.NewUserDefaultMiddleware(func() authn.User {
return authn.NewCtxUser("testuser", "", "").WithRoles("tl_download_fv_historic")
})(restSrv)
asUser.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 401 {
t.Errorf("got status code %d, expected 401", sc)
}
})
t.Run("not found", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feed_versions/asdxyz/download", nil)
rr := httptest.NewRecorder()
restSrv.ServeHTTP(rr, req)
asAdmin := ancheck.AdminDefaultMiddleware("test")(restSrv)
asAdmin.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 404 {
t.Errorf("got status code %d, expected 404", sc)
}
Expand All @@ -68,26 +127,66 @@ func TestFeedDownloadLatestRequest(t *testing.T) {
t.Run("ok", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feeds/CT/download_latest_feed_version", nil)
rr := httptest.NewRecorder()
restSrv.ServeHTTP(rr, req)
asAdmin := ancheck.AdminDefaultMiddleware("test")(restSrv)
asAdmin.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 200 {
t.Errorf("got status code %d, expected 200", sc)
}
if sc := len(rr.Body.Bytes()); sc != 59324 {
t.Errorf("got %d bytes, expected 59324", sc)
}
})
t.Run("ok as user", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feeds/CT/download_latest_feed_version", nil)
rr := httptest.NewRecorder()
asUser := ancheck.NewUserDefaultMiddleware(func() authn.User {
return authn.NewCtxUser("testuser", "", "").WithRoles("tl_download_fv_current")
})(restSrv)
asUser.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 200 {
t.Errorf("got status code %d, expected 200", sc)
}
if sc := len(rr.Body.Bytes()); sc != 59324 {
t.Errorf("got %d bytes, expected 59324", sc)
}
})
t.Run("not authorized", func(t *testing.T) {
t.Run("not authorized as anon", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feeds/CT/download_latest_feed_version", nil)
rr := httptest.NewRecorder()
asAnon := restSrv
asAnon.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 401 {
t.Errorf("got status code %d, expected 401", sc)
}
})
t.Run("not authorized as user, missing role", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feeds/CT/download_latest_feed_version", nil)
rr := httptest.NewRecorder()
asUser := ancheck.NewUserDefaultMiddleware(func() authn.User {
return authn.NewCtxUser("testuser", "", "").WithRoles("testrole")
})(restSrv)
asUser.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 401 {
t.Errorf("got status code %d, expected 401", sc)
}
})
t.Run("not authorized as user, not redistributable", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feeds/BA/download_latest_feed_version", nil)
rr := httptest.NewRecorder()
restSrv.ServeHTTP(rr, req)
asUser := ancheck.NewUserDefaultMiddleware(func() authn.User {
return authn.NewCtxUser("testuser", "", "").WithRoles("download_latest_feed_version")
})(restSrv)
asUser.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 401 {
t.Errorf("got status code %d, expected 401", sc)
}
})

t.Run("not found", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/feeds/asdxyz/download_latest_feed_version", nil)
rr := httptest.NewRecorder()
restSrv.ServeHTTP(rr, req)
asAdmin := ancheck.AdminDefaultMiddleware("test")(restSrv)
asAdmin.ServeHTTP(rr, req)
if sc := rr.Result().StatusCode; sc != 404 {
t.Errorf("got status code %d, expected 404", sc)
}
Expand Down
4 changes: 2 additions & 2 deletions server/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ func NewServer(cfg config.Config, srv http.Handler) (http.Handler, error) {
r.HandleFunc("/feeds", feedHandler)
r.HandleFunc("/feeds/{feed_key}.{format}", feedHandler)
r.HandleFunc("/feeds/{feed_key}", feedHandler)
r.HandleFunc("/feeds/{feed_key}/download_latest_feed_version", makeHandlerFunc(restcfg, "feedVersionDownloadLatest", feedVersionDownloadLatestHandler))
r.Handle("/feeds/{feed_key}/download_latest_feed_version", ancheck.RoleRequired("tl_download_fv_current")(makeHandlerFunc(restcfg, "feedVersionDownloadLatest", feedVersionDownloadLatestHandler)))

r.HandleFunc("/feed_versions.{format}", feedVersionHandler)
r.HandleFunc("/feed_versions", feedVersionHandler)
r.HandleFunc("/feed_versions/{feed_version_key}.{format}", feedVersionHandler)
r.HandleFunc("/feed_versions/{feed_version_key}", feedVersionHandler)
r.HandleFunc("/feeds/{feed_key}/feed_versions", feedVersionHandler)
r.Handle("/feed_versions/{feed_version_key}/download", ancheck.RoleRequired("tl_user_pro")(makeHandlerFunc(restcfg, "feedVersionDownload", feedVersionDownloadHandler)))
r.Handle("/feed_versions/{feed_version_key}/download", ancheck.RoleRequired("tl_download_fv_historic")(makeHandlerFunc(restcfg, "feedVersionDownload", feedVersionDownloadHandler)))

r.HandleFunc("/agencies.{format}", agencyHandler)
r.HandleFunc("/agencies", agencyHandler)
Expand Down
12 changes: 6 additions & 6 deletions test_setup.sh
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#!/bin/bash
# Remove import files
rm *.zip
TL_TEST_STORAGE="${TL_TEST_STORAGE:-tmp}"
mkdir -p "${TL_TEST_STORAGE}"; rm ${TL_TEST_STORAGE}/*.zip
# export TL_LOG=debug
(cd cmd/tlserver && go install .)
tlserver sync -dburl="$TL_TEST_SERVER_DATABASE_URL" test/data/server/server-test.dmfr.json
# older data
tlserver fetch -dburl="$TL_TEST_SERVER_DATABASE_URL" -allow-local-fetch -feed-url=test/data/external/bart-old.zip BA # old data
tlserver import -dburl="$TL_TEST_SERVER_DATABASE_URL"
tlserver fetch -dburl="$TL_TEST_SERVER_DATABASE_URL" -storage="$TL_TEST_STORAGE" -allow-local-fetch -feed-url=test/data/external/bart-old.zip BA # old data
tlserver import -dburl="$TL_TEST_SERVER_DATABASE_URL" -storage="$TL_TEST_STORAGE"
# current data
tlserver fetch -dburl="$TL_TEST_SERVER_DATABASE_URL" -allow-local-fetch
tlserver import -dburl="$TL_TEST_SERVER_DATABASE_URL" -activate
tlserver fetch -dburl="$TL_TEST_SERVER_DATABASE_URL" -storage="$TL_TEST_STORAGE" -allow-local-fetch
tlserver import -dburl="$TL_TEST_SERVER_DATABASE_URL" -storage="$TL_TEST_STORAGE" -activate
# sync again
tlserver sync -dburl="$TL_TEST_SERVER_DATABASE_URL" test/data/server/server-test.dmfr.json
# supplemental data
psql -f test_supplement.pgsql
rm *.zip