client/logout.aug
OpenID Connect login application · Source and specification
Files in this project
main.augclient/contracts.augclient/endpoints.augclient/export.augclient/login.augclient/logout.augclient/protocol.augclient/session.augclient/views.augcommon/export.augcommon/headers.augcommon/keys.augcommon/settings.augcommon/views.augprovider/authorization.augprovider/contracts.augprovider/credentials.augprovider/discovery.augprovider/export.augprovider/token.augprovider/userinfo.augprovider/views.aug
Code
// aug-spec: "logout.aug.md" explains this file. Read it before changes; refresh with aug spec.
import SessionClaims and SessionError and LogoutForm from contracts
import authenticate from session
import settings and SigningKeys and KeyError and securityHeaders and withCookie from common
import Crypto from crypto
import Clock from time
import ExpiringStore from memory
/** POST logout checks the origin and session-bound CSRF value, then removes the live registry entry before clearing the cookie. */
endpoint POST "/logout" as logout(LogoutForm input from form, optional string token from cookie "aug_session", optional string origin from header, resolve Crypto crypto, resolve Clock clock, resolve SigningKeys keys, resolve ExpiringStore<SessionClaims> sessions) unless SessionError with status 403 and KeyError and TimeError and CryptoError and HttpError:
config = settings()
if origin != config.baseUrl:
throw SessionError()
session = authenticate(token)
if not crypto.equal(left=input.csrf.bytes(), right=session.csrf.bytes()):
throw SessionError()
sessions.take(key=session.jti, now=clock.now())
headers = withCookie(
headers=securityHeaders().with(name="location", value="/"),
name="aug_session",
value="",
path="/",
maxAge=0,
secure=config.secureCookies
)
return HttpResponse(body=<p>Signed out.</p>, status=303, headers=headers)// aug-spec: "logout.aug.md" explains this file. Read it before changes; refresh with aug spec.
import SessionClaims and SessionError and LogoutForm from contracts
import authenticate from session
import settings and SigningKeys and KeyError and securityHeaders and withCookie from common
import Crypto from crypto
import Clock from time
import ExpiringStore from memory
/** POST logout checks the origin and session-bound CSRF value, then removes the live registry entry before clearing the cookie. */
endpoint POST "/logout" as logout(LogoutForm input from form, optional string token from cookie "aug_session", optional string origin from header, resolve Crypto crypto, resolve Clock clock, resolve SigningKeys keys, resolve ExpiringStore<SessionClaims> sessions) unless SessionError with status 403 and KeyError and TimeError and CryptoError and HttpError {
config = settings()
if origin != config.baseUrl {
throw SessionError()
}
session = authenticate(token)
if not crypto.equal(left=input.csrf.bytes(), right=session.csrf.bytes()) {
throw SessionError()
}
sessions.take(key=session.jti, now=clock.now())
headers = withCookie(
headers=securityHeaders().with(name="location", value="/"),
name="aug_session",
value="",
path="/",
maxAge=0,
secure=config.secureCookies
)
return HttpResponse(body=<p>Signed out.</p>, status=303, headers=headers)
}Compiled specification
Plain handler results default to HTTP 200 unless another status is declared. HttpResponse values choose their own status. Unhandled request failures return HTTP 500 and cancel the request tasks.
logout · source
logout handles POST /logout. POST logout checks the origin and session-bound CSRF value, then removes the live registry entry before clearing the cookie.
It takes input as LogoutForm from the HTTP form, token as optional string from the HTTP cookie aug_session, and origin as optional string from the HTTP header. It gets crypto (Crypto), clock (Clock), keys (SigningKeys), and sessions (ExpiringStore<SessionClaims>) from dependency injection. Omitted optional inputs are null. It can call Crypto.equal, Clock.now, ExpiringStore<SessionClaims>.take, SigningKeys.session, Crypto.publicRsa, ExpiringStore<SessionClaims>.get, Crypto.decodeBase64url, and Crypto.verifyRsa.
The handler responds with HTTP 403 for SessionError. It can also raise CryptoError, HttpError, KeyError, and TimeError.
It gets config from settings. It checks that origin equals config.baseUrl. It raises a SessionError at the first failed check. It sets session to authenticate with token using injected crypto, clock, keys, and sessions. source
It checks that crypto.equal with left from the UTF-8 bytes of input.csrf and right from the UTF-8 bytes of session.csrf returns true. It raises a SessionError at the first failed check. It calls sessions.take with key from session.jti and now from clock.now. It sets headers to withCookie with headers from securityHeaders with the header "location" set to "/", name "aug_session", value "", path "/", maxAge 0, and secure from config.secureCookies. source
It returns HTTP 303 with a paragraph containing Signed out. with escaped text and headers headers. source
Checked interface
logout(LogoutForm input, optional string token, optional string origin, resolve Crypto crypto, resolve Clock clock, resolve SigningKeys keys, resolve ExpiringStore<SessionClaims> sessions) returns HttpResponse<Html> unless CryptoError and HttpError and KeyError and SessionError and TimeError uses Crypto.equal, Clock.now, ExpiringStore<SessionClaims>.take, SigningKeys.session, Crypto.publicRsa, ExpiringStore<SessionClaims>.get, Crypto.decodeBase64url, Crypto.verifyRsaIt takes input as LogoutForm from the HTTP form, token as optional string from the HTTP cookie aug_session, and origin as optional string from the HTTP header. It gets crypto (Crypto), clock (Clock), keys (SigningKeys), and sessions (ExpiringStore<SessionClaims>) from dependency injection. Omitted optional inputs are null. It can call Crypto.equal, Clock.now, ExpiringStore<SessionClaims>.take, SigningKeys.session, Crypto.publicRsa, ExpiringStore<SessionClaims>.get, Crypto.decodeBase64url, and Crypto.verifyRsa.
The handler responds with HTTP 403 for SessionError. It can also raise CryptoError, HttpError, KeyError, and TimeError.
Dependencies
It uses ExpiringStore (get and take) from memory. It uses Crypto (decodeBase64url, equal, publicRsa, and verifyRsa) from crypto. It uses Clock (now) from time. It uses LogoutForm (csrf), SessionClaims (csrf and jti), and SessionError from contracts.
It uses authenticate from session. It uses securityHeaders, withCookie, KeyError, SigningKeys (session), and settings from common. It uses Settings (baseUrl and secureCookies).
Built-in operations follow the language reference.