Search code examples
pythongoogle-app-enginewebapp2

GAE webapp2 delete all UserTokens (drop all sessios) for specific user


I want to drop all user sessions when user resets his password, but I can't find a way to do that. My idea was to get all UserTokens of the specific user and delete them, but it seems impossible, because of

user = model.StringProperty(required=True, indexed=False)

in UserToken model

Any ideas how to do that?


Solution

  • I see two ways how to do that.

    First is to inherit from the UserToken class making user an indexed property. Then you can set the token_model class property to your new token model in your user class. Here is the code:

    class MyToken(UserToken):
        user = ndb.StringProperty(required=True)
    
    class MyUser(User):
        token_model = MyToken
        # etc.
    

    Don't forget to set the user model used by webapp2 to your user class if you do not do it already:

    webapp2_config = {
        "webapp2_extras.auth": {
            "user_model": "models.MyUser"
        },
        # etc.
    }
    
    app = webapp2.WSGIApplication(routes, config=webapp2_config)
    

    The second way is to make a complicated datastore query based on the token key name. Since the key names are of the form <user_id>.<scope>.<random>, it is possible to retrieve all the entities starting with a specific user ID. Have a look at the code:

    def query_tokens_by_user(user_id):
        min_key = ndb.Key(UserToken, "%s." % user_id)
        max_key = ndb.Key(UserToken, "%s/" % user_id)  # / is the next ASCII character after .
        return UserToken.query(UserToken.key > min_key, UserToken.key < max_key)
    

    This uses the fact that the query by key names works in the lexicographical order.