Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a sample for pipes and filters using interceptors #118

Open
LakshanWeerasinghe opened this issue Oct 10, 2023 · 3 comments
Open

Add a sample for pipes and filters using interceptors #118

LakshanWeerasinghe opened this issue Oct 10, 2023 · 3 comments

Comments

@LakshanWeerasinghe
Copy link
Contributor

LakshanWeerasinghe commented Oct 10, 2023

Description:
$subject

@LakshanWeerasinghe
Copy link
Contributor Author

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;
}

@LakshanWeerasinghe
Copy link
Contributor Author

Also we need to have a md5 signing based csrf token or Referer-based validation.

@LakshanWeerasinghe LakshanWeerasinghe self-assigned this Oct 10, 2023
@manuranga
Copy link
Contributor

We currently have one per pattern. This is to be done if and when we support multiple samples per pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants