Example #1
0
def unlock_task(name):
    """Unlock a locked task.

    :return: ``True`` if the task has been unlocked; ``False`` if it was not locked.
    """
    cache = GenericCache('task-locks')
    if not cache.get(name):
        return False
    cache.delete(name)
    return True
Example #2
0
 def _send_confirmation(self, email):
     token_storage = GenericCache('confirm-email')
     data = {'email': email, 'user_id': self.user.id}
     token = make_unique_token(lambda t: not token_storage.get(t))
     token_storage.set(token, data, 24 * 3600)
     send_email(
         make_email(email,
                    template=get_template_module(
                        'users/emails/verify_email.txt',
                        user=self.user,
                        email=email,
                        token=token)))
 def _get_user_data(self):
     user_id = request.args.get('user')
     if user_id is None:
         return {}
     elif user_id.isdigit():
         # existing fossir user
         user = User.find_first(id=user_id, is_deleted=False)
         user_data = {t.name: getattr(user, t.name, None) if user else '' for t in PersonalDataType}
     else:
         # non-fossir user
         data = GenericCache('pending_identities').get(user_id, {})
         user_data = {t.name: data.get(t.name) for t in PersonalDataType}
     user_data['title'] = get_title_uuid(self.regform, user_data['title'])
     return user_data
Example #4
0
 def has_member(self, user):
     if not user:
         return False
     cache = GenericCache('group-membership')
     key = '{}:{}:{}'.format(self.provider, self.name, user.id)
     rv = cache.get(key)
     if rv is not None:
         return rv
     elif self.group is None:
         warn('Tried to check if {} is in invalid group {}'.format(user, self))
         rv = False
     else:
         rv = any(x[1] in self.group for x in user.iter_identifiers(check_providers=True, providers={self.provider}))
     cache.set(key, rv, 1800)
     return rv
Example #5
0
 def _process_identities(obj):
     if isinstance(obj, IdentityInfo):
         GenericCache('pending_identities').set(
             '{}:{}'.format(obj.provider.name, obj.identifier), obj.data)
         return AvatarProvisionalWrapper(obj)
     else:
         return obj.as_avatar
Example #6
0
class RHUserEmailsVerify(RHUserBase):
    flash_user_status = False
    token_storage = GenericCache('confirm-email')

    def _validate(self, data):
        if not data:
            flash(_('The verification token is invalid or expired.'), 'error')
            return False, None
        user = User.get(data['user_id'])
        if not user or user != self.user:
            flash(
                _('This token is for a different fossir user. Please login with the correct account'
                  ), 'error')
            return False, None
        existing = UserEmail.find_first(is_user_deleted=False,
                                        email=data['email'])
        if existing and not existing.user.is_pending:
            if existing.user == self.user:
                flash(
                    _('This email address is already attached to your account.'
                      ))
            else:
                flash(
                    _('This email address is already in use by another account.'
                      ), 'error')
            return False, existing.user
        return True, existing.user if existing else None

    def _process(self):
        token = request.view_args['token']
        data = self.token_storage.get(token)
        valid, existing = self._validate(data)
        if valid:
            self.token_storage.delete(token)

            if existing and existing.is_pending:
                logger.info("Found pending user %s to be merged into %s",
                            existing, self.user)

                # If the pending user has missing names, copy them from the active one
                # to allow it to be marked as not pending and deleted during the merge.
                existing.first_name = existing.first_name or self.user.first_name
                existing.last_name = existing.last_name or self.user.last_name

                merge_users(existing, self.user)
                flash(
                    _("Merged data from existing '{}' identity").format(
                        existing.email))
                existing.is_pending = False

            self.user.secondary_emails.add(data['email'])
            signals.users.email_added.send(self.user, email=data['email'])
            flash(
                _('The email address {email} has been added to your account.').
                format(email=data['email']), 'success')
        return redirect(url_for('.user_emails'))
Example #7
0
 def wrapper(*args, **kwargs):
     cache = GenericCache('task-locks')
     name = current_task.name
     if cache.get(name):
         Logger.get('celery').warning(
             'Task %s is locked; not executing it. '
             'To manually unlock it, run `fossir celery unlock %s`', name,
             name)
         return
     cache.set(name, True, 86400)
     try:
         return f(*args, **kwargs)
     finally:
         cache.delete(name)
