Exemplo n.º 1
0
    def _getParams(self):
        self._offset = get_query_parameter(self._queryParams, ['O', 'offset'], 0, integer=True)
        if self._offset < 0:
            raise HTTPAPIError('Offset must be a positive number', 400)
        self._orderBy = get_query_parameter(self._queryParams, ['o', 'order'])
        self._descending = get_query_parameter(self._queryParams, ['c', 'descending'], 'no') == 'yes'
        self._detail = get_query_parameter(self._queryParams, ['d', 'detail'], self.DEFAULT_DETAIL)
        tzName = get_query_parameter(self._queryParams, ['tz'], None)

        if tzName is None:
            tzName = config.DEFAULT_TIMEZONE
        try:
            self._tz = pytz.timezone(tzName)
        except pytz.UnknownTimeZoneError as e:
            raise HTTPAPIError("Bad timezone: '%s'" % e.message, 400)
        max = self.MAX_RECORDS.get(self._detail, 1000)
        self._userLimit = get_query_parameter(self._queryParams, ['n', 'limit'], 0, integer=True)
        if self._userLimit > max:
            raise HTTPAPIError("You can only request up to %d records per request with the detail level '%s'" %
                               (max, self._detail), 400)
        self._limit = self._userLimit if self._userLimit > 0 else max

        fromDT = get_query_parameter(self._queryParams, ['f', 'from'])
        toDT = get_query_parameter(self._queryParams, ['t', 'to'])
        dayDT = get_query_parameter(self._queryParams, ['day'])

        if (fromDT or toDT) and dayDT:
            raise HTTPAPIError("'day' can only be used without 'from' and 'to'", 400)
        elif dayDT:
            fromDT = toDT = dayDT

        self._fromDT = DataFetcher._getDateTime('from', fromDT, self._tz) if fromDT else None
        self._toDT = DataFetcher._getDateTime('to', toDT, self._tz, aux=self._fromDT) if toDT else None
Exemplo n.º 2
0
    def __call__(self, user):
        """Perform the actual exporting"""
        if self.HTTP_POST != (request.method == 'POST'):
            raise HTTPAPIError(
                'This action requires %s' %
                ('POST' if self.HTTP_POST else 'GET'), 405)
        if not self.GUEST_ALLOWED and not user:
            raise HTTPAPIError('Guest access to this resource is forbidden.',
                               403)

        method_name = self._getMethodName()
        func = getattr(self, method_name, None)
        extra_func = getattr(self, method_name + '_extra', None)
        if not func:
            raise NotImplementedError(method_name)

        if not self.COMMIT:
            is_response, resultList, complete, extra = self._perform(
                user, func, extra_func)
            db.session.rollback()
        else:
            try:
                init_email_queue()
                is_response, resultList, complete, extra = self._perform(
                    user, func, extra_func)
                db.session.commit()
                flush_email_queue()
            except Exception:
                db.session.rollback()
                raise
        if is_response:
            return resultList
        return resultList, extra, complete, self.SERIALIZER_TYPE_MAP
Exemplo n.º 3
0
def checkAK(apiKey, signature, timestamp, path, query):
    apiMode = api_settings.get('security_mode')
    if not apiKey:
        if apiMode in {
                APIMode.ONLYKEY, APIMode.ONLYKEY_SIGNED, APIMode.ALL_SIGNED
        }:
            raise HTTPAPIError('API key is missing', 403)
        return None, True
    try:
        UUID(hex=apiKey)
    except ValueError:
        raise HTTPAPIError('Malformed API key', 400)
    ak = APIKey.find_first(token=apiKey, is_active=True)
    if not ak:
        raise HTTPAPIError('Invalid API key', 403)
    if ak.is_blocked:
        raise HTTPAPIError('API key is blocked', 403)
    # Signature validation
    onlyPublic = False
    if signature:
        validateSignature(ak, signature, timestamp, path, query)
    elif apiMode == APIMode.ALL_SIGNED:
        raise HTTPAPIError('Signature missing', 403)
    elif apiMode in {APIMode.SIGNED, APIMode.ONLYKEY_SIGNED}:
        onlyPublic = True
    return ak, onlyPublic
