Giter VIP home page Giter VIP logo

keg-auth's People

Contributors

bchopson avatar bladams avatar calebsyring avatar colanconnon avatar dependabot[bot] avatar guruofgentoo avatar mtbrock avatar nzac avatar rsyring avatar tjlevel12 avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keg-auth's Issues

Automattic Syncing of Permissions Breaks

Automatic syncing of permissions doesn't seem to like it when you use a pool_pre_ping on the engine.

Traceback (most recent call last):
  File "/Users/nzac/.pyenv/versions/3.5.2/envs/racebetter/lib/python3.5/site-packages/sqlalchemy/util/_collections.py", line 988, in __call__
    return self.registry[key]
KeyError: 4348003776

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

 ... clipped a bunch of click stuff

  File "/Users/nzac/.pyenv/versions/3.5.2/envs/racebetter/lib/python3.5/site-packages/keg/cli.py", line 44, in list_commands
    info.load_app()
  File "/Users/nzac/.pyenv/versions/3.5.2/envs/racebetter/lib/python3.5/site-packages/flask/cli.py", line 229, in load_app
    rv = self.create_app(self)
  File "/Users/nzac/.pyenv/versions/3.5.2/envs/racebetter/lib/python3.5/site-packages/keg/cli.py", line 332, in create_app
    return self.appcls().init(**init_kwargs)
  File "/Users/nzac/.pyenv/versions/3.5.2/envs/racebetter/lib/python3.5/site-packages/keg/app.py", line 98, in init
    self.on_init_complete()
  File "/Users/nzac/j/level12/clients/racebetter/src/racebetter/app.py", line 55, in on_init_complete
    rbext.auth_manager.init_app(self)
  File "/Users/nzac/.pyenv/versions/3.5.2/envs/racebetter/lib/python3.5/site-packages/keg_auth/core.py", line 78, in init_app
    self.init_permissions(app)
  File "/Users/nzac/.pyenv/versions/3.5.2/envs/racebetter/lib/python3.5/site-packages/keg_auth/core.py", line 199, in init_permissions
    sync_permissions()
  File "/Users/nzac/.pyenv/versions/3.5.2/envs/racebetter/lib/python3.5/site-packages/keg_auth/core.py", line 158, in sync_permissions
    db_permissions = db.session.query(Permission).all()

...  clip a bunch of sa stuff

  File "/Users/nzac/.pyenv/versions/3.5.2/envs/racebetter/lib/python3.5/site-packages/sqlalchemy/engine/strategies.py", line 160, in create
    engineclass.__name__))
TypeError: Invalid argument(s) 'pool_pre_ping' sent to create_engine(), using configuration PGDialect_psycopg2/QueuePool/Engine.  Please check that the keyword arguments are appropriate for this combination of components.

Create easy way to login a test client

Right now, we have to do something like:

client = flask_webtest.TestApp(flask.current_app)
user = ents.User.testing_create()
with client.session_transaction() as sess:
    sess['user_id'] = user.id
resp = client.get('protected-resource', status=200)

So the with is needed for each request. We can do better than that.

process a hook for all requests

All auth is currently done via decorators on blueprints/classes/methods. We should probably add the possibility of having a global request hook.

Generate API Tokens

Rather than letting the user set their API token, generate it for them and let them see it when generated. But after that, we can only re-generate it. Like AWS does their access token generation.

follow flask_login "next" parameter on login

When using flask-login, we have the capability of using a "next" get parameter on the login route, which provides the path we should redirect to after a successful login. If the parameter is not provided, the after-login route may be used.

Example, user wants to get to /protect-all-the-things. They should get redirected to /login?next=protect-all-the-things. Once logged in, get them back to /protect-all-the-things.

`check_auth` permissions discrepancy

Currently, if a Keg view implements a check_auth method, that method can be used to determine if the user should have access to the view (ie, should a 403 be returned).

Unfortunately, the nav system doesn't seem to have any way of accessing the check_auth instance method. As a result, the nav system can include links that return a 403 when clicked.

I don't currently see any way to resolve this with the check_auth method; permissions must instead be specified using the require_permissions decorator.

If using check_auth can't be resolved, we should add an "Upgrading to keg-auth" section to the readme which specifies that check_auth should not be used.

Nav generation: add additional features

  • Lazily-evaluated labels (to support i18n)
  • Nav icons
  • Nav Groups (ie, drop-down nested nav elements)

An example of this functionality can be found in level12/atech-imp#282.

Add rate limiting on particular views

Rate limit attempts on the following views:

  • Login
  • Password reset
  • Verification

Log attempts in these views in the database and limit attempts that are allowed in a configurable time span.
Include a CLI command that can be run from a cron job to purge old records

Navigation caches is_permitted and permitted sub nodes for the first user to access the page and then other users will the same nav items

In these two functions we are caching the permitted sub_nodes and is_permitted flags for the nav items. The first construction of the navbar will work fine. If another user logs in and has the same web server instance they will see the navbar items that the first user is permitted to see.

if self._is_permitted is None:

if self._permitted_sub_nodes is None:

Removing the if self._is_permitted is None: and if self._permitted_sub_nodes is None: fixed this issue for me.

Fix rendering/formatting of readme

The readme looks really jacked up. I'm guessing Markdown outline syntax was used instead of RST or something?

image

Please get it rendering correctly.

Adjust salt to not include `session_key` or `updated_utc`

After discussion we decided to remove updated_utc and session_key from the salt. We are going to add a field to the users table last_login_utc and add that field to the salt. This field will get updated on flask_login's login event.

