def create_next(cls, registration, amount, currency, action, provider=None, data=None):
     previous_transaction = registration.transaction
     new_transaction = PaymentTransaction(amount=amount, currency=currency,
                                          provider=provider, data=data)
     registration.transaction = new_transaction
     try:
         next_status = TransactionStatusTransition.next(previous_transaction, action, provider)
     except InvalidTransactionStatus as e:
         Logger.get('payment').exception("%s (data received: %r)", e, data)
         return None
     except InvalidManualTransactionAction as e:
         Logger.get('payment').exception("Invalid manual action code '%s' on initial status (data received: %r)",
                                         e, data)
         return None
     except InvalidTransactionAction as e:
         Logger.get('payment').exception("Invalid action code '%s' on initial status (data received: %r)", e, data)
         return None
     except IgnoredTransactionAction as e:
         Logger.get('payment').warning("%s (data received: %r)", e, data)
         return None
     except DoublePaymentTransaction:
         next_status = TransactionStatus.successful
         Logger.get('payment').info("Received successful payment for an already paid registration")
     new_transaction.status = next_status
     return new_transaction
예제 #2
0
def strip_ml_tags(in_text):
    """ Description: Removes all HTML/XML-like tags from the input text.
        Inputs: s --> string of text
        Outputs: text string without the tags

        # doctest unit testing framework

        >>> test_text = "Keep this Text <remove><me /> KEEP </remove> 123"
        >>> strip_ml_tags(test_text)
        'Keep this Text  KEEP  123'
    """

    # convert in_text to a mutable object (e.g. list)
    s_list = list(in_text)
    i = 0

    while i < len(s_list):
        # iterate until a left-angle bracket is found
        if s_list[i] == '<':
            try:
                while s_list[i] != '>':
                    # pop everything from the the left-angle bracket until the right-angle bracket
                    s_list.pop(i)
            except IndexError, e:
                Logger.get('strip_ml_tags').debug(
                    "Not found '>' (the end of the html tag): %s" % e)
                continue

            # pops the right-angle bracket, too
            s_list.pop(i)
        else:
            i = i + 1
 def _send_sentry(self, email, comment):
     # strip password and query string from the DSN, and all auth data from the POST target
     dsn = re.sub(r':[^@/]+(?=@)', '', config.SENTRY_DSN)
     url = url_parse(dsn)
     dsn = unicode(url.replace(query=None))
     verify = url.decode_query().get('ca_certs', True)
     url = unicode(
         url.replace(path='/api/embed/error-page/',
                     netloc=url._split_netloc()[1],
                     query=None))
     user_data = self.error_data['request_info']['user'] or {
         'name': 'Anonymous',
         'email': config.NO_REPLY_EMAIL
     }
     try:
         rv = requests.post(url,
                            params={
                                'dsn': dsn,
                                'eventId':
                                self.error_data['sentry_event_id']
                            },
                            data={
                                'name': user_data['name'],
                                'email': email or user_data['email'],
                                'comments': comment
                            },
                            headers={'Origin': config.BASE_URL},
                            verify=verify)
         rv.raise_for_status()
     except Exception:
         # don't bother users if this fails!
         Logger.get('sentry').exception('Could not submit user feedback')
예제 #4
0
 def get(self, key, default=None):
     self._connect()
     res = self._client.get(self._makeKey(key))
     Logger.get('cache.generic').debug('GET %s %r (%s)', self._namespace, key, 'HIT' if res is not None else 'MISS')
     if res is None:
         return default
     return _NoneValue.restore(res)
예제 #5
0
 def set_multi(self, mapping, ttl=0):
     try:
         self._client.mset(dict((k, pickle.dumps(v)) for k, v in mapping.iteritems()))
         if ttl:
             for key in mapping:
                 self._client.expire(key, ttl)
     except redis.RedisError:
         Logger.get('cache.redis').exception('set_multi(%r, %r) failed', mapping, ttl)
예제 #6
0
 def set(self, key, val, ttl=0):
     try:
         if ttl:
             self._client.setex(key, ttl, pickle.dumps(val))
         else:
             self._client.set(key, pickle.dumps(val))
     except redis.RedisError:
         val_repr = truncate(repr(val), 1000)
         Logger.get('cache.redis').exception('set(%r, %s, %r) failed', key, val_repr, ttl)
