Skip to content

Commit

Permalink
feat(redirect): add post-login redirect (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
wass3r authored and Neal committed Nov 13, 2019
1 parent c32ccbd commit c81349a
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 132 deletions.
5 changes: 5 additions & 0 deletions cypress/fixtures/redirect.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"username": "",
"token": "",
"entrypoint": "http://localhost:8888/Cookie/Cat"
}
3 changes: 2 additions & 1 deletion cypress/fixtures/sessionstorage.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"username": "cookie cat",
"token": "super.duper.yummy"
"token": "super.duper.yummy",
"entrypoint": ""
}
33 changes: 33 additions & 0 deletions cypress/integration/auth.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ context("Authentication", () => {
});

context("logged out", () => {
beforeEach(() => {
cy.window().then(win => {
win.sessionStorage.removeItem("vela");
});
});

it("empty values in sessionstorage object should redirect to login page", () => {
cy.visit("/");
cy.location("pathname").should("eq", "/account/login");
Expand Down Expand Up @@ -119,4 +125,31 @@ context("Authentication", () => {
cy.location("pathname").should("eq", "/account/login");
});
});

context("post-login redirect", () => {
beforeEach(() => {
cy.login("/Cookie/Cat", "redirect");
});

it("should redirect to the login page", () => {
cy.location("pathname").should("eq", "/account/login");
});

it("shows the app name near the logo since no user has logged in yet", () => {
cy.get("[data-test=identity]").contains("Vela");
});

it("should redirect to the original entrypoint after logging in", () => {
cy.server();
cy.route({
method: "GET",
url: "/authenticate*",
response: "fixture:auth.json"
});

cy.visit("/account/authenticate?code=deadbeef&state=1337");

cy.location("pathname").should("eq", "/Cookie/Cat");
});
});
});
49 changes: 24 additions & 25 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// https://on.cypress.io/custom-commands
// ***********************************************