Exemplo n.º 4
0
 def _getParams(self):
     super()._getParams()
     event = self._obj = Event.get(self._pathParams['event_id'],
                                   is_deleted=False)
     if event is None:
         raise HTTPAPIError('No such event', 404)
     session_id = self._pathParams.get('session_id')
     if session_id:
         self._obj = Session.query.with_parent(event).filter_by(
             id=session_id).first()
         if self._obj is None:
             raise HTTPAPIError("No such session", 404)
     contribution_id = self._pathParams.get('contribution_id')
     if contribution_id:
         contribution = self._obj = (
             Contribution.query.with_parent(event).filter_by(
                 id=contribution_id, is_deleted=False).first())
         if contribution is None:
             raise HTTPAPIError("No such contribution", 404)
         subcontribution_id = self._pathParams.get('subcontribution_id')
         if subcontribution_id:
             self._obj = SubContribution.query.with_parent(
                 contribution).filter_by(id=subcontribution_id,
                                         is_deleted=False).first()
             if self._obj is None:
                 raise HTTPAPIError("No such subcontribution", 404)
     self._note = EventNote.get_for_linked_object(self._obj,
                                                  preload_event=False)
     if self._note is None or self._note.is_deleted:
         raise HTTPAPIError("No such note", 404)
Exemplo n.º 5
0
 def _getParams(self):
     super(NoteExportHook, self)._getParams()
     event = self._obj = ConferenceHolder().getById(
         self._pathParams['event_id'], True)
     if event is None:
         raise HTTPAPIError('No such event', 404)
     session_id = self._pathParams.get('session_id')
     if session_id:
         session = self._obj = event.getSessionById(session_id)
         if session is None:
             raise HTTPAPIError("No such session", 404)
     contribution_id = self._pathParams.get('contribution_id')
     if contribution_id:
         contribution = self._obj = event.getContributionById(
             contribution_id)
         if contribution is None:
             raise HTTPAPIError("No such contribution", 404)
     subcontribution_id = self._pathParams.get('subcontribution_id')
     if subcontribution_id:
         subcontribution = self._obj = contribution.getSubContributionById(
             subcontribution_id)
         if subcontribution is None:
             raise HTTPAPIError("No such subcontribution", 404)
     self._note = EventNote.get_for_linked_object(self._obj)
     if self._note is None or self._note.is_deleted:
         raise HTTPAPIError("No such note", 404)
Exemplo n.º 6
0
    def _getParams(self):
        super(BookRoomHook, self)._getParams()

        username = get_query_parameter(self._queryParams, ['username'])
        booked_for = AuthenticatorMgr().getAvatarByLogin(username).values()

        if not booked_for:
            raise HTTPAPIError('Username does not exist.')

        self._params = {
            'roomid': get_query_parameter(self._queryParams, ['roomid']),
            'location': get_query_parameter(self._queryParams, ['location']),
            'username': username,
            'reason': get_query_parameter(self._queryParams, ['reason']),
            'userBookedFor': booked_for[0],
            'from': self._fromDT,
            'to': self._toDT
            }

        # calculate missing arguments
        missing = list(name for (name, value) in (self._params.iteritems()) if not value)

        if missing:
            raise HTTPAPIError('Argument(s) missing: {0}'.format(', '.join(missing)), apache.HTTP_BAD_REQUEST)

        self._room = CrossLocationQueries.getRooms(location=self._params['location'], roomID=int(self._params['roomid']))
