Code Monkey home page Code Monkey logo

invenio-accounts's Introduction

Invenio-Accounts

Invenio user management and authentication.

Features:

  • User and role management.
  • User registration, password reset/recovery and email verification.
  • Administration interface and CLI for managing users.
  • Session based authentication with session theft protection support.
  • Strong cryptographic password hashing with support for migrating password hashes (including Invenio v1.x) to new stronger algorithms.
  • Session activity tracking allowing users to e.g. logout of all devices.
  • Server-side session management.
  • JSON Web Token encoding and decoding support useful for e.g. CSRF-protection in REST APIs.

Invenio-Accounts relies on the following community packages to do all the heavy-lifting:

Further documentation is available on https://invenio-accounts.readthedocs.io/

invenio-accounts's People

Contributors

alejandromumo avatar alizeepace avatar chriz-uniba avatar drjova avatar greut avatar inveniobot avatar ioannistsanaktsidis avatar jacquerie avatar javierdelgadofernandez avatar jeromecaffaro avatar jirikuncar avatar jmartinm avatar jrcastro2 avatar kaplun avatar kpsherva avatar lnielsen avatar ludmilamarian avatar manzikki avatar max-moser avatar mb-wali avatar mvidalgarcia avatar ntarocco avatar omelkonian avatar otron avatar samihiltunen avatar slint avatar tiborsimko avatar utnapischtim avatar wohthan avatar zzacharo avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

invenio-accounts's Issues

session backend needs to be configurable.

Set CONFIG parameter for session backend. Otherwise it tries to use localhost:6379 as a back end. In production we have nodes dedicated as a redis host so this needs to be a variable.

See
https://github.com/inveniosoftware/invenio-accounts/blob/master/invenio_accounts/ext.py#L67

We need something like.

r = redis.StrictRedis(host=config['SESSION_REDIS_HOST'], port=config['SESSION_REDIS_PORT'], db=config['SESSION_REDIS_DB'])

We already have CACHE_REDIS_HOST as a config param. If we could use this by default, that would be great. The only annoying thing is that the port and db have to be specified, so the host can't be the full connection string.

api: stabilise and document

  • check existing API functionality
  • add missing important API functionality
  • check API function signatures and parameters
  • enhance API docstrings (param, returns, raises, versionadded)
  • plug API functions to existing docs

cli: change structure

Reiteration on #29

CLI conventions:

  • Max 2 levels
  • Command naming:
    • no compound names (e.g. usercreate)

Open questions:

  • Plural vs singular?
$ inveniomanages user create
$ inveniomanages role add

vs.

$ inveniomanages users create
$ inveniomanages roles add

global: upgrade to flask-security 1.7.5

Upgrade to Flask-Security 1.7.5 which was just released.

  • unpin Flask-Login from 0.2.11 to 0.x
  • current_user.is_authenticated() -> current_user.is_authenticated
  • Check all other invenio packages the the same problems.

global: load ACCOUNTS_SESSION_REDIS_URL from enviroment

Issue: On mac when redis is run in a docker machine the host ip is the one of the virtual box vm, not localhost. The default value of ACCOUNTS_SESSION_REDIS_URL is hard coded (

ACCOUNTS_SESSION_REDIS_URL = 'redis://localhost:6379/0'
). Thus docker cannot be used when running tests on a mac.