예제 #7
0
def process():
    clearCache()
    payload = request.json
    Logger.get('rpc').info('json rpc request. request: %r', payload)
    rv = {}
    if 'id' in payload:
        rv['id'] = payload['id']
    rv['result'] = invoke_method(str(payload['method']),
                                 payload.get('params', []))
    return jsonify(rv)
예제 #8
0
    def set(self, key, val, time=0):
        """Set key to val with optional validity time.

        :param key: the key of the cache entry
        :param val: any python object that can be pickled
        :param time: number of seconds or a datetime.timedelta
        """
        self._connect()
        time = self._processTime(time)
        Logger.get('cache.generic').debug('SET %s %r (%d)', self._namespace, key, time)
        self._client.set(self._makeKey(key), _NoneValue.replace(val), time)
예제 #9
0
def handle_exception(exc, message=None):
    Logger.get('flask').exception(
        to_unicode(exc.message) or 'Uncaught Exception')
    if not current_app.debug or request.is_xhr or request.is_json:
        sentry_log_exception()
        if message is None:
            message = '{}: {}'.format(
                type(exc).__name__, to_unicode(exc.message))
        return render_error(exc, _('Something went wrong'), message, 500)
    # Let the exception propagate to middleware /the webserver.
    # This triggers the Flask debugger in development and sentry
    # logging (if enabled) (via got_request_exception).
    raise
예제 #10
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)
예제 #11
0
 def set(self, key, val, ttl=0):
     try:
         f = open(self._getFilePath(key), 'wb')
         OSSpecific.lockFile(f, 'LOCK_EX')
         try:
             expiry = int(time.time()) + ttl if ttl else None
             data = (expiry, val)
             pickle.dump(data, f)
         finally:
             OSSpecific.lockFile(f, 'LOCK_UN')
             f.close()
     except (IOError, OSError):
         Logger.get('cache.files').exception('Error setting value in cache')
         return 0
     return 1
예제 #12
0
 def __init__(self,
              fallback_loader,
              customization_dir,
              customization_debug=False):
     from fossir.core.logger import Logger
     self.logger = Logger.get('customization')
     self.debug = customization_debug
     self.fallback_loader = fallback_loader
     self.fs_loader = FileSystemLoader(customization_dir, followlinks=True)
예제 #13
0
 def parseRequest(cls, path, queryParams):
     """Parse a request path and return a hook and the requested data type."""
     path = urllib.unquote(path)
     hooks = cls.HOOK_LIST
     for expCls in hooks:
         Logger.get('HTTPAPIHook.parseRequest').debug(expCls)
         m = expCls._matchPath(path)
         if m:
             gd = m.groupdict()
             g = m.groups()
             type = g[0]
             format = g[-1]
             if format not in DataFetcher.getAllowedFormats():
                 return None, None
             elif expCls.VALID_FORMATS and format not in expCls.VALID_FORMATS:
                 return None, None
             return expCls(queryParams, type, gd, format), format
     return None, None
예제 #14
0
    def run_latex(self, source_file, log_file=None):
        pdflatex_cmd = [config.XELATEX_PATH,
                        '-no-shell-escape',
                        '-interaction', 'nonstopmode',
                        '-output-directory', self._dir,
                        source_file]

        try:
            subprocess.check_call(pdflatex_cmd, stdout=log_file)
            Logger.get('pdflatex').debug("PDF created successfully!")

        except subprocess.CalledProcessError:
            Logger.get('pdflatex').warning('PDF creation possibly failed (non-zero exit code)!')
            # Only fail if we are in strict mode
            if config.STRICT_LATEX:
                # flush log, go to beginning and read it
                if log_file:
                    log_file.flush()
                raise
예제 #15
0
def temp_cleanup():
    """Cleanup temp/cache dirs"""
    from fossir.core.config import config
    from fossir.core.logger import Logger
    logger = Logger.get()
    deleted = cleanup_dir(config.CACHE_DIR,
                          timedelta(days=1),
                          exclude=lambda x: x.startswith('webassets-'))
    _log_deleted(logger, 'Deleted from cache: %s', deleted)
    deleted = cleanup_dir(config.TEMP_DIR, timedelta(days=1))
    _log_deleted(logger, 'Deleted from temp: %s', deleted)