Exemplo n.º 7
0
    def api_roomBooking(self, aw):
        resv = CrossLocationFactory.newReservation(location=self._params['location'])
        resv.room = self._room
        resv.startDT = self._fromDT.replace(tzinfo=None)
        resv.endDT = self._toDT.replace(tzinfo=None)

        # checking room availability
        for nbd in resv.room.getNonBookableDates():
            if (doesPeriodOverlap(nbd.getStartDate(), nbd.getEndDate(), resv.startDT, resv.endDT)):
                raise HTTPAPIError('Failed to create the booking. You cannot book this room because it is unavailable during this time period.')

        roomBlocked = resv.room.getBlockedDay(resv.startDT)

        # checking room blocking
        if roomBlocked and not roomBlocked.block.canOverride(self._user):
            raise HTTPAPIError('Failed to create the booking. You cannot book this room because it is blocked during this time period.')

        resv.repeatability = None
        resv.reason = self._params['reason']
        resv.createdDT = datetime.now()
        resv.createdBy = str(self._user.getId())
        resv.bookedForName = self._params['userBookedFor'].getFullName()
        resv.contactEmail = self._params['userBookedFor'].getEmail()
        resv.contactPhone = self._params['userBookedFor'].getTelephone()
        resv.isRejected = False
        resv.isCancelled = False
        resv.isConfirmed = True

        if resv.getCollisions():
            raise HTTPAPIError('Failed to create the booking. There is a collision with another booking.')

        resv.insert()

        return {'reservationID': resv.id}
Exemplo n.º 8
0
 def export_user(self, user):
     if not user:
         raise HTTPAPIError('You need to be logged in', 403)
     user = User.get(self._user_id, is_deleted=False)
     if not user:
         raise HTTPAPIError('Requested user not found', 404)
     if not user.can_be_modified(user):
         raise HTTPAPIError('You do not have access to that info', 403)
     return [user.as_avatar.fossilize()]
Exemplo n.º 9
0
def validateSignature(ak, signature, timestamp, path, query):
    ttl = api_settings.get('signature_ttl')
    if not timestamp and not (ak.is_persistent_allowed and api_settings.get('allow_persistent')):
        raise HTTPAPIError('Signature invalid (no timestamp)', 403)
    elif timestamp and abs(timestamp - int(time.time())) > ttl:
        raise HTTPAPIError('Signature invalid (bad timestamp)', 403)
    digest = hmac.new(ak.secret, normalizeQuery(path, query), hashlib.sha1).hexdigest()
    if signature != digest:
        raise HTTPAPIError('Signature invalid', 403)
Exemplo n.º 10
0
def validateSignature(ak, minfo, signature, timestamp, path, query):
    ttl = HelperMaKaCInfo.getMaKaCInfoInstance().getAPISignatureTTL()
    if not timestamp and not (ak.isPersistentAllowed() and minfo.isAPIPersistentAllowed()):
        raise HTTPAPIError('Signature invalid (no timestamp)', apache.HTTP_FORBIDDEN)
    elif timestamp and abs(timestamp - int(time.time())) > ttl:
        raise HTTPAPIError('Signature invalid (bad timestamp)', apache.HTTP_FORBIDDEN)
    digest = hmac.new(ak.getSignKey(), normalizeQuery(path, query), hashlib.sha1).hexdigest()
    if signature != digest:
        raise HTTPAPIError('Signature invalid', apache.HTTP_FORBIDDEN)
Exemplo n.º 11
0
 def _getParams(self):
     super(AgreementExportHook, self)._getParams()
     type_ = self._pathParams['agreement_type']
     try:
         self._definition = get_agreement_definitions()[type_]
     except KeyError:
         raise HTTPAPIError('No such agreement type', 404)
     self.event = Event.get(self._pathParams['event_id'], is_deleted=False)
     if self.event is None:
         raise HTTPAPIError('No such event', 404)
Exemplo n.º 12
0
 def export_user(self, aw):
     requested_user = AvatarHolder().getById(self._user_id)
     user = aw.getUser()
     if not requested_user:
         raise HTTPAPIError('Requested user not found', 404)
     if user:
         if requested_user.canUserModify(user):
             return [requested_user.fossilize()]
         raise HTTPAPIError('You do not have access to that info', 403)
     raise HTTPAPIError('You need to be logged in', 403)
Exemplo n.º 13
0
 def _getParams(self):
     super(AgreementExportHook, self)._getParams()
     type_ = self._pathParams['agreement_type']
     try:
         self._definition = get_agreement_definitions()[type_]
     except KeyError:
         raise HTTPAPIError('No such agreement type', 404)
     self._event = ConferenceHolder().getById(self._pathParams['event_id'], True)
     if self._event is None:
         raise HTTPAPIError('No such event', 404)
