playframework / play-ebean

Play Ebean module
Apache License 2.0
102 stars 69 forks source link

Who Created/Who Modified/Change Log: How to get current user? #196

Closed jtammen closed 3 years ago

jtammen commented 4 years ago

As Http.Context.current() is not available anymore since Play 2.8, I wonder how to get access to the current user from my CurrentUserProvider or ChangeLogPrepare.

I used to store the current user in the request attributes.

Does anyone have a working implementation of io.ebean.config.CurrentUserProvider in a Play 2.8 project?

Maco03 commented 3 years ago

I'm facing the same issue here. Have you eventually figured out how to get Context information into the CurrentUserProvider implementation?

jmswenski commented 3 years ago

So, play got rid of Http.Context.current() of course. Ideally your persistence layers and your http layers are not so tightly coupled that CurrentUserProvider is leveraging something like Http.Context.current(). I think io.ebean.config.CurrentUserProvider interface should probably be enhanced to take some sort of pluggable or perhaps I'm not thinking about the solution correctly - in any case. I did something like this in the mean time (re-create the threadlocal that Http.Context.current() was doing) and setting it up on user authorization while I work on figuring out how to better decouple these things:

public class HttpSession {

    public static class Context {

        private final Long userId;

        private static final ThreadLocal<Context> current = new ThreadLocal<>();

        public static Option<Context> current() {
            return option(Context.current.get());
        }

        public static void setCurrent(Context ctx) {
            Context.current.set(ctx);
        }

        public static void clear() {
            Context.current.remove();
        }

        public Context(Long userId) {
            this.userId = userId;
        }

        public Long getUserId() {
            return userId;
        }
    }
}
@Override
    public Object currentUser() {
            return HttpSession.Context
                .current()
                .map(HttpSession.Context::getUserId)
                .getOrElse(SYSTEM_USER);
    }
petahathub commented 3 years ago

Hi, any news in this topic?

I am afraid your HttpSession would be hard to use, if i used thread pool for rendering (controllers layer) and another database thread pool for accessing database.

And what about calling clear method after request was processed in play framework infrastructure?

hapreanmanuel commented 3 years ago

Hello,

I am also looking into this topic and try to configure a CurrentUserProvider in Play 2.8

@jmswenski would you recommend creating the same classes locally in the project?

ghost commented 3 years ago

If I understand correctly how Play works, the snippet provided by @jmswenski would not do well with AkkaHTTPServer due to requests not having one unique thread to themselves, therefore ThreadLocal not being a good idea.

I am currently also trying to implement CurrentUserProvider, and am unsure whether this issue should have been closed. I'd love if someone with more experience in Play/Akka/EBean could point me (and future googlers who land here) into the right direction.

LeComptoirDesPharmacies commented 3 years ago

Hi everyone,

We faced the same problem on our side. Impossible to access HTTP Request context from CurrentUserProvider. If there is any progression on this topic, feel free to share your ideas.

Yours faithfully, LCDP