NewAuth

NewAuth is a full featured authentication system for your Eve Online alliance or corporation. It brings out of the box support for multiple api keys per user, user groups with applications and invitations, and pings.

It is easily extensible and we’re very much welcoming of new features!

Installation

Dependencies

You will need, of course, Python (tested on 2.7, might need some fixes for Python 3.x), a running SQL server (NewAuth has been tested with SQLite and PostgreSQL but it should work with MySQL) and a Redis server. Create a new SQL database and a user for NewAuth and keep its login details close. You might also need some extra packages to compile python dependencies, most notably libxml2 and database driver specific libraries.

Downloading

Here’s the basic commands to download and install NewAuth:

$ git clone https://github.com/J4LP/newauth.git
$ cd newauth
$ virtualenv .
$ source bin/activate
$ pip install -r requirements.txt

Configuration

NewAuth configuration is read from the newauth/settings.py file. Refer to Settings for documentation and come back here!

Corporation API Key

In order to pick up your corporation/alliance, you will need to generate a corporation or alliance key with the Contact and Standings permissions. Please click this link to open CCP’s API page to create one.

Initial launch

Once NewAuth is configured, you will need to migrate the database:

$ python manage.py db migrate
$ python manage.py db upgrade

You should then be able to start NewAuth with its development server:

$ python run.py
 * Running on http://0.0.0.0:5002/

Once NewAuth is confirmed to be working, it’s time to import your corporation’s contacts:

$ python manage.py update_contacts

And there you have it! NewAuth is now running on your computer. You are now able to create an account and login with it! Once your account created, make yourself admin with:

$ python manage.py make_admin $YOUR_USER_ID

Thanks you for using NewAuth!

Background Tasks

NewAuth is using Celery to delegate heavy tasks to the background and cronjobs. Please refer to Celery’s documentation for more configuration options. You will need to launch it alongside newauth with:

celery -A manage.celery worker -Q newauth,celery -B

This command should be ran in the root directory of NewAuth.

Settings

Settings in NewAuth works by subclassing BaseConfig with “DevConfig” or “ProdConfig” or any other prefix. The prefix will be read from NEWAUTH_ENV and default to “Dev”.

class newauth.settings_dist.BaseConfig[source]

File based configuration object.

SECRET_KEY

Secret key for securing cookies. Generate one with openssl rand –base64 64

APP_DIR

Application absolute path

PROJECT_ROOT

Project root

DEBUG

Turn on debug mode by environment

SQLALCHEMY_DATABASE_URI

Default SQLAlchemy database

SQLALCHEMY_ECHO

Turn on debug mode for SQLAlchemy (prints out queries)

EVE

Eve related settings, see Eve Settings.

ADMIN_GROUP

The admin group

PING_GROUP

The ping group

PINGERS

Array of pings to load and use

PINGERS_SETTINGS

Runtime configuration for pingers

PLUGINS

Plugins list

Mail Settings

#: Mail settings for https://pythonhosted.org/flask-mail/
MAIL_SERVER = 'localhost'
MAIL_PORT = 25
MAIL_USE_TLS = False
MAIL_USE_SSL = False
MAIL_DEBUG = os.getenv('DEBUG', False)
MAIL_USERNAME = None
MAIL_PASSWORD = None
MAIL_DEFAULT_SENDER = None

Celery Settings

#: Celery Settings, more available http://celery.readthedocs.org/en/latest/configuration.html
CELERY_BROKER_URL = 'redis://localhost:6379'
CELERY_RESULT_BACKEND = 'db+sqlite:///celery.sqlite'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'

Eve Settings

The Eve settings configure your NewAuth instance with your corporation/alliance identity and needs. For NewAuth to work, it needs one or several corporation api keys that will allow it to query its contacts to compute a list of allowable characters. See Update Contacts for more informations. Here’s an example for the I Whip My Slaves Back and Forth alliance:

EVE = {
    'auth_name': 'J4LP',
    'requirements': {
        # Members need a mask of 65544538 and a key that does not expires
        # Allies need a mask of 50331656 and a key that can expires
        'internal': {'mask': 65544538, 'expires': False},
        'ally': {'mask': 50331656, 'expires': True}
    },
    'alliances': [99002172], # This is J4LP's alliance id
    'corporations': [],
    'keys': [(0, 'sekret')]
}

The alliances and corporations lists are a list of entity ID to add by default when updating the contacts. Here’s an example

Manage commands

NewAuth ships with some CLI commands to help make your life easier.

Update Contacts

Usage:

$ python manage.py update_contacts

This method will fetch all contact lists of all the api keys given in Eve Settings in order to build a list of corporations and alliances to allow or deny access and registration to NewAuth.

Make Admin

Description
Make a user join the group newauth.settings_dist.BaseConfig.ADMIN_GROUP and create the group if necessary.
Usage
$ python manage.py make_admin $USER_ID

Make Ping

Description
Make a user join the group newauth.settings_dist.BaseConfig.PING_GROUP and create the group if necessary.
Usage
$ python manage.py make_ping $USER_ID

Update Users

Description
Update one user or all users with Celery
Usage
$ python manage.py update_users [user_id]

Models

class newauth.models.User(**kwargs)

User model

update_password(new_password)

Hash a new password to bcrypt.

Parameters:new_password (str) – The new password
check_password(password)

Check if given password checks out. If the password is in a LDAP format, it will convert it to bcrypt.

Parameters:password (str) – The password to compare
Returns:bool – If the password checks out or not
update_status()

