Unfortunately, that doesn't work -- when I set an ...
# ktor
m
Unfortunately, that doesn't work -- when I set an interceptor on a phase in the Application's Pipeline, that executes before the Route-specific Pipeline. Is there a different way I should be applying defaults to the Application's Pipeline?
d
Have you managed to fix this? If not, do you have the non-working code somewhere, so I can have a look?
m
I didn't end up committing the not-working state, but you can see the current version at https://bitbucket.org/marshallpierce/ktor-csrf/src/master/. I switched to having to apply a
csrfProtection
to all routes where protection is needed (which in my use case is 95% of them) because I couldn't find another way to do it. It does seem like potentially very useful functionality to be able to specify a global change with per-route overrides, though. Authentication could benefit from this as well, I think -- what if 80% of your endpoints are authenticated?
The non-working state is basically a hybrid of https://bitbucket.org/marshallpierce/ktor-csrf/src/991ce7b4c864b730f3ced1d640ccd2210cac9e47/src/main/kotlin/org/mpierce/ktor/csrf/CsrfProtection.kt#lines-50 (intercept pipeline at feature install time) and https://bitbucket.org/marshallpierce/ktor-csrf/src/6025767ba27235f59de438c2d1266fe4ad42cea4/src/main/kotlin/org/mpierce/ktor/csrf/CsrfProtection.kt#lines-68 (intercept pipeline at route helper call time) -- I tried to insert an additional phase before
CsrfProtection
phase that would set a call attribute (to a dummy object) that I could then look for in the "global" intercept.
Perhaps with a better understanding of how per-route pipelines are constructed and how they relate to the application pipeline there is a way. I poked around in the debugger looking at the pipeline structure and I couldn't find a way.
d
Going to check
I have been trying, without luck. This is my current approach for a blacklist approach: https://github.com/soywiz/marshallpierce-ktor-csrf/commit/379f0425f11c78b8e9c4a3ca6a93704132029f89 The idea is to intercept, per route, both when whitelisting or when blacklisting. Put an attribute in the call marking it. And then have another phase executing for all the routes after that, and if with the marking and the mode (blacklist / whitelist) you can then decide what to do. But somehow the phase I install at the application level, is always executing before the route ones, so obviously it doesn’t work. Going to ask internally how do to this.
After asking internally I have managed to do it. Here is the code with it working: https://github.com/soywiz/marshallpierce-ktor-csrf/compare/intercept.whitelist.blacklist Later I will revisit documentation to try to explain pipeline internals better. What I have done is to create two Phases. The Routing feature has its own pipeline at the root’s Call phase. So I registered a phase to be executed later at the Routing pipeline. And then another interception per route. Each route merges the interceptions from the routing tree, so I inserted the per route interception phase before the global one. And that’s it. Hope it helps!
m
Thanks for looking into it! I’m traveling this weekend but I’ll definitely dig in when I get back!
👍 1
d
For the record. I have updated the pipeline page with more contents: https://ktor.io/advanced/pipeline.html (If you have the chance other day, let me know if it is now easier to understand or if I still have to adjust a few things)
m
Your code was really helpful, thanks. RE the doc improvements, the notes about merging and when you need to
addPhase
are helpful in retrospect, but I think they would make more sense to a new reader if how pipeline merging was done in routes. Otherwise, I think people will just glaze over because they wouldn't know yet that they care about merging. Otherwise, looks good. It's a somewhat abstract concept so I'm not sure how much you can really do in just docs without saying "here's some code, figure it out"
👍 1
👌 1