Document configuration changes needed for Keg Auth

    # Required for Keg Auth when generating URL in create-user CLI command.
    SERVER_NAME = '{{ nginx_vhost_server_name }}'
    # This is important so that generated auth related URLS are secure.  We have an SSL redirect
    # but by the time that would fire, the key would have already been sent in the URL.
    PREFERRED_URL_SCHEME = 'https'
    KEGAUTH_EMAIL_SITE_NAME = 'Some Thing'
    KEGAUTH_EMAIL_SITE_ABBR = 'Some Thing'

Endpoint to Permission Map

Copy from internal project:

Hindsight is 20/20, but it's now quite clear that having a mapping between endpoints and required permissions would have been a huge win. Literally every place we use url_for, we must wrap it in a conditional to only show the link (or make it clickable, etc.) if the user has permission to access that endpoint. But since there is no mapping dictionary, we must hard code the mapping at every call site. Effectively not having the mapping means there is a ton of code duplication and a truckload of room for mistakes. In fact, there are whole swaths of links that are not properly checked for this condition. It's not a security issue, but a usability issue, since the links are clickable but will inevitably result in 403s for some users. Equally as bad is the difficulty in building abstractions around endpoints such that they are "permission-aware." Without the mapping, there is no generic way to write a form of url_for that considers permissions.

make custom edit/delete access easier

CrudView.delete uses init_object to control access on a per-object basis. But, sometimes edit vs delete should yield different results. Currently, in that case, it means more has to be overridden.

  • add init_object_delete method that passes through to init_object
    • provides an override case for deletes
  • move the delete action method to a place in the view where it can be overridden

Permissions

Add support for permissions. Permissions should be assignable in the following ways:

  • Assigned directly to a user
  • Via a Bundle assigned to a user
  • Via a Group assigned to a user
  • Via a Bundle assigned to a Group assigned to a user

In applying permissions to views:

  • Create classes for permission and and or relationships that would allow more complex conditions so you could do something like permisisons_required = and_('foo', or_('bar', 'baz')) sortof sqlalchemy style
  • Set up decorator(s) to allow you to define different perms for each route and give the option of just decorating the class for all routes
    • Using the decorator should assume that authentication should be happening as well, i.e. we shouldn't also have to use @flask_login.login_required on all of those views
    • Warn if a route is not covered by a decorator
    • Store the perms on the method object so we can look them up without executing any of the view code
      • This will be useful for basic nav setup, to limit links available by permission. The nav tree shouldn't need to have permissions in it, and we shouldn't have to init a view instance to get that info.
  • Be sure to have a basic method to check if a user has access to one or more permissions, so more complex authorization can be set up

option to not require email operations

The current assumption is that all user IDs are email addresses.

The dev can overrides things, for everything from the user ID being an email address, to user activation by email, etc. We will likely need to be able to use this in environments where email won't be happening, and users may not in fact be associated with an email at all.

Email could be an all-or-nothing idea, rather than having settings for each email op. I.e. have a feature-flag kind of setting that enables email functionality, and then the user object gets an email field, maybe default the user ID to the same field, turn on activations, links in the templates, etc.
In that case, if we don't have email ops turned on, we'd be restricted to having an admin reset any passwords that are forgotten, etc.

There is a separate setting for what field in the model is the user identifier for login (KEGAUTH_USER_IDENT_FIELD).

Pieces that would be affected:

  • user model (email is non-nullable and unique)
  • CLI (requires email by default, though that can be overridden)
  • user form (assumes email)
  • login form (assumes email)
  • forgot password view (assumes email input, view would be meaningless outside of email context)
  • reset password views (currently assumes a token will be passed in that would have been sent via email)
  • user grid
  • AuthManager requires mail extension to be passed in

CrudView template arguments

CrudView should assign more template arguments out of the box.

The following are rendered by crud-list.html but are not assigned by CrudView:

  • object_name
  • page_heading

page_heading also appears in form-base.html but is not assigned when rendering forms in CrudView.

Override Default PASSLIB CRYTPOCONTEXT?

Do we need to set the value to something other than the default? If so, is there a better way to set/enforce this than to have the apps have to remember to set it in their config?

PASSLIB_CRYPTCONTEXT_KWARGS = {
     'schemes': ['bcrypt']
}

Add flexibility in CLI

Right now, if you have a user model that adds something like name, and you require that name in the model, the only way to make the CLI command require it is to override the CLI implementation.

permission changes should trigger invalidation

A user's current permission set at login will get stored in the session, so we don't have to run expensive queries constantly. The tradeoff to that is when permissions change for the user or related groups/bundles, that session will have to update, lest the user have access to something now denied, etc.

We've done this at the app level before in the blaze world, where we had a known session backend (beaker). We should see if flask has an API to access sessions and invalidate them according to whether they have particular data (e.g. the user ID) in them. If not, we would need to create plugins for our most-used session storage backends.

user disable date

In some projects we have the ability to set a date at which the user becomes disabled, which has been useful over time. The logic becomes, the user is active if:

  • the verified flag is set
  • the enabled flag is set
  • the disable date is not set OR the disabled date is in the future

Add helper method for getting the current user

At present, the current user can obtained from flask_login.current_user. This is somewhat of an internal detail, however, and future authenticators might not use the flask_login system.

Add a method which provides access to the current user.

Per @guruofgentoo, simply returning flask_login.current_user should be sufficient for now.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.