예제 #16
0
 def handle_starttag(self, tag, attrs):
     if tag not in allowedTags:
         raise HarmfulHTMLException(tag, self.getpos())
     for attr in attrs:
         if self.getSanitizationLevel() >= 2 and attr[0] == 'style':
             self.handle_inlineStyle(attr[1])
         elif attr[0] not in allowedAttrs:
             raise HarmfulHTMLException(attr[0], self.getpos())
         elif attr[0] in urlProperties:
             val_unescaped = re.sub("[`\000-\040\177-\240\s]+", '',
                                    unescape(attr[1])).lower()
             try:
                 #remove replacement characters from unescaped characters
                 val_unescaped = val_unescaped.replace(u"\ufffd", "")
             except UnicodeDecodeError, e:
                 Logger.get('RestrictedHTMLParser-urlProperties').exception(
                     str(e))
             if (re.match("^[a-z0-9][-+.a-z0-9]*:", val_unescaped) and
                 (val_unescaped.split(':')[0] not in allowedProtocols)):
                 raise HarmfulHTMLException(
                     val_unescaped.split(':')[0], self.getpos())
예제 #17
0
    def delete(self, user, delete_all=False):
        """Deletes a VC room from an event

        If the room is not used anywhere else, the room itself is also deleted.

        :param user: the user performing the deletion
        :param delete_all: if True, the room is detached from all
                           events and deleted.
        """
        vc_room = self.vc_room
        if delete_all:
            for assoc in vc_room.events[:]:
                Logger.get('modules.vc').info("Detaching VC room {} from event {} ({})".format(
                    vc_room, assoc.event, assoc.link_object)
                )
                vc_room.events.remove(assoc)
        else:
            Logger.get('modules.vc').info("Detaching VC room {} from event {} ({})".format(
                vc_room, self.event, self.link_object)
            )
            vc_room.events.remove(self)
        db.session.flush()
        if not vc_room.events:
            Logger.get('modules.vc').info("Deleting VC room {}".format(vc_room))
            if vc_room.status != VCRoomStatus.deleted:
                vc_room.plugin.delete_room(vc_room, self.event)
                notify_deleted(vc_room.plugin, vc_room, self, self.event, user)
            db.session.delete(vc_room)
예제 #18
0
    def get(self, key):
        try:
            path = self._getFilePath(key, False)
            if not os.path.exists(path):
                return None

            f = open(path, 'rb')
            OSSpecific.lockFile(f, 'LOCK_SH')
            expiry = val = None
            try:
                expiry, val = pickle.load(f)
            finally:
                OSSpecific.lockFile(f, 'LOCK_UN')
                f.close()
            if expiry and time.time() > expiry:
                return None
        except (IOError, OSError):
            Logger.get('cache.files').exception('Error getting cached value')
            return None
        except (EOFError, pickle.UnpicklingError):
            Logger.get('cache.files').exception('Cached information seems corrupted. Overwriting it.')
            return None

        return val
예제 #19
0
    def _process(self):
        if not self.plugin.can_manage_vc_rooms(session.user, self.event):
            flash(
                _('You are not allowed to refresh {plugin_name} rooms for this event.'
                  ).format(plugin_name=self.plugin.friendly_name), 'error')
            return redirect(url_for('.manage_vc_rooms', self.event))

        Logger.get('modules.vc').info("Refreshing VC room %r from event %r",
                                      self.vc_room, self.event)

        try:
            self.plugin.refresh_room(self.vc_room, self.event)
        except VCRoomNotFoundError as err:
            Logger.get('modules.vc').warning(
                "VC room %r not found. Setting it as deleted.", self.vc_room)
            self.vc_room.status = VCRoomStatus.deleted
            flash(err.message, 'error')
            return redirect(url_for('.manage_vc_rooms', self.event))

        flash(
            _("{plugin_name} room '{room.name}' refreshed").format(
                plugin_name=self.plugin.friendly_name, room=self.vc_room),
            'success')
        return redirect(url_for('.manage_vc_rooms', self.event))