def memoize_redis(ttl):
    """Memoize a function in redis

    The cached value can be cleared by calling the method
    ``clear_cached()`` of the decorated function with the same
    arguments that were used during the function call.  To check
    whether a value has been cached call ``is_cached()`` in the
    same way.

    :param ttl: How long the result should be cached.  May be a
                timedelta or a number (seconds).
    """
    from fossir.legacy.common.cache import GenericCache
    cache = GenericCache('memoize')

    def decorator(f):
        def _get_key(args, kwargs):
            return f.__name__, make_hashable(getcallargs(f, *args, **kwargs))

        def _clear_cached(*args, **kwargs):
            cache.delete(_get_key(args, kwargs))

        def _is_cached(*args, **kwargs):
            return cache.get(_get_key(args, kwargs), _notset) is not _notset

        @wraps(f)
        def memoizer(*args, **kwargs):
            if current_app.config['TESTING'] or current_app.config.get('REPL'):
                # No memoization during tests or in the shell
                return f(*args, **kwargs)

            key = _get_key(args, kwargs)
            value = cache.get(key, _notset)
            if value is _notset:
                value = f(*args, **kwargs)
                cache.set(key, value, ttl)
            return value

        memoizer.clear_cached = _clear_cached
        memoizer.is_cached = _is_cached
        return memoizer

    return decorator
Example #9
0
class WPRoomBookingMapOfRoomsWidget(WPNotDecorated):
    sidemenu_option = 'map'
    cache = GenericCache('MapOfRooms')

    def getCSSFiles(self):
        return WPNotDecorated.getCSSFiles(self) + ['css/mapofrooms.css']

    def getJSFiles(self):
        return WPNotDecorated.getJSFiles(self) + self._includeJSPackage(
            'RoomBooking')

    def _get_widget_params(self):
        default_location = Location.default_location
        return {
            'aspects': [a.to_serializable() for a in default_location.aspects],
            'buildings':
            default_location.get_buildings(),
            'default_repeat':
            '{}|0'.format(int(RepeatFrequency.NEVER)),
            'default_start_dt':
            datetime.combine(date.today(), Location.working_time_start),
            'default_end_dt':
            datetime.combine(date.today(), Location.working_time_end),
            'repeat_mapping':
            RepeatMapping.mapping
        }

    def _getBody(self, params):
        api_key = rb_settings.get('google_maps_api_key')
        cache_key = str(sorted(dict(
            request.args, lang=session.lang).items())) + str(crc32(api_key))
        html = self.cache.get(cache_key)
        if html is None:
            params.update(self._get_widget_params())
            params['api_key'] = api_key
            html = WTemplated('RoomBookingMapOfRoomsWidget').getHTML(params)
            self.cache.set(cache_key, html, 3600)
        return html
Example #10
0
class OAuthGrant(object):
    """OAuth grant token"""

    #: cache entry to store grant tokens
    _cache = GenericCache('oauth-grant-tokens')

    def __init__(self, client_id, code, redirect_uri, user, scopes, expires):
        self.client_id = client_id
        self.code = code
        self.redirect_uri = redirect_uri
        self.user = user
        self.scopes = scopes
        self.expires = expires

    @property
    def key(self):
        return self.make_key(self.client_id, self.code)

    @property
    def ttl(self):
        return self.expires - datetime.utcnow()

    @classmethod
    def get(cls, client_id, code):
        key = cls.make_key(client_id, code)
        return cls._cache.get(key)

    @classmethod
    def make_key(cls, client_id, code):
        return '{}:{}'.format(client_id, code)

    def delete(self):
        self._cache.delete(self.key)

    def save(self):
        self._cache.set(key=self.key, val=self, time=self.ttl)