Solution: load ACCOUNTS_SESSION_REDIS_URL from environment if it is set. This solution is already used in invenio-search (https://github.com/inveniosoftware/invenio-search/blob/f19a3c743ad9d578d0840a416e7dd76e6fffca06/invenio_search/config.py#L58)

tests: repeated arg-less calls to `create_test_user` throw error

Calling testutils.py:create_test_user without any arguments twice cause an error to be thrown as it attempts to create a second user with the default email address.

Fix: generate random email address when none is given instead of using a static default.

global: support for legacy invenio password hashes

Error on index creation for userEXT table

Starting inveniomanage database create, I receive this error on id_user index:

>>> problem with creating userEXT#############################      ] 85% 0:00:00.086719 
--------------------------------------------------------------------------------
ERROR in database [/home/vagrant/.virtualenvs/invenio2/src/invenio/invenio/base/scripts/database.py:195]:
userEXT
--------------------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/vagrant/.virtualenvs/invenio2/src/invenio/invenio/base/scripts/database.py", line 191, in _creator
    creator(table)
  File "/home/vagrant/.virtualenvs/invenio2/src/invenio/invenio/base/scripts/database.py", line 204, in <lambda>
    lambda table: table.create(bind=db.engine))
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 725, in create
    checkfirst=checkfirst)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1856, in _run_visitor
    conn._run_visitor(visitorcallable, element, **kwargs)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1481, in _run_visitor
    **kwargs).traverse_single(element)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py", line 121, in traverse_single
    return meth(obj, **kw)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/sql/ddl.py", line 769, in visit_table
    self.traverse_single(index)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py", line 121, in traverse_single
    return meth(obj, **kw)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/sql/ddl.py", line 788, in visit_index
    self.connection.execute(CreateIndex(index))
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 914, in execute
    return meth(self, multiparams, params)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/sql/ddl.py", line 68, in _execute_on_connection
    return connection._execute_ddl(self, multiparams, params)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 968, in _execute_ddl
    compiled
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1146, in _execute_context
    context)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1341, in _handle_dbapi_exception
    exc_info
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 199, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1139, in _execute_context
    context)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 450, in do_execute
    cursor.execute(statement, parameters)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
    self.errorhandler(self, exc, value)
  File "/home/vagrant/.virtualenvs/invenio2/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
OperationalError: (_mysql_exceptions.OperationalError) (1280, "Incorrect index name 'id_user'") [SQL: u'CREATE UNIQUE INDEX id_user ON `userEXT` (id_user, method)']

Flask-Login>0.3 is_authenticated and is_anonymous becoming properties

Flask-Login changed is_authenticated() and is_anonymous() to properties in >0.3 versions. This will causes issues as the development version of Flask-Security pin Flask-Login to >0.3 version. For now, I've commented out Flask-Security from the development requirements. When the new version is released, we should pin the version to the new one and amend calls to is_authenticated and is_anonymous.

Related:

global: different flask security blueprint handling for API and UI

Currently the flask-security blueprints are loaded in both API and UI.
After some discussions with @lnielsen and @jirikuncar there were two solutions:
1/ Load the blueprint only in one of the applications.
2/ Load them in both application but make the default content-type different: json for API and HTML for UI.

For the time being we chose to go with option 2. This remains as TODO but does not have a high priority right now.

sessions: clean session sid on db when logout

Problem

It looks like that when you click on "logout" button the current user session is cleaned on Redis but not on database.

Solution

A solution could be find the right hook and call the delete_session().

views: add a REST API

As for the other modules a REST API will be needed here.

The main features would be:

  • searching/listing users
  • getting a user's information
  • updating a user's information
  • searching roles
  • creating roles
  • assigning roles to users or unassigning them.

It would also need a shortcut URI for the currently authenticated user.

There is however one question. Do we want this in invenio-accounts or do we create an API for both invenio-accounts and invenio-userprofiles at the same time? Not being able to search users by name would be a strange limitation.

@inveniosoftware/triagers

examples: RuntimeError: Flask application is already initialized

Running example app leads to:

flask -a app.py npm
app
/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py:800: UserWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True to suppress this warning.
  warnings.warn('SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True to suppress this warning.')