예제 #20
0
    def to_serializable(self, attr='__public__', converters=None):
        serializable = {}
        if converters is None:
            converters = {}
        for k in getattr(self, attr):
            try:
                if isinstance(k, tuple):
                    k, name = k
                else:
                    k, name = k, k

                v = getattr(self, k)
                if callable(
                        v
                ):  # to make it generic, we can get rid of it by properties
                    v = v()
                if isinstance(v, Serializer):
                    v = v.to_serializable()
                elif isinstance(v, list):
                    v = [e.to_serializable() for e in v]
                elif isinstance(v, dict):
                    v = dict((k, vv.to_serializable(
                    ) if isinstance(vv, Serializer) else vv)
                             for k, vv in v.iteritems())
                elif isinstance(v, Enum):
                    v = v.name
                if type(v) in converters:
                    v = converters[type(v)](v)
                serializable[name] = v
            except Exception:
                msg = 'Could not retrieve {}.{}.'.format(
                    self.__class__.__name__, k)
                Logger.get('Serializer{}'.format(
                    self.__class__.__name__)).exception(msg)
                raise fossirError(msg)
        return serializable
예제 #21
0
from __future__ import unicode_literals

from flask import flash, request, session

from fossir.core import signals
from fossir.core.logger import Logger
from fossir.modules.events.settings import EventSettingsProxy
from fossir.util.i18n import ngettext
from fossir.web.flask.util import url_for
from fossir.web.menu import SideMenuItem

logger = Logger.get('events.features')
features_event_settings = EventSettingsProxy('features', {'enabled': None})


@signals.menu.items.connect_via('event-management-sidemenu')
def _extend_event_management_menu(sender, event, **kwargs):
    if not event.can_manage(session.user):
        return
    return SideMenuItem('features',
                        'Features',
                        url_for('event_features.index', event),
                        section='advanced')


@signals.app_created.connect
def _check_feature_definitions(app, **kwargs):
    # This will raise RuntimeError if the feature names are not unique
    from fossir.modules.events.features.util import get_feature_definitions
    get_feature_definitions()
예제 #22
0
 def delete(self, key):
     try:
         self._client.delete(key)
     except redis.RedisError:
         Logger.get('cache.redis').exception('delete(%r) failed', key)
예제 #23
0
 def get(self, key):
     try:
         return self._unpickle(self._client.get(key))
     except redis.RedisError:
         Logger.get('cache.redis').exception('get(%r) failed', key)
예제 #24
0
 def get_multi(self, keys):
     try:
         return dict(zip(keys, map(self._unpickle, self._client.mget(keys))))
     except redis.RedisError:
         Logger.get('cache.redis').exception('get_multi(%r) failed', keys)
예제 #25
0
from fossir.core import signals
from fossir.core.db import db
from fossir.core.logger import Logger
from fossir.core.roles import ManagementRole
from fossir.modules.events import Event
from fossir.modules.events.features.base import EventFeature
from fossir.modules.events.layout.util import MenuEntryData
from fossir.modules.events.models.events import EventType
from fossir.modules.events.registration.settings import RegistrationSettingsProxy
from fossir.util.i18n import _, ngettext
from fossir.web.flask.templating import template_hook
from fossir.web.flask.util import url_for
from fossir.web.menu import SideMenuItem

logger = Logger.get('events.registration')

registration_settings = RegistrationSettingsProxy(
    'registrations',
    {
        # Whether to merge display forms on the participant list
        'merge_registration_forms': True,
        # Columns to show on the participant list when the registration forms are merged
        'participant_list_columns': ['first_name', 'last_name', 'affiliation'],
        # Order of the forms to show on the participant list
        'participant_list_forms': [],
        # Columns to show for each form on the participant list
        'participant_list_form_columns': {}
    })

예제 #26
0
from __future__ import unicode_literals

from flask import flash, session

from fossir.core import signals
from fossir.core.logger import Logger
from fossir.core.roles import ManagementRole, check_roles
from fossir.modules.events.sessions.models.sessions import Session
from fossir.modules.events.sessions.util import has_sessions_for_user
from fossir.modules.events.settings import EventSettingsProxy
from fossir.util.i18n import _, ngettext
from fossir.web.flask.util import url_for
from fossir.web.menu import SideMenuItem