Example #11
0
def principal_from_fossil(fossil,
                          allow_pending=False,
                          allow_groups=True,
                          allow_missing_groups=False,
                          allow_emails=False,
                          allow_networks=False,
                          existing_data=None):
    from fossir.modules.networks.models.networks import IPNetworkGroup
    from fossir.modules.groups import GroupProxy
    from fossir.modules.users import User

    if existing_data is None:
        existing_data = set()

    type_ = fossil['_type']
    id_ = fossil['id']
    if type_ == 'Avatar':
        if isinstance(id_, int) or id_.isdigit():
            # regular user
            user = User.get(int(id_))
        elif allow_pending:
            data = GenericCache('pending_identities').get(id_)
            if not data:
                raise ValueError("Cannot find user '{}' in cache".format(id_))

            data = {k: '' if v is None else v for k, v in data.items()}
            email = data['email'].lower()

            # check if there is not already a (pending) user with that e-mail
            # we need to check for non-pending users too since the search may
            # show a user from external results even though the email belongs
            # to an fossir account in case some of the search criteria did not
            # match the fossir account
            user = User.find_first(User.all_emails.contains(email),
                                   ~User.is_deleted)
            if not user:
                user = User(first_name=data.get('first_name') or '',
                            last_name=data.get('last_name') or '',
                            email=email,
                            address=data.get('address', ''),
                            phone=data.get('phone', ''),
                            affiliation=data.get('affiliation', ''),
                            is_pending=True)
                db.session.add(user)
                db.session.flush()
        else:
            raise ValueError(
                "Id '{}' is not a number and allow_pending=False".format(id_))
        if user is None:
            raise ValueError('User does not exist: {}'.format(id_))
        return user
    elif allow_emails and type_ == 'Email':
        return EmailPrincipal(id_)
    elif allow_networks and type_ == 'IPNetworkGroup':
        group = IPNetworkGroup.get(int(id_))
        if group is None or (group.hidden and group not in existing_data):
            raise ValueError('IP network group does not exist: {}'.format(id_))
        return group
    elif allow_groups and type_ in {'LocalGroupWrapper', 'LocalGroup'}:
        group = GroupProxy(int(id_))
        if group.group is None:
            raise ValueError('Local group does not exist: {}'.format(id_))
        return group
    elif allow_groups and type_ in {'LDAPGroupWrapper', 'MultipassGroup'}:
        provider = fossil['provider']
        group = GroupProxy(id_, provider)
        if group.group is None and not allow_missing_groups:
            raise ValueError('Multipass group does not exist: {}:{}'.format(
                provider, id_))
        return group
    else:
        raise ValueError('Unexpected fossil type: {}'.format(type_))
Example #12
0
import posixpath
from io import BytesIO

from flask import redirect

from fossir.core.config import config
from fossir.legacy.common.cache import GenericCache
from fossir.modules.rb.models.photos import Photo
from fossir.modules.rb.models.rooms import Room
from fossir.web.flask.util import send_file

_cache = GenericCache('Rooms')


def _redirect_no_photo(size):
    return redirect(
        posixpath.join(config.IMAGES_BASE_URL,
                       'rooms/{}_photos/NoPhoto.jpg'.format(size)))


def room_photo(roomID, size, **kw):
    cache_key = 'photo-{}-{}'.format(roomID, size)
    photo_data = _cache.get(cache_key)

    if photo_data == '*':
        return _redirect_no_photo(size)
    elif photo_data is None:
        photo = Photo.find_first(Room.id == roomID, _join=Photo.room)
        if photo is None:
            _cache.set(cache_key, '*')
            return _redirect_no_photo(size)
Example #13
0
import uuid

from flask import request
from werkzeug.exceptions import Forbidden, NotFound

from fossir.legacy.common.cache import GenericCache
from fossir.modules.designer.models.templates import DesignerTemplate
from fossir.modules.events.management.controllers import RHManageEventBase
from fossir.modules.events.management.forms import PosterPrintingForm
from fossir.modules.events.posters import PosterPDF
from fossir.util.i18n import _
from fossir.web.flask.util import send_file, url_for
from fossir.web.util import jsonify_data, jsonify_form


poster_cache = GenericCache('poster-printing')


class RHPosterPrintSettings(RHManageEventBase):
    ALLOW_LOCKED = True

    def _process_args(self):
        RHManageEventBase._process_args(self)
        self.template_id = request.args.get('template_id')

    def _process(self):
        self.commit = False
        form = PosterPrintingForm(self.event, template=self.template_id)
        if form.validate_on_submit():
            data = dict(form.data)
            template_id = data.pop('template')
Example #14
0
import fossir
from fossir.core import signals
from fossir.core.config import config
from fossir.core.db import db
from fossir.core.plugins import url_for_plugin
from fossir.legacy.common.cache import GenericCache
from fossir.modules.events.layout import layout_settings
from fossir.modules.events.layout.models.menu import MenuEntry, MenuEntryType, TransientMenuEntry
from fossir.util.caching import memoize_request
from fossir.util.signals import named_objects_from_signal, values_from_signal
from fossir.util.string import crc32, return_ascii
from fossir.web.flask.util import url_for


_cache = GenericCache('updated-menus')


def _menu_entry_key(entry_data):
    return entry_data.position == -1, entry_data.position, entry_data.name


