Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

views: access control #18

Merged
merged 3 commits into from
Jan 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2015 CERN.
# Copyright (C) 2015, 2016 CERN.
#
# Invenio is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
Expand Down Expand Up @@ -37,7 +37,7 @@ charset = utf-8
indent_size = 4
# isort plugin configuration
known_first_party = invenio_records_rest
known_third_party = invenio_records, invenio_rest
known_third_party = invenio_records, invenio_rest, invenio_pidstore
multi_line_output = 2
default_section = THIRDPARTY

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,6 @@ docs/_build/

# PyBuilder
target/

# Examples instance directories
examples/*_instance
58 changes: 44 additions & 14 deletions examples/app.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2015 CERN.
# Copyright (C) 2015, 2016 CERN.
#
# Invenio is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
Expand All @@ -25,19 +25,35 @@

"""Minimal Flask application example for development.

For this example the access control is disabled.

Run example development server:

.. code-block:: console

$ cd examples
$ flask -a app.py db init
$ flask -a app.py db create
$ flask -a app.py load_fixture
$ flask -a app.py --debug run
$ cd examples
$ flask -a app.py db init
$ flask -a app.py db create
$ flask -a app.py fixture records
$ flask -a app.py --debug run

Try to get some records:

.. code-block:: console

$ curl -XGET http://localhost:5000/records/1
$ curl -XGET http://localhost:5000/records/2
$ curl -XGET http://localhost:5000/records/3
$ curl -XGET http://localhost:5000/records/4
$ curl -XGET http://localhost:5000/records/5
$ curl -XGET http://localhost:5000/records/6
$ curl -XGET http://localhost:5000/records/7
"""

from __future__ import absolute_import, print_function

import os

from flask import Flask
from flask_celeryext import FlaskCeleryExt
from flask_cli import FlaskCLI
Expand All @@ -48,13 +64,25 @@

from invenio_records_rest import InvenioRecordsREST


# create application's instance directory. Needed for this example only.
current_dir = os.path.dirname(os.path.realpath(__file__))
instance_dir = os.path.join(current_dir, 'app_instance')
if not os.path.exists(instance_dir):
os.makedirs(instance_dir)

# Create Flask application
app = Flask(__name__)
app = Flask(__name__, instance_path=instance_dir)
app.config.update(
CELERY_ALWAYS_EAGER=True,
CELERY_CACHE_BACKEND="memory",
CELERY_CACHE_BACKEND='memory',
CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
CELERY_RESULT_BACKEND="cache",
CELERY_RESULT_BACKEND='cache',
# No permission checking
RECORDS_REST_DEFAULT_CREATE_PERMISSION_FACTORY=None,
RECORDS_REST_DEFAULT_READ_PERMISSION_FACTORY=None,
RECORDS_REST_DEFAULT_UPDATE_PERMISSION_FACTORY=None,
RECORDS_REST_DEFAULT_DELETE_PERMISSION_FACTORY=None,
)
FlaskCLI(app)
FlaskCeleryExt(app)
Expand All @@ -65,8 +93,13 @@
InvenioRecordsREST(app)


@app.cli.command()
def load_fixture():
@app.cli.group()
def fixtures():
"""Command for working with test data."""


@fixtures.command()
def records():
"""Load test data fixture."""
import uuid
from invenio_records.api import Record
Expand Down Expand Up @@ -111,6 +144,3 @@ def load_fixture():
# Record 7 - Unregistered PID
PersistentIdentifier.create(
'recid', '7', status=PIDStatus.RESERVED)

if __name__ == "__main__":
app.run()
65 changes: 61 additions & 4 deletions invenio_records_rest/ext.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2015 CERN.
# Copyright (C) 2015, 2016 CERN.
#
# Invenio is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
Expand All @@ -26,9 +26,66 @@

from __future__ import absolute_import, print_function

from werkzeug.utils import import_string, cached_property

from .views import create_blueprint


class _RecordRESTState(object):
"""Record REST state."""

def __init__(self, app):
"""Initialize state."""
self.app = app
self._read_permission_factory = None
self._create_permission_factory = None
self._update_permission_factory = None
self._delete_permission_factory = None

@cached_property
def read_permission_factory(self):
"""Load default read permission factory."""
if self._read_permission_factory is None:
imp = self.app.config[
'RECORDS_REST_DEFAULT_READ_PERMISSION_FACTORY'
]
self._read_permission_factory = import_string(imp) if imp else None
return self._read_permission_factory

@cached_property
def create_permission_factory(self):
"""Load default create permission factory."""
if self._create_permission_factory is None:
imp = self.app.config[
'RECORDS_REST_DEFAULT_CREATE_PERMISSION_FACTORY'
]
self._create_permission_factory = import_string(imp) \
if imp else None
return self._create_permission_factory

@cached_property
def update_permission_factory(self):
"""Load default update permission factory."""
if self._update_permission_factory is None:
imp = self.app.config[
'RECORDS_REST_DEFAULT_UPDATE_PERMISSION_FACTORY'
]
self._update_permission_factory = import_string(imp) \
if imp else None
return self._update_permission_factory

@cached_property
def delete_permission_factory(self):
"""Load default delete permission factory."""
if self._delete_permission_factory is None:
imp = self.app.config[
'RECORDS_REST_DEFAULT_DELETE_PERMISSION_FACTORY'
]
self._delete_permission_factory = import_string(imp) \
if imp else None
return self._delete_permission_factory


class InvenioRecordsREST(object):
"""Invenio-Records-REST extension."""

Expand All @@ -42,15 +99,15 @@ def init_app(self, app):
self.init_config(app)
# Register records API blueprints
app.register_blueprint(
create_blueprint(app.config["RECORDS_REST_ENDPOINTS"])
create_blueprint(app.config['RECORDS_REST_ENDPOINTS'])
)
app.extensions['invenio-records-rest'] = self
app.extensions['invenio-records-rest'] = _RecordRESTState(app)

def init_config(self, app):
"""Initialize configuration."""
# Set up API endpoints for records.
app.config.setdefault(
"RECORDS_REST_ENDPOINTS",
'RECORDS_REST_ENDPOINTS',
dict(
recid=dict(
pid_type='recid',
Expand Down
4 changes: 2 additions & 2 deletions invenio_records_rest/serializers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2015 CERN.
# Copyright (C) 2015, 2016 CERN.
#
# Invenio is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
Expand Down Expand Up @@ -39,7 +39,7 @@ def record_self_link(pid, record, **kwargs):
:Returns Type: str
"""
return url_for(
"invenio_records_rest.{0}_item".format(pid.pid_type),
'invenio_records_rest.{0}_item'.format(pid.pid_type),
pid_value=pid.pid_value, **kwargs)


Expand Down
4 changes: 2 additions & 2 deletions invenio_records_rest/version.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2015 CERN.
# Copyright (C) 2015, 2016 CERN.
#
# Invenio is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
Expand Down Expand Up @@ -30,4 +30,4 @@

from __future__ import absolute_import, print_function

__version__ = "1.0.0a4.dev20150000"
__version__ = '1.0.0a4.dev20150000'
Loading