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

Flask 0.10.1, app_context and "_AppCtxGlobals object has no 'identity'" #26

Closed
cybertoast opened this issue Dec 20, 2013 · 5 comments
Closed

Comments

@cybertoast
Copy link

I've got an issue that I don't quite know how to articulate but it's due to updates in Flask from 0.9 -> 0.10. I'm using Flask-Principal==0.4.0, Flask-Login==0.2.7.

I've got a permission-decorated function that's somethink like the below:

@admin_role.require(http_exception=401)
def do_stuff():
    return jsonify(code=200)

content_editor_role is defined as:

admin_role = Permission(RoleNeed('admin'))

Something changed between between flask==0.9 and flask==0.10.1 which is causing the below exception stack to be thrown on this decorated (permission-restricted) function:

  File "/Users/sundar/.virtualenvs/mmweb/lib/python2.6/site-packages/flask_principal.py", line 198, in _decorated
    with self:
  File "/Users/sundar/.virtualenvs/mmweb/lib/python2.6/site-packages/flask_principal.py", line 205, in __enter__
    if not self.can():
  File "/Users/sundar/.virtualenvs/mmweb/lib/python2.6/site-packages/flask_principal.py", line 193, in can
    return self.identity.can(self.permission)
  File "/Users/sundar/.virtualenvs/mmweb/lib/python2.6/site-packages/flask_principal.py", line 188, in identity
    return g.identity
  File "/Users/sundar/.virtualenvs/mmweb/lib/python2.6/site-packages/werkzeug/local.py", line 338, in __getattr__
    return getattr(self._get_current_object(), name)
AttributeError: '_AppCtxGlobals' object has no attribute 'identity'

Note that this happens ONLY when I run this from a flask-script through an app_context():

def run_script_task():
    with app.app_context():
        from myapp.views.api import cleanup
        cleanup.do_stuff()

And this basically is telling me that something is weird when I use the app_context to "fake" a user's identity.

I'm posting this here in case anyone knows what this might be from, since I'm at a bit of a loss. I'm going to start looking at the source to see if I can trace anything, but would appreciate any suggestions as well.

Thanks much!

@mattupstate
Copy link
Collaborator

I believe there was some changes to how the contexts (app and request) are handled between Flask version. But you're problem lies in the fact that flask-principal only works when there is a a request context. See this code. In the context of a Flask-Script command you only have an app context.

@cybertoast
Copy link
Author

Thanks much. I guess flask 0.9's bundling of a bunch of request context stuff into the app context was a convenient (but sadly incorrect) accident.
The problem I'm actually grappling with (which I'll have to think about now) is how to provide a request context to a celery task (which is what the script is calling, if celery is running). I think I unfortunately went down the path of writing my code with this app-context hack.
So I now need to think about a correct approach; speaking of which, I know you use celery (per one of your blog posts) .. do you have any suggestions on writing a script to execute a celery task (which executes a function as an authenticated user)?
Thanks much in any case - at least I now know the general path I need to traverse :)

@mattupstate
Copy link
Collaborator

The trick will be to update the identity to be that of the user that initiated the delayed task in the context of the Celery app. You could send the user's ID along as an argument to the task, then load the user before doing anything else, then construct the Identity object, and pass it to the identity_changed signal so that the context is properly updated before calling your protected method.

@cybertoast
Copy link
Author

Thanks much. Gives me some idea of where to start :)

On Mon, Dec 23, 2013 at 3:47 PM, Matt Wright notifications@github.comwrote:

The trick will be to update the identity to be that of the user that
initiated the delayed task in the context of the Celery app. You could send
the user's ID along as an argument to the task, then load the user before
doing anything else, then construct the Identity object, and pass it to
the identity_changed signal so that the context is properly updated
before calling your protected method.


Reply to this email directly or view it on GitHubhttps://github.com//issues/26#issuecomment-31142939
.

@Abdur-rahmaanJ
Copy link
Member

Closing as solved.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

3 participants