Exemplo n.º 14
0
    def export_user(self, user):
        from indico.modules.users.schemas import UserSchema

        if not user:
            raise HTTPAPIError('You need to be logged in', 403)
        user = User.get(self._user_id, is_deleted=False)
        if not user:
            raise HTTPAPIError('Requested user not found', 404)
        if not user.can_be_modified(user):
            raise HTTPAPIError('You do not have access to that info', 403)
        return [UserSchema().dump(user)]
Exemplo n.º 15
0
    def __call__(self, aw):
        """Perform the actual exporting"""
        if self.HTTP_POST != (request.method == 'POST'):
            raise HTTPAPIError(
                'This action requires %s' %
                ('POST' if self.HTTP_POST else 'GET'), 405)
        if not self.GUEST_ALLOWED and not aw.getUser():
            raise HTTPAPIError('Guest access to this resource is forbidden.',
                               403)

        method_name = self._getMethodName()
        func = getattr(self, method_name, None)
        extra_func = getattr(self, method_name + '_extra', None)
        if not func:
            raise NotImplementedError(method_name)

        if not self.COMMIT:
            is_response, resultList, complete, extra = self._perform(
                aw, func, extra_func)
        else:
            dbi = DBMgr.getInstance()
            try:
                for i, retry in enumerate(transaction.attempts(10)):
                    with retry:
                        if i > 0:
                            dbi.abort()
                        flush_after_commit_queue(False)
                        GenericMailer.flushQueue(False)
                        dbi.sync()
                        try:
                            is_response, resultList, complete, extra = self._perform(
                                aw, func, extra_func)
                            transaction.commit()
                            flush_after_commit_queue(True)
                            GenericMailer.flushQueue(True)
                            break
                        except ConflictError:
                            transaction.abort()
                        except ClientDisconnected:
                            transaction.abort()
                            time.sleep(i * 5)
                else:
                    raise HTTPAPIError(
                        'An unresolvable database conflict has occured', 500)
            except Exception:
                transaction.abort()
                raise
        if is_response:
            return resultList
        return resultList, extra, complete, self.SERIALIZER_TYPE_MAP
Exemplo n.º 16
0
    def _getParams(self):
        super(BookRoomHook, self)._getParams()
        self._fromDT = utc_to_server(self._fromDT.astimezone(pytz.utc)).replace(tzinfo=None) if self._fromDT else None
        self._toDT = utc_to_server(self._toDT.astimezone(pytz.utc)).replace(tzinfo=None) if self._toDT else None
        if not self._fromDT or not self._toDT or self._fromDT.date() != self._toDT.date():
            raise HTTPAPIError('from/to must be on the same day')
        elif self._fromDT >= self._toDT:
            raise HTTPAPIError('to must be after from')
        elif self._fromDT < datetime.now():
            raise HTTPAPIError('You cannot make bookings in the past')

        username = get_query_parameter(self._queryParams, 'username')
        if not username:
            raise HTTPAPIError('No username provided')
        users = User.query.join(User.identities).filter(~User.is_deleted, Identity.identifier == username).all()
        if not users:
            raise HTTPAPIError('Username does not exist')
        elif len(users) != 1:
            raise HTTPAPIError('Ambiguous username ({} users found)'.format(len(users)))
        user = users[0]

        self._params = {
            'room_id': get_query_parameter(self._queryParams, 'roomid'),
            'reason': get_query_parameter(self._queryParams, 'reason'),
            'booked_for': user,
            'from': self._fromDT,
            'to': self._toDT
        }
        missing = [key for key, val in self._params.iteritems() if not val]
        if missing:
            raise HTTPAPIError('Required params missing: {}'.format(', '.join(missing)))
        self._room = Room.get(self._params['room_id'])
        if not self._room:
            raise HTTPAPIError('A room with this ID does not exist')
Exemplo n.º 17
0
    def api_recordingManager(self, aw):
        if not self._indicoID or not self._cdsID:
            raise HTTPAPIError('A required argument is missing.',
                               apache.HTTP_BAD_REQUEST)

        success = createIndicoLink(self._indicoID, self._cdsID)
        return {'success': success}