@memoize_request
def get_menu_entries_from_signal():
    return named_objects_from_signal(signals.event.sidemenu.send(), plugin_attr='plugin')


def build_menu_entry_name(name, plugin=None):
    """ Builds the proper name for a menu entry.

    Given a menu entry's name and optionally a plugin, returns the
class fossirSessionInterface(SessionInterface):
    pickle_based = True
    serializer = cPickle
    session_class = fossirSession
    temporary_session_lifetime = timedelta(days=7)

    def __init__(self):
        self.storage = GenericCache('flask-session')

    def generate_sid(self):
        return str(uuid.uuid4())

    def get_cookie_secure(self, app):
        return request.is_secure

    def get_storage_lifetime(self, app, session):
        # Permanent sessions are stored for exactly the same duration as the session id cookie.
        # "Temporary" session are stored for a period that is not too short/long as some people
        # close their browser very rarely and thus shouldn't be logged out that often.
        if session.permanent:
            return app.permanent_session_lifetime
        else:
            return self.temporary_session_lifetime

    def should_refresh_session(self, app, session):
        if session.new or '_expires' not in session:
            return False
        threshold = self.get_storage_lifetime(app, session) / 2
        return session['_expires'] - datetime.now() < threshold

    def should_refresh_sid(self, app, session):
        if not session.new and self.get_cookie_secure(
                app) and not session.get('_secure'):
            return True
        if getattr(session, '_refresh_sid', False):
            return True
        return False

    def open_session(self, app, request):
        sid = request.cookies.get(app.session_cookie_name)
        if not sid:
            return self.session_class(sid=self.generate_sid(), new=True)
        data = self.storage.get(sid)
        if data is not None:
            return self.session_class(self.serializer.loads(data), sid=sid)
        return self.session_class(sid=self.generate_sid(), new=True)

    def save_session(self, app, session, response):
        domain = self.get_cookie_domain(app)
        secure = self.get_cookie_secure(app)
        refresh_sid = self.should_refresh_sid(app, session)
        if not session and not session.new:
            # empty session, delete it from storage and cookie
            self.storage.delete(session.sid)
            response.delete_cookie(app.session_cookie_name, domain=domain)
            return

        if not refresh_sid and not session.modified and not self.should_refresh_session(
                app, session):
            # If the session has not been modified we only store if it needs to be refreshed
            return

        if config.SESSION_LIFETIME > 0:
            # Setting session.permanent marks the session as modified so we only set it when we
            # are saving the session anyway!
            session.permanent = True

        storage_ttl = self.get_storage_lifetime(app, session)
        cookie_lifetime = self.get_expiration_time(app, session)
        session['_expires'] = datetime.now() + storage_ttl

        if refresh_sid:
            self.storage.delete(session.sid)
            session.sid = self.generate_sid()

        session['_secure'] = request.is_secure
        self.storage.set(session.sid, self.serializer.dumps(dict(session)),
                         storage_ttl)
        response.set_cookie(app.session_cookie_name,
                            session.sid,
                            expires=cookie_lifetime,
                            httponly=True,
                            secure=secure)
 def __init__(self):
     self.storage = GenericCache('flask-session')
from fossir.modules.events.registration.util import (create_registration, generate_spreadsheet_from_registrations,
                                                     get_event_section_data, get_ticket_attachments, get_title_uuid,
                                                     make_registration_form)
from fossir.modules.events.registration.views import WPManageRegistration
from fossir.modules.events.util import ZipGeneratorMixin
from fossir.modules.users import User
from fossir.util.fs import secure_filename
from fossir.util.i18n import _, ngettext
from fossir.util.placeholders import replace_placeholders
from fossir.util.spreadsheets import send_csv, send_xlsx
from fossir.web.flask.templating import get_template_module
from fossir.web.flask.util import send_file, url_for
from fossir.web.util import jsonify_data, jsonify_template


badge_cache = GenericCache('badge-printing')


def _render_registration_details(registration):
    event = registration.registration_form.event
    tpl = get_template_module('events/registration/management/_registration_details.html')
    return tpl.render_registration_details(registration=registration, payment_enabled=event.has_feature('payment'))


class RHRegistrationsListManage(RHManageRegFormBase):
    """List all registrations of a specific registration form of an event"""

    def _process(self):
        if self.list_generator.static_link_used:
            return redirect(self.list_generator.get_list_url())
        reg_list_kwargs = self.list_generator.get_list_kwargs()