Traceback (most recent call last):
  File "/home/simko/.virtualenvs/invenio-accounts/bin/flask", line 11, in <module>
    sys.exit(main())
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/flask_cli/cli.py", line 495, in main
    cli.main(args=args, prog_name=name)
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/flask_cli/cli.py", line 343, in main
    return AppGroup.main(self, *args, **kwargs)
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/click/core.py", line 1055, in invoke
    cmd_name, cmd, args = self.resolve_command(ctx, args)
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/click/core.py", line 1094, in resolve_command
    cmd = self.get_command(ctx, cmd_name)
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/flask_cli/cli.py", line 316, in get_command
    rv = info.load_app().cli.get_command(ctx, name)
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/flask_cli/cli.py", line 191, in load_app
    rv = locate_app(self.app_import_path)
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/flask_cli/cli.py", line 89, in locate_app
    __import__(module)
  File "/home/simko/private/src/invenio-accounts/examples/app.py", line 135, in <module>
    InvenioTheme(app)
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/invenio_theme/ext.py", line 48, in __init__
    self.init_app(app, **kwargs)
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/invenio_theme/ext.py", line 55, in init_app
    self.menu_ext.init_app(app)
  File "/home/simko/.virtualenvs/invenio-accounts/local/lib/python2.7/site-packages/flask_menu/__init__.py", line 50, in init_app
    raise RuntimeError("Flask application is already initialized.")
RuntimeError: Flask application is already initialized.

setup: wheel not universal

The wheel built on Python 2.7 and uploaded on PyPI cannot be installed on Python 3 due to dependency on ipaddr (which in setup.py is only added in 2.7, but the wheel doesn't care)

cli: change to flat structure

Change CLI to flat structure:

from:

inveniomanage accounts users create
inveniomanage accounts users activate
inveniomanage accounts users deactivate
inveniomanage accounts roles add
inveniomanage accounts roles create
inveniomanage accounts roles remove

to

inveniomanage accounts createuser
inveniomanage accounts activateuser
inveniomanage accounts deactivateuser
inveniomanage accounts addrole
inveniomanage accounts createrole
inveniomanage accounts removerole

admin: admin interface for accounts

Once Invenio-Admin is integrated, add admin interface for managing users.

  1. Support for batch actions: active/deactivate user.
  2. User deactivation must ensure that user get's logged out immediately (i.e. kill session).
  3. By default sort by last_login
  4. Add filters to quickly filter list of users.

Open Question:

  • Will we support the old "Become user" feature? (ping @tiborsimko @jirikuncar) IMHO it's not good that an admin can impersonate a user.

admin: user creation doesn't work

If you use different way to create user.

With the /signup/ url, or the admin interface, or the cli. It seems they all ignore each others.

For example if I create 4 users with admin it will allocate 1-4 for ids then if I use the CLI I will have to crash it four times to make it create a user with the id 5.

Way to create, ID
Admin UI, 1
Admin UI, 2
Admin UI, 3
CLI, 1 -> crash
CLI, 2 -> crash
CLI, 3 -> crash
CLI, 4

global: session activity feature

We need the ability to destroy a valid session without the user making a request (this is useful to e.g. ban users immediately #44). Also, this can be used to allow users to see a list of their active sessions (e.g. from multiple devices, and logout a specific device). This is only really possible when sessions are stored server-side (i.e #51). We also need to associate a session (for a logged in user) with a user id (Flask-Session/KVSession use uuids as session ids).

  • Model: user, session, timestamp (UTC), country, browser, os (deduced from ip and user agent)
  • Connect to Flask-Login's user_logged_in signal to store the session activity when a user logins.
  • Celery cron task to clean up session activity table.
  • Account settings item "Security", with a panel that list Sessions (see e.g. DropBox as an example). Allow a user to remove a session plus "Log me out of all devices". I would also include "Change password" on the same page.
  • Model: +country, browser, browser version, os (deduced from ip and user agent)
  • Configuration: Allow 1) tracking only user/session/timestamp and not country, browser and os 2) completely switching off the session activity feature.
  • Admin interface (needs very restrictive permissions). Browse, remove, filter by user. (related to #33)

mail: Celery is unable to serialize the Message object

EncodeError: can't serialize <flask_mail.Message object at 0x10cb0f310>

File "/Users/eamonnmaguire/.virtualenvs/hepdata3/src/invenio-accounts/invenio_accounts/ext.py", line 63, in delay_security_email
    send_security_email.delay(msg)
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/celery/app/task.py", line 453, in delay
    return self.apply_async(args, kwargs)
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/celery/app/task.py", line 560, in apply_async
    **dict(self._get_exec_options(), **options)
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/celery/app/base.py", line 354, in send_task
    reply_to=reply_to or self.oid, **options
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/celery/app/amqp.py", line 305, in publish_task
    **kwargs
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/kombu/messaging.py", line 165, in publish
    compression, headers)
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/kombu/messaging.py", line 241, in _prepare
    body) = dumps(body, serializer=serializer)
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/kombu/serialization.py", line 164, in dumps
    payload = encoder(data)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/contextlib.py", line 35, in __exit__
    self.gen.throw(type, value, traceback)
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/kombu/serialization.py", line 59, in _reraise_errors
    reraise(wrapper, wrapper(exc), sys.exc_info()[2])
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/kombu/serialization.py", line 55, in _reraise_errors
    yield
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/kombu/serialization.py", line 164, in dumps
    payload = encoder(data)
  File "/Users/eamonnmaguire/.virtualenvs/hepdata3/lib/python2.7/site-packages/msgpack/__init__.py", line 47, in packb
    return Packer(**kwargs).pack(o)
  File "msgpack/_packer.pyx", line 223, in msgpack._packer.Packer.pack (msgpack/_packer.cpp:223)
  File "msgpack/_packer.pyx", line 225, in msgpack._packer.Packer.pack (msgpack/_packer.cpp:225)
  File "msgpack/_packer.pyx", line 184, in msgpack._packer.Packer._pack (msgpack/_packer.cpp:184)
  File "msgpack/_packer.pyx", line 213, in msgpack._packer.Packer._pack (msgpack/_packer.cpp:213)
  File "msgpack/_packer.pyx", line 220, in msgpack._packer.Packer._pack (msgpack/_packer.cpp:220)