Exemplo n.º 18
0
 def _process(self, iterator, filter=None, iface=None):
     if iface is None:
         iface = self.DETAIL_INTERFACES.get(self._detail)
         if iface is None:
             raise HTTPAPIError('Invalid detail level: %s' % self._detail, 400)
     for obj in self._iterateOver(iterator, self._offset, self._limit, self._orderBy, self._descending, filter):
         yield self._postprocess(obj, self._makeFossil(obj, iface), iface)
Exemplo n.º 19
0
 def _getParams(self):
     super(CollaborationExportHook, self)._getParams()
     self._conf = ConferenceHolder().getById(self._pathParams['confId'],
                                             True)
     if not self._conf:
         raise HTTPAPIError('Conference does not exist.',
                            apache.HTTP_BAD_REQUEST)
Exemplo n.º 20
0
    def _getParams(self):
        super(FileHook, self)._getParams()

        self._event = self._pathParams['event']
        self._session = self._pathParams['session']
        self._contrib = self._pathParams['contrib']
        self._subcontrib = self._pathParams['subcontrib']
        self._material = self._pathParams['material']
        self._res = self._pathParams['res']

        self._params = {
            'confId': self._event,
            'sessionId': self._session,
            'contribId': self._contrib,
            'subContId': self._subcontrib,
            'materialId': self._material,
            'resId': self._res
        }

        import MaKaC.webinterface.locators as locators
        l = locators.WebLocator()
        try:
            l.setResource(self._params)
            self._file = l.getObject()
        except (KeyError, AttributeError):
            raise HTTPAPIError("File not found", 404)
Exemplo n.º 21
0
    def _getParams(self):
        super()._getParams()

        self._attachment = Attachment.get(int(self._pathParams['res']))

        if not self._attachment:
            raise HTTPAPIError("File not found", 404)
Exemplo n.º 22
0
 def export_linked_events(self, aw):
     if not redis_client:
         raise HTTPAPIError('This API is only available when using Redis')
     self._checkProtection(aw)
     links = avatar_links.get_links(self._avatar.user, self._fromDT,
                                    self._toDT)
     for event_id in get_events_registered(self._avatar.user, self._fromDT,
                                           self._toDT):
         links.setdefault(str(event_id),
                          set()).add('registration_registrant')
     for event_id in get_events_with_submitted_surveys(
             self._avatar.user, self._fromDT, self._toDT):
         links.setdefault(str(event_id), set()).add('survey_submitter')
     for event_id in get_events_managed_by(self._avatar.user, self._fromDT,
                                           self._toDT):
         links.setdefault(str(event_id), set()).add('conference_manager')
     for event_id in get_events_created_by(self._avatar.user, self._fromDT,
                                           self._toDT):
         links.setdefault(str(event_id), set()).add('conference_creator')
     for event_id, principal_roles in get_events_with_linked_sessions(
             self._avatar.user, self._fromDT, self._toDT).iteritems():
         links.setdefault(str(event_id), set()).update(principal_roles)
     for event_id, principal_roles in get_events_with_linked_contributions(
             self._avatar.user, self._fromDT, self._toDT).iteritems():
         links.setdefault(str(event_id), set()).update(principal_roles)
     for event_id in get_events_with_linked_event_persons(
             self._avatar.user, self._fromDT, self._toDT):
         links.setdefault(str(event_id), set()).add('conference_chair')
     return UserRelatedEventFetcher(aw, self, links).events(links.keys())
Exemplo n.º 23
0
 def _checkProtection(self, aw):
     if not self._avatar:
         # No avatar specified => use self. No need to check any permissinos.
         self._avatar = aw.getUser()
         return
     elif not self._avatar.canUserModify(aw.getUser()):
         raise HTTPAPIError('Access denied', 403)
Exemplo n.º 24
0
 def _perform(self, aw, func, extra_func):
     self._getParams()
     if not self._hasAccess(aw):
         raise HTTPAPIError('Access to this resource is restricted.', 403)
     resultList, complete = self._performCall(func, aw)
     extra = extra_func(aw, resultList) if extra_func else None
     return resultList, complete, extra
