BartOtten
Currently I am writing a small macro which adds authorization functionality to a function. Rewrite ‘def’ to ‘defprot’ and add the rules to an Authorization module. Too easy it is.
defmodule One do
defprot bar(), do: :result
enddefmodule Two do
def foo(), do: One.bar()
end
In order to write nice debug information and add the possibility to create enforced boundaries between (context) modules, I need the names of the ‘calling’ Function and Module in a macro. Saving them as an environment variable and retrieving them in the macro does work while developing but A: ain’t nice and B: would be useless in case of concurrency.
The output should become:
iex > Two.foo()
[debug] "Two.foo() requested authorization to access One.bar()"
Is there a good way to retrieve the information of the calling Module (Two) and calling Function (foo) while in One.bar()?
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
Other Trending Topics
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #hex
- #security










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
OvermindDL1
For Macro’s you can access the callers environment inside the
__CALLER__argument (implicitly passed in to every macro call).It’s just a normal Macro.Env struct.
BartOtten
__CALLER__returns the current calling environment as a Macro.Env struct; a struct that holds compile time environment information. That’s why you can’t use it in aquote block.However, I need run time information. When function
Two.foo/1is calling functionOne.bar/1as in the example, the caller should beTwo.foo/1(info might be split in callingMod en callingFunc)NobbZ
A function should not care from where it is called. It should return the same regardless the caller.
If though you really have to, you could do it similar how logger injects metadata.
Use a macro which takes the arguments defined by your API, injects code to collect metadata and then delegates to a function that takes the actual arguments AND the collected metadata.
michalmuskala
You can use
Process.info(self(), :current_stacktrace)to get the current stacktrace (and the calling function should be there), but this is generally considered a debugging utility, not something to be used in production.Additionally, be aware that tail calls don’t produce stack entries, so in a code like this:
The stacktrace information won’t include
foo().BartOtten
Figured it out myself, but michalmuska was right. Code became:
Now I need to handle the ‘no stack entry’ situation, somehow
@NobbZ Will have a look at the proposal. Thanks for the input.
OvermindDL1
I’m exceptionally curious, “what” are you trying to accomplish? o.O
BartOtten
An insane experiment to build a non plug-based authorization code which can easily applied on existing modules, functions, con(n/text) and even arguments. In Phoenix applications authorization is quite easy as Phoenix uses conventions and does normalize a lot to (conn, object map, current_user). Custom applications don’t have such thing. I doubt I will even succeed, but it’s worth to spend a week of my free time on as I learn a lot
Had a working POC which needed environment variables to work; which would make it useless. If I can take those out, it might actually be a nice solution to secure an otherwise insecure codebase without much rewrites.
If there is a solid way to track which Module and Function did the request, it will also be possible to pattern match at those. Allowing (for example) to mimic defp (just because we can…) or reject all calls to functions which write to the database unless the authorization rules allow them to.
Edit: If I ever find a good solution, I will try to have it added to GitHub - arjan/decorator: Function decorators for Elixir · GitHub, as that lib is doing 90% of what I wrote already. Now only those few last bits…
Edit2: Gotta get some sleep…sigh
BartOtten
Status update:
It is possible, yet it has so many side effects it will never see an open repository for too many good reasons.
Conclusion: Meta programming and message passing between processes rock. Never underestimate their power, but use them wisely.
Read before complains
I did not bother to print arity instead of () anymore as the experiment has ended.
OvermindDL1
Hah, interesting though. ^.^
BartOtten
I’ll clean up the POC one day and request some additional functionality in Elixir to make it possible without a zillion hacks. Now I have a demo to demonstrate the concept