Example #1
0
def create_security_blueprint(state, import_name):
    from udata.i18n import I18nBlueprint
    # from flask.ext.security.utils import slash_url_suffix

    """
    Creates the security extension blueprint
    This creates an I18nBlueprint to use as a base.
    """

    bp = I18nBlueprint(state.blueprint_name, import_name,
                       url_prefix=state.url_prefix,
                       subdomain=state.subdomain,
                       template_folder='templates')

    bp.route(state.logout_url, endpoint='logout')(logout)

    if state.passwordless:
        bp.route(state.login_url,
                 methods=['GET', 'POST'],
                 endpoint='login')(send_login)
        bp.route(
            state.login_url + slash_url_suffix(state.login_url, '<token>'),
            endpoint='token_login'
        )(token_login)
    else:
        bp.route(state.login_url,
                 methods=['GET', 'POST'],
                 endpoint='login')(login)

    if state.registerable:
        bp.route(state.register_url,
                 methods=['GET', 'POST'],
                 endpoint='register')(register)

    if state.recoverable:
        bp.route(state.reset_url,
                 methods=['GET', 'POST'],
                 endpoint='forgot_password')(forgot_password)
        bp.route(
            state.reset_url + slash_url_suffix(state.reset_url, '<token>'),
            methods=['GET', 'POST'],
            endpoint='reset_password'
        )(reset_password)

    if state.changeable:
        bp.route(state.change_url,
                 methods=['GET', 'POST'],
                 endpoint='change_password')(change_password)

    if state.confirmable:
        bp.route(state.confirm_url,
                 methods=['GET', 'POST'],
                 endpoint='send_confirmation')(send_confirmation)
        bp.route(
            state.confirm_url + slash_url_suffix(state.confirm_url, '<token>'),
            methods=['GET', 'POST'],
            endpoint='confirm_email'
        )(confirm_email)

    return bp
Example #2
0
    def test_i18n_alternate_links(self):
        test = I18nBlueprint('test', __name__)

        @test.route('/i18n/<key>/')
        def i18n(key):
            return render_template_string('{{ i18n_alternate_links() }}')

        self.app.register_blueprint(test)
        self.app.config['DEFAULT_LANGUAGE'] = 'en'
        self.app.config['LANGUAGES'] = {
            'en': 'English',
            'fr': 'Français',
            'de': 'German',
        }

        response = self.get(url_for('test.i18n', key='value', param='other'))
        self.assertEqual(
            response.data, ''.join([
                '<link rel="alternate" href="/fr/i18n/value/?param=other" hreflang="fr" />',
                '<link rel="alternate" href="/de/i18n/value/?param=other" hreflang="de" />',
            ]))
    def test_i18n_alternate_links(self, app, client):
        test = I18nBlueprint('test', __name__)

        @test.route('/i18n/<key>/')
        def i18n(key):
            return render_template_string('{{ i18n_alternate_links() }}')

        app.register_blueprint(test)
        app.config['DEFAULT_LANGUAGE'] = 'en'
        app.config['LANGUAGES'] = {
            'en': 'English',
            'fr': 'Français',
            'de': 'German',
        }

        response = client.get(url_for('test.i18n', key='value', param='other'))
        link = ('<link rel="alternate" '
                'href="/{lang}/i18n/value/?param=other" '
                'hreflang="{lang}" />')
        assert response.data.decode('utf8') == ''.join(
            [link.format(lang='fr'),
             link.format(lang='de')])
Example #4
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from flask import request

from udata import search, theme
from udata.models import Dataset, Organization, Reuse
from udata.utils import multi_to_dict
from udata.features.territories import check_for_territories
from udata.i18n import I18nBlueprint

blueprint = I18nBlueprint('search', __name__)

# Maps template variables names to model types
MAPPING = {
    'datasets': Dataset,
    'reuses': Reuse,
    'organizations': Organization,
}


@blueprint.route('/search/', endpoint='index')
def render_search():
    params = multi_to_dict(request.args)
    params['facets'] = True
    # We only fetch relevant data for the given filter.
    if 'tag' in params:
        types = ['datasets', 'reuses']
    elif 'badge' in params:
        types = ['datasets', 'organizations']
    else:
Example #5
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from flask import g, url_for

from udata.i18n import I18nBlueprint, language

from . import DBTestMixin, WebTestMixin, TestCase
from .factories import UserFactory

bp = I18nBlueprint('i18nbp', __name__)


@bp.route('/lang/<msg>/')
def lang(msg):
    return g.lang_code