Exemplo n.º 25
0
 def _hasAccess(self, aw):
     if not Config.getInstance().getIsRoomBookingActive() or not rb_check_user_access(aw.getUser()):
         return False
     if self._room.can_be_booked(aw.getUser()):
         return True
     elif self._room.can_be_prebooked(aw.getUser()):
         raise HTTPAPIError('The API only supports direct bookings but this room only allows pre-bookings.')
     return False
Exemplo n.º 26
0
 def _has_access(self, user):
     if not config.ENABLE_ROOMBOOKING or not rb_check_user_access(user):
         return False
     if self._room.can_book(user):
         return True
     elif self._room.can_prebook(user):
         raise HTTPAPIError('The API only supports direct bookings but this room only allows pre-bookings.')
     return False
Exemplo n.º 27
0
    def _getParams(self):
        self._offset = get_query_parameter(self._queryParams, ['O', 'offset'], 0, integer=True)
        if self._offset < 0:
            raise HTTPAPIError('Offset must be a positive number', 400)
        self._orderBy = get_query_parameter(self._queryParams, ['o', 'order'])
        self._descending = get_query_parameter(self._queryParams, ['c', 'descending'], 'no') == 'yes'
        self._detail = get_query_parameter(self._queryParams, ['d', 'detail'], self.DEFAULT_DETAIL)
        tzName = get_query_parameter(self._queryParams, ['tz'], None)

        self._serverTZ = Config.getInstance().getDefaultTimezone()

        if tzName is None:
            tzName = self._serverTZ
        try:
            self._tz = pytz.timezone(tzName)
        except pytz.UnknownTimeZoneError, e:
            raise HTTPAPIError("Bad timezone: '%s'" % e.message, 400)
Exemplo n.º 28
0
    def __call__(self, aw, req):
        """Perform the actual exporting"""
        if self.HTTP_POST != (req.method == 'POST'):
            raise HTTPAPIError(
                'This action requires %s' %
                ('POST' if self.HTTP_POST else 'GET'),
                apache.HTTP_METHOD_NOT_ALLOWED)
        self._req = req
        self._getParams()
        req = self._req
        if not self.GUEST_ALLOWED and not aw.getUser():
            raise HTTPAPIError('Guest access to this resource is forbidden.',
                               apache.HTTP_FORBIDDEN)
        if not self._hasAccess(aw):
            raise HTTPAPIError('Access to this resource is restricted.',
                               apache.HTTP_FORBIDDEN)

        func = getattr(self, self.PREFIX + '_' + self._type, None)
        if not func:
            raise NotImplementedError(self.PREFIX + '_' + self._type)

        if not self.COMMIT:
            # Just execute the function, we'll never have to repeat it
            resultList, complete = self._performCall(func, aw)
        else:
            # Try it a few times until commit succeeds
            dbi = DBMgr.getInstance()
            for _retry in xrange(10):
                dbi.sync()
                resultList, complete = self._performCall(func, aw)
                try:
                    dbi.commit()
                except ConflictError:
                    pass  # retry
                else:
                    break
            else:
                raise HTTPAPIError(
                    'An unresolvable database conflict has occured',
                    apache.HTTP_INTERNAL_SERVER_ERROR)

        extraFunc = getattr(self, self.PREFIX + '_' + self._type + '_extra',
                            None)
        extra = extraFunc(aw, resultList) if extraFunc else None
        return resultList, extra, complete, self.SERIALIZER_TYPE_MAP
Exemplo n.º 29
0
 def _getParams(self):
     super(UserEventHook, self)._getParams()
     self._avatar = None
     # User-specified avatar
     userId = get_query_parameter(self._queryParams, ['uid', 'userid'])
     if userId is not None:
         self._avatar = AvatarHolder().getById(userId)
         if not self._avatar:
             raise HTTPAPIError('Avatar does not exist')
Exemplo n.º 30
0
 def _perform(self, user, func, extra_func):
     self._getParams()
     if not self._has_access(user):
         raise HTTPAPIError('Access to this resource is restricted.', 403)
     resultList, complete = self._performCall(func, user)
     if isinstance(resultList, current_app.response_class):
         return True, resultList, None, None
     extra = extra_func(user, resultList) if extra_func else None
     return False, resultList, complete, extra