Loop around characters and keys to determinate best status.

Ineligible < Ally < Internal

:returns CharacterStatus – The status that was computed

update_keys()

Update all API Keys and Characters associated.

Plugins

NewAuth allows the loading of foreign plugins to extend its features. These plugins are loaded at the end of the creation of the application after models, routes and other settings have been loaded.

Plugins follow the architecture of a Flask extension.

Example plugin

This is an example of a NewAuth plugin that hooks into different signals and add a route to the admin.

class ExamplePlugin(object):
    """Example plugin for NewAuth"""

    def __init__(self, app=None):
        if app:
            self.init_app(app)

    def init_app(self, app):
        self.app = app

        self.app.logger.debug("ExamplePlugin enabled.")

        # Registering events
        User.login_success.connect_via(app)(self.login_success)
        User.login_fail.connect_via(app)(self.login_fail)

        # Registering template hooks
        if not hasattr(app, 'admin_user_hooks'):
            app.admin_user_hooks = [self.admin_user_hook]
        else:
            app.admin_user_hooks.append(self.admin_user_hook)
        if not hasattr(app, 'dashboard_hooks'):
            app.dashboard_hooks = [self.dashboard_hook]
        else:
            app.dashboard_hooks.append(self.dashboard_hook)

        # Registering routes
        app.add_url_rule('/admin/example', 'example_route', self.admin_example_route)

        # Registering to navbar
        app.navbar['admin'].append(('fa-info', 'Example Route', '/admin/example'))

    def login_success(self, app, user):
        current_app.logging.debug('Login success')

    def login_fail(self, app, user):
        current_app.logging.debug('Login fail')

    def admin_user_hook(self, user):
        return 'This will be displayed on the user\'s admin profile'

    def dashboard_hook(self, user):
        return 'This is a dashboard widget'

    def admin_example_route(self):
        return 'This is an extra route'

LDAP Plugin

NewAuth ships with a LDAP plugin that allow the application to save its user data to a LDAP directory.

Configuration

SYNC_LDAP_HOST = '127.0.0.1'
SYNC_LDAP_ADMIN_USER = 'cn=admin,dc=example,dc=org'
SYNC_LDAP_ADMIN_PASS = 'admin'
SYNC_LDAP_BASEDN = 'dc=example,dc=org'
SYNC_LDAP_MEMBERDN = 'ou=People,dc=example,dc=org'

Management commands

python manage.py ldap import_users [--user_id $USER_ID]

This command will import all users in SYNC_LDAP_MEMBERDN. We recommend making a backup of your LDAP server before though. If you include add –user_id it will only import this user.

Tasks Dashboard

NewAuth is using Celery to leverage some heavy tasks to the background, by default, no dashboard is available because it requires an external dependency. If you so wish, you can get a basic dashboard available to your admin and a better more functional one for your IT team. More information about Flower can be found here.

Requirements

This plugin requires you to install Flower, a Celery dashboard providing a REST API.

pip install flower

We also need to run Flower alongside NewAuth and Celery with:

celery -A newauth.tasks flower --address=127.0.0.1 --port=5555

Configuration

To enable Tasks Dashboard, add newauth.plugins.tasks_dashboard.TasksDashboard to the PLUGINS setting.

This plugin only requires one setting:

CELERY_FLOWER_URL = 'http://127.0.0.1:5555/  # Note the trailing slash

Pings

A Ping is a message sent through NewAuth to a group of people registered. It can be sent over XMPP or Pushbullet for example.

XMPP Pinger

NewAuth can send its pings to a Jabber server. To enable this pinger, add newauth.plugins.ping.xmpp.XMPPPinger to the PINGERS setting.

Pushbullet Pinger

NewAuth can send its pings to Pushbullet, a notification web service that has applications for Chrome, Android, iOS and more.

To enable this pinger, add newauth.plugins.ping.pushbullet.PushbulletPinger to the PINGERS setting.

Create your own Pinger

You would need to subclass and implement the newauth.plugins.ping.Pinger.

class newauth.plugins.ping.Pinger(app=None)[source]

Pinger base class to create a new pinger. Works like a plugin.

description = ''

Description to be displayed, supports Markdown.

disable(user, configuration)[source]

Called when disabling the pinger.

You can do additional steps before NewAuth disable this pinger for the user.

Feel free to flash messages through Flask’s flash.

configuration will be serialized, saved and tied to the user.

Returns:Return the configuration if successful or False
display_name = ''

Pinger name to be displayed.

enable(user, configuration)[source]

Called when enabling the pinger after the form has been validated.

Feel free to flash messages through Flask’s flash.

configuration will be serialized, saved and tied to the user.

Returns:Return True, False, or a dict for more action. See pingers for more info.
enabled(user)[source]

Test if the user has the pinger enabled and configured.

Return type:boolean
get_form(user_config)[source]

Return a WTForm to display on the pinger settings page or None if no configuration needed. :param user_config: :return:

immutable = False

Can this pinger be disabled ?

init_app(app)[source]

Called when the application starts, use to check for settings or register signals :param app: :return:

name = ''

Pinger name used for configuration storage and in other various places.

save_configuration(user, configuration, form)[source]

Called when saving the plugin settings and the form has been validated.

Feel free to flash messages through Flask’s flash.

configuration will be serialized, saved and tied to the user.

Returns:Return the configuration if successful or False
send_ping(ping)[source]

Send the ping to the users.

Indices and tables