Skip to content
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
10 changes: 6 additions & 4 deletions integration/appaccess/appaccess_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,11 @@ func testForward(p *Pack, t *testing.T) {
},
{
desc: "invalid application session cookie, redirect to login",
inCookies: []*http.Cookie{{
Name: app.CookieName,
Value: "D25C463CD27861559CC6A0A6AE54818079809AA8731CB18037B4B37A80C4FC6C"},
inCookies: []*http.Cookie{
{
Name: app.CookieName,
Value: "D25C463CD27861559CC6A0A6AE54818079809AA8731CB18037B4B37A80C4FC6C",
},
},
outStatusCode: http.StatusFound,
},
Expand Down Expand Up @@ -576,7 +578,7 @@ func testInvalidateAppSessionsOnLogout(p *Pack, t *testing.T) {
require.Equal(t, http.StatusOK, status)

// Logout from Teleport.
status, _, err = p.makeWebapiRequest(http.MethodDelete, "sessions", []byte{})
status, _, err = p.makeWebapiRequest(http.MethodDelete, "sessions/web", []byte{})
require.NoError(t, err)
require.Equal(t, http.StatusOK, status)

Expand Down
23 changes: 15 additions & 8 deletions lib/web/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,12 +505,19 @@ func (h *Handler) bindDefaultEndpoints() {
// Forwards traces to the configured upstream collector
h.POST("/webapi/traces", h.WithAuth(h.traces))

// Web sessions
h.POST("/webapi/sessions/web", httplib.WithCSRFProtection(h.WithLimiterHandlerFunc(h.createWebSession)))
// App sessions
h.POST("/webapi/sessions/app", h.WithAuth(h.createAppSession))
h.DELETE("/webapi/sessions", h.WithAuth(h.deleteSession))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should keep the old routes around for a while to avoid breakages. Are these only ever used by the Web UI?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only see them being used by the Web UI. Although maybe there's some compatibility guarantee we make towards 3rd party clients?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with adding a "DELETE IN 12.0" as long as we don't finally get to deleting in 17.1 😂

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a deprecated session for the older routes. Didn't know when to put a "DELETE" but left a comment to this PR to give context.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the compatibility guarantee is more in terms of binary versions than APIs, but this is more to play it safe.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's put DELETE IN 13 and let's go back and do this as soon as we cut the v12 branch next week so we don't forget again.

h.POST("/webapi/sessions/renew", h.WithAuth(h.renewSession))

// DELETE IN 13, deprecated/unused web sessions routes (avatus)
// https://github.com/gravitational/teleport/pull/19892
h.POST("/webapi/sessions", httplib.WithCSRFProtection(h.WithLimiterHandlerFunc(h.createWebSession)))
h.DELETE("/webapi/sessions", h.WithAuth(h.deleteWebSession))
h.POST("/webapi/sessions/renew", h.WithAuth(h.renewWebSession))

// Web sessions
h.POST("/webapi/sessions/web", httplib.WithCSRFProtection(h.WithLimiterHandlerFunc(h.createWebSession)))
h.DELETE("/webapi/sessions/web", h.WithAuth(h.deleteWebSession))
h.POST("/webapi/sessions/web/renew", h.WithAuth(h.renewWebSession))
h.POST("/webapi/users", h.WithAuth(h.createUserHandle))
h.PUT("/webapi/users", h.WithAuth(h.updateUserHandle))
h.GET("/webapi/users", h.WithAuth(h.getUsersHandle))
Expand Down Expand Up @@ -1720,14 +1727,14 @@ func clientMetaFromReq(r *http.Request) *auth.ForwardedClientMetadata {
}
}

// deleteSession is called to sign out user
// deleteWebSession is called to sign out user
//
// DELETE /v1/webapi/sessions/:sid
//
// Response:
//
// {"message": "ok"}
func (h *Handler) deleteSession(w http.ResponseWriter, r *http.Request, _ httprouter.Params, ctx *SessionContext) (interface{}, error) {
func (h *Handler) deleteWebSession(w http.ResponseWriter, r *http.Request, _ httprouter.Params, ctx *SessionContext) (interface{}, error) {
err := h.logout(r.Context(), w, ctx)
if err != nil {
return nil, trace.Wrap(err)
Expand Down Expand Up @@ -1755,14 +1762,14 @@ type renewSessionRequest struct {
ReloadUser bool `json:"reloadUser"`
}

// renewSession updates this existing session with a new session.
// renewWebSession updates this existing session with a new session.
//
// Depending on request fields sent in for extension, the new session creation can vary depending on:
// - AccessRequestID (opt): appends roles approved from access request to currently assigned roles or,
// - Switchback (opt): roles stacked with assuming approved access requests, will revert to user's default roles
// - ReloadUser (opt): similar to default but updates user related data (e.g login traits) by retrieving it from the backend
// - default (none set): create new session with currently assigned roles
func (h *Handler) renewSession(w http.ResponseWriter, r *http.Request, params httprouter.Params, ctx *SessionContext) (interface{}, error) {
func (h *Handler) renewWebSession(w http.ResponseWriter, r *http.Request, params httprouter.Params, ctx *SessionContext) (interface{}, error) {
req := renewSessionRequest{}
if err := httplib.ReadJSON(r, &req); err != nil {
return nil, trace.Wrap(err)
Expand Down
20 changes: 11 additions & 9 deletions lib/web/apiserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ func noCache(clt auth.ClientI, cacheName []string) (auth.RemoteProxyAccessPoint,
}

func (r *authPack) renewSession(ctx context.Context, t *testing.T) *roundtrip.Response {
resp, err := r.clt.PostJSON(ctx, r.clt.Endpoint("webapi", "sessions", "renew"), nil)
resp, err := r.clt.PostJSON(ctx, r.clt.Endpoint("webapi", "sessions", "web", "renew"), nil)
require.NoError(t, err)
return resp
}
Expand Down Expand Up @@ -775,7 +775,7 @@ func TestWebSessionsCRUD(t *testing.T) {
// now delete session
_, err = pack.clt.Delete(
context.Background(),
pack.clt.Endpoint("webapi", "sessions"))
pack.clt.Endpoint("webapi", "sessions", "web"))
require.NoError(t, err)

// subsequent requests trying to use this session will fail
Expand Down Expand Up @@ -1129,15 +1129,17 @@ func TestNewTerminalHandler(t *testing.T) {
ID: session.ID("not a uuid"),
},
},
}, {
},
{
expectedErr: "login: missing login",
cfg: TerminalHandlerConfig{
SessionData: session.Session{
ID: session.NewID(),
Login: "",
},
},
}, {
},
{
expectedErr: "server: missing server",
cfg: TerminalHandlerConfig{
SessionData: session.Session{
Expand Down Expand Up @@ -1921,7 +1923,7 @@ func TestCloseConnectionsOnLogout(t *testing.T) {
_, err = stream.Read(out)
require.NoError(t, err)

_, err = pack.clt.Delete(s.ctx, pack.clt.Endpoint("webapi", "sessions"))
_, err = pack.clt.Delete(s.ctx, pack.clt.Endpoint("webapi", "sessions", "web"))
require.NoError(t, err)

// wait until we timeout or detect that connection has been closed
Expand Down Expand Up @@ -3735,7 +3737,7 @@ func TestApplicationWebSessionsDeletedAfterLogout(t *testing.T) {
require.Len(t, sessions, len(applications))

// Logout from Telport.
_, err = pack.clt.Delete(context.Background(), pack.clt.Endpoint("webapi", "sessions"))
_, err = pack.clt.Delete(context.Background(), pack.clt.Endpoint("webapi", "sessions", "web"))
require.NoError(t, err)

// Check sessions after logout, should be empty.
Expand Down Expand Up @@ -4481,7 +4483,7 @@ func TestWebSessionsRenewAllowsOldBearerTokenToLinger(t *testing.T) {
// now delete session
_, err = newPack.clt.Delete(
context.Background(),
pack.clt.Endpoint("webapi", "sessions"))
pack.clt.Endpoint("webapi", "sessions", "web"))
require.NoError(t, err)

// subsequent requests to use this session will fail
Expand Down Expand Up @@ -6859,7 +6861,7 @@ func TestUserContextWithAccessRequest(t *testing.T) {
accessRequestID := accessReq.GetMetadata().Name

// Make a request to renew the session with the ID of the access request.
_, err = pack.clt.PostJSON(ctx, pack.clt.Endpoint("webapi", "sessions", "renew"), renewSessionRequest{
_, err = pack.clt.PostJSON(ctx, pack.clt.Endpoint("webapi", "sessions", "web", "renew"), renewSessionRequest{
AccessRequestID: accessRequestID,
})
require.NoError(t, err)
Expand Down Expand Up @@ -7387,7 +7389,7 @@ func TestLogout(t *testing.T) {
require.Len(t, clusters, 1)

// logout from proxy 1
_, err = pack.clt.Delete(ctx, pack.clt.Endpoint("webapi", "sessions"))
_, err = pack.clt.Delete(ctx, pack.clt.Endpoint("webapi", "sessions", "web"))
require.NoError(t, err)

// ensure proxy 1 invalidated the session
Expand Down