EncodeError: can't serialize <flask_mail.Message object at 0x10cb0f310>

tests: add tests for user deactivation

Need test(s) that verify that a user, once deactivated, immediately has their session(s) invalidated and are unable to log in.

Test description:

  1. Create user X
  2. log in as X
  3. deactivate user X
  4. try to do things as user X. Result should be the same as trying to do so as any anonymous/unauthenticated user

accounts: delete account feature

@lnielsen commented on Mon Aug 04 2014

Goal:
Allow users to delete their account via the account settings.

Additional info
The account deletion facility should check any attached baskets, any predefined alerts, any submitted records, messages etc.

Overlays must be able to hook into the deletion process, to do custom processing via e.g. pre/post delete signals.

Open questions:
Do we delete the account or simply mark it as deleted for record keeping?

See also issue #1973


@jirikuncar commented on Mon Aug 04 2014

Overlays must be able to hook into the deletion process, to do custom processing via e.g. pre/post delete signals.

I think we can rely on SQLAlchemy signals for User model.


@tiborsimko commented on Wed Aug 13 2014

Do we delete the account or simply mark it as deleted for record keeping?

I think the account inactivation and marking-as-deleted would be good for record keeping. We do it already for records in the same way. (via 980 $c DELETED)


@aw-bib commented on Wed Aug 13 2014

I think one point needs to be addressed here which shares probably some parts with #2022.

Today, the more common case with email addresses in research institutions and universities is, that the email address as such get's recycled. So you may have a naming scheme like [email protected] (say [email protected]). Now if you have only one [email protected] he gets this address. Now, [email protected] may leave the company. Later a another one joins in some John Doe, and he gets [email protected]...

To make the long story short: IRL email addresses do not make a good primary key anymore :(


@tiborsimko commented on Wed Aug 13 2014

@aw-bib Yes, e.g. Yahoo email addresses may also get recycled now... http://yahoo.tumblr.com/post/52805929240/yourname-yahoo-com-can-be-yours

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.