Open LakshanWeerasinghe opened 11 months ago
Here is a sample code that can be used.
import ballerina/cache;
import ballerina/http;
import ballerina/uuid;
type NewOrder record {|
*OrderRequest;
string id;
|};
type OrderRequest record {|
Item[] items;
string deliveryAddress;
|};
type Item record {|
string code;
int quantity;
|};
service class AuthInterceptor {
*http:RequestInterceptor;
resource function 'default [string... path](http:RequestContext ctx, http:Request req) returns http:NextService|http:HeaderNotFoundError|error? {
string csrfToken = check req.getHeader("X-CSRF-Token");
if csrfTokenStore.hasKey(csrfToken) {
return ctx.next();
}
return error http:ClientAuthError("Invalid csrf token");
}
}
service class RequestValidationInterceptor {
*http:RequestInterceptor;
resource function post 'order(http:RequestContext ctx, http:Request req) returns http:NextService|error? {
json orderRequestJson = check req.getJsonPayload();
OrderRequest orderRequest = check orderRequestJson.fromJsonWithType();
if orderValidate(orderRequest) {
return ctx.next();
}
return error ("Invalid request payload");
}
}
final cache:Cache csrfTokenStore = new (capacity = 100, defaultMaxAge = 14400);
final http:Client firebaseClient = check new ("http://api.orders.firebase.com.balmock.io");
service http:InterceptableService /api/v1 on new http:Listener(8080) {
public function createInterceptors() returns http:RequestInterceptor[] {
return [new AuthInterceptor(), new RequestValidationInterceptor()];
}
resource function post 'order(OrderRequest orderRequest) returns NewOrder|error {
string id = uuid:createType1AsString();
NewOrder newOrder = {
id,
...orderRequest
};
_ = check firebaseClient->/orders\.json.post(newOrder, targetType = http:Response);
return newOrder;
}
}
function orderValidate(OrderRequest orderRequest) returns boolean {
foreach Item item in orderRequest.items {
if item.quantity <= 0 {
return false;
}
}
return true;
}
Also we need to have a md5 signing based csrf token or Referer-based validation.
We currently have one per pattern. This is to be done if and when we support multiple samples per pattern.
Description: $subject