diff --git a/.gitignore b/.gitignore index 8559446267..3e9ecd618a 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,4 @@ webui/app/b2share-bundle.js.map webui/app/lib/ webui/app/vendors/ webui/src/version.js +webui/package-lock.json \ No newline at end of file diff --git a/b2share/modules/communities/api.py b/b2share/modules/communities/api.py index aced973367..e4d6f5e8d2 100644 --- a/b2share/modules/communities/api.py +++ b/b2share/modules/communities/api.py @@ -32,6 +32,7 @@ from invenio_db import db from jsonpatch import apply_patch from sqlalchemy.orm.exc import NoResultFound +from sqlalchemy.exc import StatementError from invenio_accounts.models import Role from .errors import CommunityDeletedError, CommunityDoesNotExistError, \ @@ -89,7 +90,7 @@ def get(cls, id=None, name=None, with_deleted=False): if metadata.deleted and not with_deleted: raise CommunityDeletedError(id) return cls(metadata) - except NoResultFound as e: + except (NoResultFound, StatementError) as e: raise CommunityDoesNotExistError(id) from e @classmethod diff --git a/b2share/modules/communities/serializers.py b/b2share/modules/communities/serializers.py index c64ca9a4ea..963752a228 100644 --- a/b2share/modules/communities/serializers.py +++ b/b2share/modules/communities/serializers.py @@ -25,6 +25,10 @@ from flask import jsonify, url_for +from b2share.modules.schemas.api import CommunitySchema +from b2share.modules.schemas.serializers import block_schema_version_self_link, community_schema_json_schema_link +import json + def community_self_link(community, **kwargs): """Create self link to a given community. @@ -44,6 +48,9 @@ def community_self_link(community, **kwargs): def community_to_dict(community): + community_schema = CommunitySchema.get_community_schema(community.id) + community_schema_dict = json.loads(community_schema.community_schema) + props = community_schema_dict['properties'] return dict( id=community.id, name=community.name, @@ -54,7 +61,13 @@ def community_to_dict(community): publication_workflow=community.publication_workflow, restricted_submission=community.restricted_submission, links=dict( - self=community_self_link(community, _external=True) + self=community_self_link(community, _external=True), + schema=community_schema_json_schema_link(community_schema, _external=True), + block_schema=next(iter(props.values()))['$ref'] if props else "" + ), + schema=dict( + version=community_schema.version, + block_schema_id=next(iter(props)) if props else "" ), roles=dict( admin=dict(id=community.admin_role.id, diff --git a/b2share/modules/communities/views.py b/b2share/modules/communities/views.py index 75af26c77d..6e4f43ec69 100644 --- a/b2share/modules/communities/views.py +++ b/b2share/modules/communities/views.py @@ -45,6 +45,7 @@ update_permission_factory from .serializers import community_to_json_serializer, \ search_to_json_serializer, community_self_link +from b2share.utils import is_valid_uuid current_communities = LocalProxy( lambda: current_app.extensions['b2share-communities']) @@ -61,7 +62,10 @@ def pass_community(f): @wraps(f) def inner(self, community_id, *args, **kwargs): try: - community = Community.get(id=community_id) + if is_valid_uuid(community_id): + community = Community.get(id=community_id) + else: + community = Community.get(name=community_id) except (CommunityDoesNotExistError): abort(404) except (CommunityDeletedError): diff --git a/b2share/modules/schemas/api.py b/b2share/modules/schemas/api.py index c329439251..b95778c5db 100644 --- a/b2share/modules/schemas/api.py +++ b/b2share/modules/schemas/api.py @@ -495,7 +495,7 @@ def get_community_schema(cls, community_id, version=None): """Retrieve the requested version of a community schema. Args: - schema_id (ID): schema id. + community_id (ID): community id. version (int): version of the schema to retrieve. If None, the last version will be retrieved. diff --git a/b2share/modules/schemas/cli.py b/b2share/modules/schemas/cli.py index 52f5959d75..ecf6bc8fe6 100644 --- a/b2share/modules/schemas/cli.py +++ b/b2share/modules/schemas/cli.py @@ -112,8 +112,7 @@ def block_schema_list(verbose, community): except BlockSchemaDoesNotExistError: raise click.ClickException("""No block schemas found, community parameter was: %s""" % community) - click.secho("""BLOCK SCHEMA - ID\t\t\t\tNAME\t\tMAINTAINER\tDEPRECATED\t#VERSIONS""") + click.secho("""BLOCK SCHEMA ID\t\t\t\tNAME\t\tMAINTAINER\tDEPRECATED\t#VERSIONS""") for bs in block_schemas: bs_comm = Community.get(id=bs.community) click.secho("%s\t%s\t%s\t%s\t\t%d" % ( diff --git a/b2share/utils.py b/b2share/utils.py index c87a79f881..522806fa06 100644 --- a/b2share/utils.py +++ b/b2share/utils.py @@ -25,6 +25,7 @@ from sqlalchemy import UniqueConstraint, PrimaryKeyConstraint from invenio_db import db +import uuid def add_to_db(instance, skip_if_exists=False, **fields): @@ -69,3 +70,10 @@ def add_to_db(instance, skip_if_exists=False, **fields): # Add the row if it does not already exist db.session.add(instance) return instance + +def is_valid_uuid(val): + try: + uuid.UUID(str(val)) + return True + except ValueError: + return False diff --git a/webui/src/components/community_admin.jsx b/webui/src/components/community_admin.jsx index 7fd8a7a492..f38b83e161 100644 --- a/webui/src/components/community_admin.jsx +++ b/webui/src/components/community_admin.jsx @@ -3,6 +3,7 @@ import { Link } from 'react-router'; import { DropdownList, Multiselect } from 'react-widgets'; import { fromJS, OrderedMap, Map } from 'immutable'; import { serverCache, notifications , browser , Error, loginURL} from '../data/server'; +import { isCommunityAdmin } from './record.jsx'; import { LoginOrRegister } from './user.jsx'; import { Wait, Err } from './waiting.jsx'; @@ -37,8 +38,7 @@ export const CommunityAdmin = React.createClass({ render() { const current_user = serverCache.getUser(); - const communityName = this.props.params.id; - const community = serverCache.getCommunity(communityName); + const community = serverCache.getCommunity(this.props.params.id); if (!current_user || !current_user.get || !current_user.get('name')) { return this.renderNoUser(); @@ -50,6 +50,12 @@ export const CommunityAdmin = React.createClass({ return ; } + if (!isCommunityAdmin(community.get('id'))) { + return ; + } + + const communityName = community.get('name'); + var roles = {}; community.get('roles').forEach( role =>{ roles[role.get('name').replace(new RegExp("^com:[^:]*:"), "")] = role.get('id'); @@ -110,12 +116,12 @@ export const UsersTable = React.createClass({ return (
-
+

Email Address

Role

Edit

-
{rows}
+
{rows}
); } @@ -138,7 +144,7 @@ export const UserRow = React.createClass({ defRoleName={this.props.userRoleName} defRoleID={this.props.userRoleID} userEmail={this.props.userEmail} - userID={this.props.userID}/ >
+ userID={this.props.userID}/> ); diff --git a/webui/src/components/record.jsx b/webui/src/components/record.jsx index 6e1a5be79f..72d7ab3fce 100644 --- a/webui/src/components/record.jsx +++ b/webui/src/components/record.jsx @@ -120,11 +120,13 @@ const Record = React.createClass({ return !community ? false : (community instanceof Error) ? : ( -
-
-

{community.get('name')}

- -
+
+ +
+

{community.get('name')}

+ +
+
); } @@ -245,7 +247,7 @@ const Record = React.createClass({ ); }, - renderField(id, schema, value) { + renderField(id, schema, value, vtype=null) { function renderScalar(schema, value) { const type = schema.get('type'); if (type === 'string' && schema.get('format') === 'date-time') { @@ -258,13 +260,24 @@ const Record = React.createClass({