Added web interface for organizations.

It looks like crap, but it allows you to edit the details and the members.
This commit is contained in:
2017-08-23 15:38:56 +02:00
parent 64eab850c5
commit e9cb235640
6 changed files with 611 additions and 1 deletions

View File

@@ -313,6 +313,20 @@ class OrgManager:
'$pull': {'unknown_members': member_email}
})
def org_members(self, member_sting_ids: typing.Iterable[str]) -> typing.List[dict]:
"""Returns the user documents of the organization members.
This is a workaround to provide membership information for
organizations without giving 'mortal' users access to /api/users.
"""
from pillar.api.utils import str2id
member_ids = [str2id(uid) for uid in member_sting_ids]
users_coll = current_app.db('users')
users = users_coll.find({'_id': {'$in': member_ids}},
projection={'_id': 1, 'full_name': 1, 'email': 1})
return list(users)
def setup_app(app):
from . import patch, hooks

View File

@@ -1,5 +1,5 @@
def setup_app(app):
from . import main, users, projects, nodes, notifications, redirects, subquery
from . import main, users, projects, nodes, notifications, organizations, redirects, subquery
main.setup_app(app, url_prefix=None)
users.setup_app(app, url_prefix=None)
redirects.setup_app(app, url_prefix='/r')
@@ -7,3 +7,4 @@ def setup_app(app):
nodes.setup_app(app, url_prefix='/nodes')
notifications.setup_app(app, url_prefix='/notifications')
subquery.setup_app(app)
organizations.setup_app(app, url_prefix='/orgs')

View File

@@ -0,0 +1,5 @@
from .routes import blueprint
def setup_app(app, url_prefix=None):
app.register_blueprint(blueprint, url_prefix=url_prefix)

View File

@@ -0,0 +1,83 @@
import logging
import attr
from flask import Blueprint, render_template, request, jsonify
import flask_wtf.csrf
import werkzeug.exceptions as wz_exceptions
from pillarsdk import User
import pillar.flask_extra
from pillar import current_app
from pillar.api.utils import authorization, str2id, gravatar
from pillar.web.system_util import pillar_api
from pillar.api.utils.authentication import current_user
from pillarsdk import Organization
log = logging.getLogger(__name__)
blueprint = Blueprint('pillar.web.organizations', __name__, url_prefix='/organizations')
@blueprint.route('/', endpoint='index')
def index(organization_id: str = None):
api = pillar_api()
organizations = Organization.all(api=api)
if not organization_id and organizations['_items']:
organization_id = organizations['_items'][0]._id
can_create_organization = current_user().has_cap('create-organization')
return render_template('organizations/index.html',
can_create_organization=can_create_organization,
organizations=organizations,
open_organization_id=organization_id)
@blueprint.route('/<organization_id>')
@pillar.flask_extra.vary_xhr()
def view_embed(organization_id: str):
if not request.is_xhr:
return index(organization_id)
api = pillar_api()
organization: Organization = Organization.find(organization_id, api=api)
om = current_app.org_manager
organization_oid = str2id(organization_id)
members = om.org_members(organization.members)
for member in members:
member['avatar'] = gravatar(member.get('email'))
member['_id'] = str(member['_id'])
can_edit = om.user_is_admin(organization_oid)
csrf = flask_wtf.csrf.generate_csrf()
return render_template('organizations/view_embed.html',
organization=organization,
members=members,
can_edit=can_edit,
seats_used=len(members) + len(organization.unknown_members),
csrf=csrf)
@blueprint.route('/create-new', methods=['POST'])
@authorization.require_login(require_cap='create-organization')
def create_new():
"""Creates a new Organization, owned by the currently logged-in user."""
user_id = current_user().user_id
log.info('Creating new organization for user %s', user_id)
name = request.form['name']
seat_count = int(request.form['seat_count'], 10)
org_doc = current_app.org_manager.create_new_org(name, user_id, seat_count)
return jsonify({'_id': org_doc['_id']}), 201