// Login helper
Cypress.Commands.add("login", (path = "/") => {
cy.fixture("sessionstorage").then(sessionstorageSample => {
// Login helper (accepts initial path to vist and sessionstorage fixture)
Cypress.Commands.add("login", (path = "/", fixture = "sessionstorage") => {
cy.fixture(fixture).then(sessionstorageSample => {
cy.visit(path, {
onBeforeLoad: win => {
const serialized = JSON.stringify(sessionstorageSample);
Expand All @@ -28,28 +28,28 @@ Cypress.Commands.add("stubBuild", () => {
cy.fixture("build_success.json").as("successBuild");
cy.fixture("build_failure.json").as("failureBuild");
cy.route({
method: "GET",
url: "api/v1/repos/*/*/builds/1",
status: 200,
response: "@runningBuild"
method: "GET",
url: "api/v1/repos/*/*/builds/1",
status: 200,
response: "@runningBuild"
});
cy.route({
method: "GET",
url: "api/v1/repos/*/*/builds/2",
status: 200,
response: "@pendingBuild"
method: "GET",
url: "api/v1/repos/*/*/builds/2",
status: 200,
response: "@pendingBuild"
});
cy.route({
method: "GET",
url: "api/v1/repos/*/*/builds/3",
status: 200,
response: "@successBuild"
method: "GET",
url: "api/v1/repos/*/*/builds/3",
status: 200,
response: "@successBuild"
});
cy.route({
method: "GET",
url: "api/v1/repos/*/*/builds/4",
status: 200,
response: "@failureBuild"
method: "GET",
url: "api/v1/repos/*/*/builds/4",
status: 200,
response: "@failureBuild"
});
});

Expand All @@ -75,21 +75,20 @@ Cypress.Commands.add("stubBuilds", () => {
});
});


Cypress.Commands.add("stubStepsWithLogs", () => {
cy.server();
cy.fixture("steps_5.json").as("steps");
cy.route({
method: "GET",
url: "api/v1/repos/*/*/builds/*/steps",
status: 200,
response: "@steps"
method: "GET",
url: "api/v1/repos/*/*/builds/*/steps",
status: 200,
response: "@steps"
});
cy.fixture("logs").then(logs => {
for (let i = 0; i < logs.length; i++) {
cy.route({
method: "GET",
url: "api/v1/repos/*/*/builds/*/steps/"+logs[i]['step_id']+"/logs",
url: "api/v1/repos/*/*/builds/*/steps/" + logs[i]["step_id"] + "/logs",
status: 200,
response: logs[i]
});
Expand Down
49 changes: 22 additions & 27 deletions src/elm/Api.elm
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import Api.Pagination as Pagination
import Http
import Http.Detailed
import Json.Decode exposing (Decoder)
import RemoteData exposing (RemoteData(..), WebData)
import RemoteData exposing (RemoteData(..))
import Task exposing (Task)
import Vela
exposing
Expand All @@ -41,6 +41,7 @@ import Vela
, Repo
, Repositories
, Repository
, Session
, SourceRepositories
, Step
, StepNumber
Expand All @@ -55,7 +56,7 @@ import Vela
, decodeStep
, decodeSteps
, decodeUser
, defaultUser
, defaultSession
)


Expand Down Expand Up @@ -95,21 +96,14 @@ type ListResponse a
type alias PartialModel a =
{ a
| velaAPI : String
, user : WebData User
, session : Maybe Session
}



-- HELPERS


{-| remoteDataToUser : simple helper to turn a RemoteData User into a User
-}
remoteDataToUser : WebData User -> User
remoteDataToUser maybeUser =
Maybe.withDefault defaultUser <| RemoteData.toMaybe maybeUser


{-| request : turn a request configuration into a request
-}
request : RequestConfig a -> Request a
Expand Down Expand Up @@ -226,13 +220,14 @@ update old new =

{-| withAuth : returns an auth header with given Bearer token
-}
withAuth : WebData User -> Request a -> Request a
withAuth user (Request config) =
withAuth : Maybe Session -> Request a -> Request a
withAuth maybeSession (Request config) =
let
user_ =
remoteDataToUser user
session : Session
session =
Maybe.withDefault defaultSession maybeSession
in
request { config | headers = Http.header "authorization" ("Bearer " ++ user_.token) :: config.headers }
request { config | headers = Http.header "authorization" ("Bearer " ++ session.token) :: config.headers }



Expand Down Expand Up @@ -336,7 +331,7 @@ getUser model { code, state } =
getRepositories : PartialModel a -> Maybe Pagination.Page -> Maybe Pagination.PerPage -> Request Repositories
getRepositories model maybePage maybePerPage =
get model.velaAPI (Endpoint.Repositories maybePage maybePerPage) decodeRepositories
|> withAuth model.user
|> withAuth model.session


{-| getAllRepositories : used in conjuction with 'tryAll', it retrieves all pages of the resource
Expand All @@ -348,47 +343,47 @@ getAllRepositories : PartialModel a -> Request Repository
getAllRepositories model =
-- we using the max perPage setting of 100 to reduce the number of calls
get model.velaAPI (Endpoint.Repositories (Just 1) (Just 100)) decodeRepository
|> withAuth model.user
|> withAuth model.session


{-| getSourceRepositories : fetches source repositories by username for creating them via api
-}
getSourceRepositories : PartialModel a -> Request SourceRepositories
getSourceRepositories model =
get model.velaAPI Endpoint.UserSourceRepositories decodeSourceRepositories
|> withAuth model.user
|> withAuth model.session


{-| deleteRepo : removes an added repository
-}
deleteRepo : PartialModel a -> Repository -> Request String
deleteRepo model repository =
delete model.velaAPI (Endpoint.Repository repository.org repository.name)
|> withAuth model.user
|> withAuth model.session


{-| addRepository : adds a repository
-}
addRepository : PartialModel a -> Http.Body -> Request Repository
addRepository model body =
post model.velaAPI (Endpoint.Repositories Nothing Nothing) body decodeRepository
|> withAuth model.user
|> withAuth model.session


{-| restartBuild : restarts a build
-}
restartBuild : PartialModel a -> Org -> Repo -> BuildNumber -> Request Build
restartBuild model org repository buildNumber =
post model.velaAPI (Endpoint.Build org repository buildNumber) Http.emptyBody decodeBuild
|> withAuth model.user
|> withAuth model.session


{-| getBuilds : fetches vela builds by repository
-}
getBuilds : PartialModel a -> Maybe Pagination.Page -> Maybe Pagination.PerPage -> Org -> Repo -> Request Builds
getBuilds model maybePage maybePerPage org repository =
get model.velaAPI (Endpoint.Builds maybePage maybePerPage org repository) decodeBuilds
|> withAuth model.user
|> withAuth model.session


{-| getAllBuilds : used in conjuction with 'tryAll', it retrieves all pages of the resource
Expand All @@ -400,36 +395,36 @@ getAllBuilds : PartialModel a -> Org -> Repo -> Request Build
getAllBuilds model org repository =
-- we using the max perPage setting of 100 to reduce the number of calls
get model.velaAPI (Endpoint.Builds (Just 1) (Just 100) org repository) decodeBuild
|> withAuth model.user
|> withAuth model.session


{-| getBuild : fetches vela build by repository and build number
-}
getBuild : PartialModel a -> Org -> Repo -> BuildNumber -> Request Build
getBuild model org repository buildNumber =
get model.velaAPI (Endpoint.Build org repository buildNumber) decodeBuild
|> withAuth model.user
|> withAuth model.session


{-| getSteps : fetches vela build steps by repository and build number
-}
getSteps : PartialModel a -> Maybe Pagination.Page -> Maybe Pagination.PerPage -> Org -> Repo -> BuildNumber -> Request Steps
getSteps model maybePage maybePerPage org repository buildNumber =
get model.velaAPI (Endpoint.Steps maybePage maybePerPage org repository buildNumber) decodeSteps
|> withAuth model.user
|> withAuth model.session


{-| getStep : fetches vela build steps by repository, build number and step number
-}
getStep : PartialModel a -> Org -> Repo -> BuildNumber -> StepNumber -> Request Step
getStep model org repository buildNumber stepNumber =
get model.velaAPI (Endpoint.Step org repository buildNumber stepNumber) decodeStep
|> withAuth model.user
|> withAuth model.session


{-| getStepLogs : fetches vela build step log by repository, build number and step number
-}
getStepLogs : PartialModel a -> Org -> Repo -> BuildNumber -> StepNumber -> Request Log
getStepLogs model org repository buildNumber stepNumber =
get model.velaAPI (Endpoint.StepLogs org repository buildNumber stepNumber) decodeLog
|> withAuth model.user
|> withAuth model.session
Loading

0 comments on commit c81349a

Please sign in to comment.