Skip to content

Commit

Permalink
Add support for session-less requests
Browse files Browse the repository at this point in the history
  • Loading branch information
Gene Gleyzer committed Nov 20, 2024
1 parent 0709d21 commit 6583652
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
3 changes: 3 additions & 0 deletions lib_web/src/main/x/web.x
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ module web.xtclang.org {
mixin Consumes(MediaType|MediaType[] consumes)
into Class<WebApp> | Class<WebService> | Endpoint;

mixin SessionOptional
into Class<WebApp> | Class<WebService> | Endpoint;

/**
* This annotation, `@LoginRequired`, is used to mark a web service call -- or any containing
* class thereof, up to the level of the web module itself -- as requiring authentication.
Expand Down
39 changes: 32 additions & 7 deletions lib_xenia/src/main/x/xenia/Catalog.x
Original file line number Diff line number Diff line change
Expand Up @@ -117,26 +117,39 @@ const Catalog(WebApp webApp, String systemPath, WebServiceInfo[] services, Class
: new UriTemplate(templateString);

// check if the template matches UriParam's in the method
Int requiredParamCount = 0;
Int requiredParamCount = 0;
Boolean requiredSessionParam = False;
Boolean hasBodyParam = False;
for (Parameter param : method.params) {
// well-known types are Session and RequestIn (see ChainBundle.ensureCallChain)
if (param.ParamType.is(Type<Session>) ||
param.ParamType == RequestIn ||
if (param.ParamType == RequestIn ||
param.is(QueryParam) ||
param.is(BodyParam) ||
param.defaultValue()) {
continue;
}
if (param.is(BodyParam)) {
if (hasBodyParam) {
throw new IllegalState($|The template for method "{method}" has more than \
|one "@BodyParam" annotated parameter
);
}
hasBodyParam = True;
continue;
}

if (param.ParamType.is(Type<Session>)) {
requiredSessionParam = True;
continue;
}

assert String name := param.hasName();
if (param.is(UriParam)) {
name ?= param.bindName;
}
if (!template.vars.contains(name)) {
throw new IllegalState($|The template for method "{method}" is missing \
|a variable name "{name}": \
|"{templateString}"
);
|a variable name "{name}": "{templateString}"
);
}
requiredParamCount++;
}
Expand All @@ -146,6 +159,13 @@ const Catalog(WebApp webApp, String systemPath, WebServiceInfo[] services, Class
? !method.is(HttpsOptional)
: method.is(HttpsRequired);

this.requiresSession = !method.is(SessionOptional);
if (requiredSessionParam && !requiresSession) {
throw new IllegalState($|Invalid "@SessionOptional" annotation for endpoint \
|"{method}"; parameters require a session
);
}

this.requiredTrust = switch (method.is(_)) {
case LoginRequired: TrustLevel.maxOf(serviceTrust, method.security);
case LoginOptional: None; // explicitly optional overrides service trust level
Expand Down Expand Up @@ -213,6 +233,11 @@ const Catalog(WebApp webApp, String systemPath, WebServiceInfo[] services, Class
*/
Boolean requiresTls;

/**
* Indicates if this endpoint requires an http session.
*/
Boolean requiresSession;

/**
* [TrustLevel] of security that is required by the this endpoint.
*/
Expand Down
2 changes: 1 addition & 1 deletion lib_xenia/src/main/x/xenia/Dispatcher.x
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ service Dispatcher {
requestInfo.clientAddress);
}

if (redirect) {
if (redirect && endpoint.requiresSession) {
Int|HttpStatus redirectResult = session.prepareRedirect_(requestInfo);
if (redirectResult.is(HttpStatus)) {
RequestIn request = new Http1Request(requestInfo, []);
Expand Down

0 comments on commit 6583652

Please sign in to comment.