logger = Logger.get('events.sessions')
session_settings = EventSettingsProxy('sessions', {
    # Whether session coordinators can manage contributions inside their sessions
    'coordinators_manage_contributions': False,
    # Whether session coordinators can manage their session blocks
    'coordinators_manage_blocks': False
})


COORDINATOR_PRIV_SETTINGS = {'manage-contributions': 'coordinators_manage_contributions',
                             'manage-blocks': 'coordinators_manage_blocks'}
COORDINATOR_PRIV_TITLES = {'manage-contributions': _('Contributions'),
                           'manage-blocks': _('Session blocks')}
COORDINATOR_PRIV_DESCS = {'manage-contributions': _('Allows coordinators to modify contributions in their sessions.'),
                          'manage-blocks': _('Allows coordinators to manage/reschedule session blocks of their '
                                             'sessions.  This includes creating new session blocks..')}
예제 #27
0
from fossir.core import signals
from fossir.core.logger import Logger
from fossir.core.roles import ManagementRole
from fossir.modules.events.abstracts.clone import AbstractSettingsCloner
from fossir.modules.events.abstracts.notifications import ContributionTypeCondition, StateCondition, TrackCondition
from fossir.modules.events.features.base import EventFeature
from fossir.modules.events.models.events import Event, EventType
from fossir.modules.events.timetable.models.breaks import Break
from fossir.util.i18n import _
from fossir.util.placeholders import Placeholder
from fossir.web.flask.templating import template_hook
from fossir.web.flask.util import url_for
from fossir.web.menu import SideMenuItem


logger = Logger.get('events.abstracts')


@signals.event.updated.connect
@signals.event.contribution_created.connect
@signals.event.contribution_updated.connect
@signals.event.contribution_deleted.connect
@signals.event.session_deleted.connect
@signals.event.session_updated.connect
@signals.event.person_updated.connect
@signals.event.times_changed.connect
def _clear_boa_cache(sender, obj=None, **kwargs):
    from fossir.modules.events.abstracts.util import clear_boa_cache
    if isinstance(obj, Break):
        # breaks do not show up in the BoA
        return
예제 #28
0
from __future__ import unicode_literals

from flask import flash, session

from fossir.core import signals
from fossir.core.logger import Logger
from fossir.core.roles import ManagementRole, check_roles
from fossir.modules.events.contributions.contrib_fields import get_contrib_field_types
from fossir.modules.events.contributions.models.contributions import Contribution
from fossir.modules.events.contributions.models.fields import ContributionField
from fossir.util.i18n import _, ngettext
from fossir.web.flask.util import url_for
from fossir.web.menu import SideMenuItem

logger = Logger.get('events.contributions')


@signals.menu.items.connect_via('event-management-sidemenu')
def _extend_event_management_menu(sender, event, **kwargs):
    if not event.can_manage(session.user):
        return
    if event.type == 'conference':
        return SideMenuItem('contributions',
                            _('Contributions'),
                            url_for('contributions.manage_contributions',
                                    event),
                            section='organization')


@signals.users.merged.connect
def _merge_users(target, source, **kwargs):
예제 #29
0
 def delete(self, key):
     self._connect()
     Logger.get('cache.generic').debug('DEL %s %r', self._namespace, key)
     self._client.delete(self._makeKey(key))
예제 #30
0
from __future__ import unicode_literals

from flask import session

from fossir.core import signals
from fossir.core.logger import Logger
from fossir.core.settings import SettingsProxy
from fossir.util.i18n import _
from fossir.web.flask.util import url_for
from fossir.web.menu import SideMenuItem

logger = Logger.get('news')

news_settings = SettingsProxy(
    'news',
    {
        # Whether to show the recent news on the home page
        'show_recent': True,
        # The number of recent news to show on the home page
        'max_entries': 3,
        # How old a news may be to be shown on the home page
        'max_age': 0,
        # How long a news is labelled as 'new'
        'new_days': 14
    })


@signals.menu.items.connect_via('admin-sidemenu')
def _sidemenu_items(sender, **kwargs):
    if session.user.is_admin:
        yield SideMenuItem('news',