@bp.route('/hardcoded/')
def hardcoded():
    out = g.lang_code + '-'
    with language('fr'):
        out += g.lang_code
    return out


class I18nBlueprintTest(WebTestMixin, DBTestMixin, TestCase):
    def create_app(self):
        app = super(I18nBlueprintTest, self).create_app()
        app.config['DEFAULT_LANGUAGE'] = 'en'
        app.config['LANGUAGES'] = {
Example #6
0
from __future__ import unicode_literals

from flask import url_for, redirect, abort
from jinja2.exceptions import TemplateNotFound

from udata import theme
from udata.models import Reuse, Organization, Dataset
from udata.i18n import I18nBlueprint
from udata.sitemap import sitemap

from .models import (DATACONNEXIONS_5_CANDIDATE, C3, NECMERGITUR, OPENFIELD16,
                     SPD)

blueprint = I18nBlueprint('gouvfr',
                          __name__,
                          template_folder='templates',
                          static_folder='static',
                          static_url_path='/static/gouvfr')


@blueprint.route('/dataset/<dataset>/')
def redirect_datasets(dataset):
    '''Route Legacy CKAN datasets'''
    return redirect(url_for('datasets.show', dataset=dataset))


@blueprint.route('/organization/')
def redirect_organizations_list():
    '''Route legacy CKAN organizations listing'''
    return redirect(url_for('organizations.list'))
Example #7
0
from authlib.specs.rfc6750 import BearerTokenValidator
from authlib.specs.rfc7009 import RevocationEndpoint
from flask import abort, request
from flask_security.utils import verify_password
from werkzeug.exceptions import Unauthorized
from werkzeug.security import gen_salt

from udata import theme
from udata.app import csrf
from udata.auth import current_user, login_required, login_user
from udata.i18n import I18nBlueprint, lazy_gettext as _
from udata.models import db
from udata.core.user.models import User
from udata.core.storages import images, default_image_basename

blueprint = I18nBlueprint('oauth', __name__, url_prefix='/oauth')
oauth = AuthorizationServer()
require_oauth = ResourceProtector()

GRANT_EXPIRATION = 100  # 100 seconds
TOKEN_EXPIRATION = 30 * 24 * 60 * 60  # 30 days in seconds
REFRESH_EXPIRATION = 30  # days
EPOCH = datetime.fromtimestamp(0)

TOKEN_TYPES = {
    'Bearer': _('Bearer Token'),
}

SCOPES = {
    'default': _('Default scope'),
    'admin': _('System administrator rights')
Example #8
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from flask import g, request

from udata import search, theme
from udata.i18n import I18nBlueprint
from udata.models import Topic, Reuse, Dataset
from udata.sitemap import sitemap
from udata.utils import multi_to_dict

from .permissions import TopicEditPermission

blueprint = I18nBlueprint('topics', __name__, url_prefix='/topics')


class TopicSearchQuery(search.SearchQuery):
    '''
    A SearchQuery that should also match on topic tags
    '''
    @property
    def topic(self):
        return self.kwargs['topic']

    def build_text_query(self):
        query = super(TopicSearchQuery, self).build_text_query()
        self._update_bool_query(
            query,
            {'should': [{
                'term': {
                    'tags': tag
Example #9
0
from udata.auth import current_user

from udata.i18n import I18nBlueprint

from udata.core.followers.models import Follow

blueprint = I18nBlueprint('followers', __name__)


@blueprint.app_template_global()
@blueprint.app_template_filter()
def is_following(obj):
    if not current_user.is_authenticated:
        return False
    return Follow.objects.is_following(current_user._get_current_object(), obj)
Example #10
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import logging

from flask import redirect, url_for

from udata.app import nav
from udata.core.user.permissions import sysadmin
from udata.i18n import I18nBlueprint

log = logging.getLogger(__name__)

blueprint = I18nBlueprint('admin', __name__, url_prefix='/admin')

navbar = nav.Bar('admin', [])


@blueprint.route('/', endpoint='root')
def redirect_to_first_admin_tab():
    endpoint = navbar.items[0].endpoint
    return redirect(url_for(endpoint))


class AdminView(object):
    require = sysadmin

    def get_context(self):
        context = super(AdminView, self).get_context()
        current_item = None
        for item in navbar:
Example #11
0
import logging

from udata.frontend import csv
from udata.i18n import I18nBlueprint

from .csv import TagCsvAdapter
from .models import Tag

log = logging.getLogger(__name__)


blueprint = I18nBlueprint('tags', __name__)


@blueprint.route('/tags.csv', endpoint='csv', cors=True)
def tags_csv():
    adapter = TagCsvAdapter(Tag.objects.order_by('-total'))
    return csv.stream(adapter, 'tags')
Example #12
0
from __future__ import unicode_literals

from contextlib import contextmanager

from flask import json

from udata.core import storages
from udata.core.storages.views import blueprint
from udata.i18n import I18nBlueprint

from ..factories import UserFactory
from ..frontend import FrontTestCase

# Temporary fix to have the admin blueprint in context before we integrate
# it directly within the udata core.
admin = I18nBlueprint('admin', __name__)


@admin.route('/admin/', defaults={'path': ''})
@admin.route('/admin/<path:path>')
def index(path):
    pass
# End of fix, don't forget the registerd blueprint below.


class APITestCase(FrontTestCase):
    def create_app(self):
        app = super(APITestCase, self).create_app()
        storages.init_app(app)
        app.register_blueprint(blueprint)
        try:
Example #13
0
class ContactForm(FlaskForm):
    name = fields.StringField("Name", [validators.Required()])
    email = EmailField("Email", [validators.Required(), validators.Email()])
    subject = fields.StringField("Subject", [validators.Required()])
    message = fields.TextAreaField("Message", [validators.Required()])
    recaptcha = recaptcha.RecaptchaField()

def get_redis_connection():
    parsed_url = urlparse(current_app.config['CELERY_BROKER_URL'])
    db = parsed_url.path[1:] if parsed_url.path else 0
    return redis.StrictRedis(host=parsed_url.hostname, port=parsed_url.port,
                             db=db)

blueprint = I18nBlueprint('gouvpt', __name__,
                          template_folder='../theme/templates/custom',
                          static_folder='../theme/static')


#Dynamic FAQ's pages cached in redis
@blueprint.route('/docs/', defaults={'section': 'index'})
@blueprint.route('/docs/<string:section>/')
def faq(section):
    r = get_redis_connection()
    lang_code = g.get('lang_code', current_app.config['DEFAULT_LANGUAGE'])
    lang = lang_code if lang_code == current_app.config['DEFAULT_LANGUAGE'] else 'en'
    try:
        giturl = "https://raw.githubusercontent.com/amagovpt/docs.dados.gov.pt/master/faqs_{0}/{1}.md".format(lang,section)
        response = urllib2.urlopen(giturl, timeout = 2).read().decode('utf-8')
        content = Markup(markdown.markdown(response))
    except urllib2.URLError:
Example #14
0
import inspect
import logging

from importlib import import_module
from jinja2 import Markup, contextfunction

from udata import assets, entrypoints
from udata.i18n import I18nBlueprint

from .markdown import UdataCleaner, init_app as init_markdown


log = logging.getLogger(__name__)


hook = I18nBlueprint('hook', __name__)

_template_hooks = {}

def _wrapper(func, name=None, when=None):
    name = name or func.__name__
    if name not in _template_hooks:
        _template_hooks[name] = []
    _template_hooks[name].append((func, when))
    return func


def template_hook(func_or_name, when=None):
    if callable(func_or_name):
        return _wrapper(func_or_name)
    elif isinstance(func_or_name, str):
Example #15
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from collections import namedtuple
from datetime import date, datetime
import unicodedata

from flask import abort, current_app, redirect, url_for

from udata import theme
from udata.auth import current_user
from udata.core.dataset.permissions import DatasetEditPermission
from udata.i18n import I18nBlueprint
from udata.models import Dataset, GeoZone, TERRITORY_DATASETS
from udata.sitemap import sitemap

blueprint = I18nBlueprint('territories', __name__)


def dict_to_namedtuple(name, data):
    """Convert a `data` dict to a namedtuple.

    Useful for easy attribute access.
    """
    return namedtuple(name, data.keys())(**data)


@blueprint.route('/territories/', endpoint='home')
def render_home():
    if not current_app.config.get('ACTIVATE_TERRITORIES'):
        return abort(404)
Example #16
0
import logging

from importlib import import_module

from flask import abort, current_app

from udata.i18n import I18nBlueprint

from .markdown import init_app as init_markdown

from .. import theme


log = logging.getLogger(__name__)

front = I18nBlueprint('front', __name__)

_footer_snippets = []


def footer_snippet(func):
    _footer_snippets.append(func)
    return func


@front.app_context_processor
def inject_footer_snippets():
    return {'footer_snippets': _footer_snippets}


@front.app_context_processor
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from flask import g, url_for
from werkzeug.routing import BuildError

from udata.i18n import I18nBlueprint, language

from . import DBTestMixin, WebTestMixin, TestCase
from udata.core.user.factories import UserFactory

bp = I18nBlueprint('i18nbp', __name__, static_folder='static')


@bp.route('/lang/<msg>/')
def lang(msg):
    return g.lang_code


@bp.route('/hardcoded/')
def hardcoded():
    out = g.lang_code + '-'
    with language('fr'):
        out += g.lang_code
    return out


class I18nBlueprintTest(WebTestMixin, DBTestMixin, TestCase):
    def create_app(self):
        app = super(I18nBlueprintTest, self).create_app()
        app.config['DEFAULT_LANGUAGE'] = 'en'
Example #18
0
from flask import abort, request, url_for
from werkzeug.contrib.atom import AtomFeed

from udata.app import nav
from udata.frontend.views import SearchView, DetailView
from udata.i18n import I18nBlueprint, lazy_gettext as _
from udata.models import Follow
from udata.sitemap import sitemap
from udata.theme import render as render_template

from .models import Reuse
from .permissions import ReuseEditPermission

blueprint = I18nBlueprint('reuses', __name__, url_prefix='/reuses')


@blueprint.route('/recent.atom')
def recent_feed():
    feed = AtomFeed(_('Last reuses'),
                    feed_url=request.url,
                    url=request.url_root)
    reuses = Reuse.objects.visible().order_by('-created_at').limit(15)
    for reuse in reuses:
        author = None
        if reuse.organization:
            author = {
                'name':
                reuse.organization.name,
                'uri':
                url_for('organizations.show',
                        org=reuse.organization.id,
Example #19
0
from flask_security.utils import login_user

from udata import theme
from udata.i18n import I18nBlueprint, gettext as _

from udata.core.user.models import datastore

from .forms import LoginForm
from .ldap import manager
from .utils import get_ldap_value

from flask_ldap3_login import AuthenticationResponseStatus

bp = I18nBlueprint('ldap',
                   __name__,
                   url_prefix='/ldap',
                   template_folder='templates')

log = logging.getLogger(__name__)


@bp.before_app_request
def check_remote_user():
    if not current_app.config.get('LDAP_ALLOW_REMOTE_USER', False):
        return
    remote_user = request.headers.get('REMOTE_USER')
    if not remote_user:
        return
    data = manager.get_trusted_user_infos(
        remote_user, manager.config.get('LDAP_REMOTE_USER_ATTR'))
    if data:
Example #20
0
import logging

from flask import abort, g
from flask_security import current_user

from udata.frontend.views import DetailView
from udata.models import User, Activity, Organization, Dataset, Reuse, Follow
from udata.i18n import I18nBlueprint

from .permissions import sysadmin

blueprint = I18nBlueprint('users', __name__, url_prefix='/users')

log = logging.getLogger(__name__)


@blueprint.before_app_request
def set_g_sysadmin():
    g.sysadmin = sysadmin


@blueprint.app_context_processor
def inject_sysadmin_perms():
    return {'sysadmin': sysadmin}


class UserView(object):
    model = User
    object_name = 'user'

    @property
Example #21
0
from flask import abort, request
from flask.ext.oauthlib.provider import OAuth2Provider
from werkzeug.security import gen_salt
from werkzeug.exceptions import Unauthorized

from udata import theme
from udata.app import Blueprint, csrf
from udata.auth import current_user, login_required, login_user
from udata.i18n import I18nBlueprint, lazy_gettext as _
from udata.models import db
from udata.core.storages import images, default_image_basename


oauth = OAuth2Provider()
bp = Blueprint('oauth', __name__)
i18n = I18nBlueprint('oauth-i18n', __name__)


GRANT_EXPIRATION = 100  # 100 seconds
TOKEN_EXPIRATION = 30 * 24 # 30 days


CLIENT_TYPES = {
    'public': _('Public'),
    'confidential': _('Confidential'),
}

CLIENT_PROFILES = {
    'web': _('Web Application'),
    'user': _('User Agent'),
    'native': _('Native'),
Example #22
0
from udata.frontend import csv
from udata.frontend.views import DetailView, SearchView
from udata.i18n import I18nBlueprint, lazy_gettext as _
from udata.models import (Organization, Reuse, Dataset, Follow, Issue,
                          Discussion)
from udata.sitemap import sitemap

from udata.core.dataset.csv import (DatasetCsvAdapter,
                                    IssuesOrDiscussionCsvAdapter,
                                    ResourcesCsvAdapter)

from .permissions import (EditOrganizationPermission,
                          OrganizationPrivatePermission)

blueprint = I18nBlueprint('organizations',
                          __name__,
                          url_prefix='/organizations')


@blueprint.before_app_request
def set_g_user_orgs():
    if current_user.is_authenticated:
        g.user_organizations = current_user.organizations


@blueprint.route('/', endpoint='list')
class OrganizationListView(SearchView):
    model = Organization
    context_name = 'organizations'
    template_name = 'organization/list.html'
Example #23
0
from udata.i18n import I18nBlueprint, get_locale
from udata.auth import (current_user, login_user, Permission, RoleNeed,
                        PermissionDenied)
from udata.core.user.models import User
from udata.core.organization.factories import OrganizationFactory
from udata.core.organization.models import Organization
from udata.sitemap import sitemap
from udata.utils import safe_unicode

from . import fields, oauth2
from .signals import on_api_call

log = logging.getLogger(__name__)

apiv1 = Blueprint('api', __name__, url_prefix='/api/1')
apidoc = I18nBlueprint('apidoc', __name__)

DEFAULT_PAGE_SIZE = 50
HEADER_API_KEY = 'X-API-KEY'

# TODO: make upstream flask-restplus automatically handle
# flask-restplus headers and allow lazy evaluation
# of headers (ie. callable)
PREFLIGHT_HEADERS = (
    HEADER_API_KEY,
    'X-Fields',
    'Content-Type',
    'Accept',
    'Accept-Charset',
    'Accept-Language',
    'Cache-Control',
Example #24
0
from udata.core.reuse.csv import ReuseCsvAdapter
from udata.core.reuse.models import Reuse
from udata.frontend import csv
from udata.frontend.views import DetailView
from udata.i18n import I18nBlueprint, lazy_gettext as _
from udata.rdf import (
    CONTEXT, RDF_MIME_TYPES, RDF_EXTENSIONS,
    negociate_content, graph_response
)
from udata.sitemap import sitemap
from udata.utils import multi_to_dict

from .models import current_site
from .rdf import build_catalog

blueprint = I18nBlueprint('site', __name__)

log = logging.getLogger(__name__)


@blueprint.app_context_processor
def inject_site():
    return dict(current_site=current_site)


@blueprint.route('/activity.atom')
def activity_feed():
    activity_keys = request.args.getlist('key')

    feed = AtomFeed(
        current_app.config.get('SITE_TITLE'), feed_url=request.url,
Example #25
0
from flask import current_app

from udata import theme
from udata.frontend.views import ListView
from udata.i18n import I18nBlueprint
from udata.models import Post
from udata.sitemap import sitemap

from .permissions import PostEditPermission

blueprint = I18nBlueprint('posts', __name__, url_prefix='/posts')


class PostView(object):
    model = Post
    object_name = 'post'

    @property
    def _post(self):
        return self.get_object()


class ProtectedPostView(PostView):
    require = PostEditPermission()


@blueprint.route('/', endpoint='list')
class PostListView(ListView):
    model = Post
    template_name = 'post/list.html'
    context_name = 'posts'
Example #26
0
from udata.core.site.models import current_site
from udata.frontend.views import DetailView, SearchView
from udata.i18n import I18nBlueprint, lazy_gettext as _
from udata.models import Follow, Reuse
from udata.rdf import (RDF_MIME_TYPES, RDF_EXTENSIONS, negociate_content,
                       want_rdf, graph_response)
from udata.sitemap import sitemap
from udata.theme import render as render_template

from .models import Dataset, RESOURCE_TYPES, get_resource
from .rdf import dataset_to_rdf
from .search import DatasetSearch
from .permissions import ResourceEditPermission, DatasetEditPermission

blueprint = I18nBlueprint('datasets', __name__, url_prefix='/datasets')


@blueprint.route('/recent.atom')
def recent_feed():
    feed = AtomFeed(_('Last datasets'),
                    feed_url=request.url,
                    url=request.url_root)
    datasets = (Dataset.objects.visible().order_by('-created_at').limit(
        current_site.feed_size))
    for dataset in datasets:
        author = None
        if dataset.organization:
            author = {
                'name':
                dataset.organization.name,
Example #27
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from flask import url_for, redirect, abort
from jinja2.exceptions import TemplateNotFound

from udata import theme
from udata.models import Reuse, Organization, Dataset
from udata.i18n import I18nBlueprint
from udata.sitemap import sitemap

blueprint = I18nBlueprint('components-guidelines',
                          __name__,
                          template_folder='templates',
                          static_folder='static',
                          static_url_path='/static/gouvfr')


@blueprint.route('/carousel')
def carousel():
    theme.render('carousel.html')