def add_event(cls, slug, params=None): # Only a validation simulation! Custom events are only tracked on the game site. try: session = cls.game_session_list.get_session(params['gameSessionId']) except (KeyError, TypeError): raise BadRequest('Invalid game session id') game = session.game if game is None: raise ApiException('No game with that slug') if slug != game.slug: raise BadRequest('Slug and game session do not match') try: event_key = params['key'] except (TypeError, KeyError): raise BadRequest('Event key missing') try: event_value = params['value'] except (TypeError, KeyError): raise BadRequest('Event value missing') del params['value'] try: event_key, event_value = _validate_event(event_key, event_value) except ValueError as e: raise BadRequest(e.message) # If reaches this point, assume success return {'ok': True, 'data': {'msg': 'Added "' + str(event_value) + '" for "' + event_key + '" ' \ '(Simulation only - Custom events are only tracked on the game site)'}}
def get_size(default_size, max_size): try: size = int(params.get('size', default_size)) if size <= 0 or size > max_size: raise BadRequest('size must be a positive integer smaller than %d' % max_size) except ValueError: raise BadRequest('size must be a positive integer smaller than %d' % max_size) return size
def _validate_access(self, access): try: access = int(access) except ValueError: raise BadRequest('Access level invalid. Access must be an integer.') if access not in self.valid_access_levels: raise BadRequest('Access level invalid. Must be one of %s' % str(self.valid_access_levels)) return access
def get(self, user, key): with self.lock: self.datashare_access(user) if not isinstance(key, unicode): raise BadRequest('Key must be a string') if not self.validate_key.match(key): raise BadRequest('Key can only contain alphanumeric characters hyphens and dots') return self.store.get(key)
def add_event_batch(cls, slug, params=None): # Only a validation simulation! Custom events are only tracked on the game site. try: session = cls.game_session_list.get_session(params['gameSessionId']) except (KeyError, TypeError): raise BadRequest('Invalid game session id') game = session.game if game is None: raise ApiException('No game with that slug') if slug != game.slug: raise BadRequest('Slug and game session do not match') try: event_batch = params['batch'] except (TypeError, KeyError): raise BadRequest('Event batch missing') del params['batch'] if not isinstance(event_batch, list): raise BadRequest('Event batch must be an array of events') for event in event_batch: try: event_key = event['key'] except (TypeError, KeyError): raise BadRequest('Event key missing') try: event_value = event['value'] except (TypeError, KeyError): raise BadRequest('Event value missing') try: event_key, event_value = _validate_event(event_key, event_value) except ValueError as e: raise BadRequest(e.message) try: event_time = float(event['timeOffset']) except (TypeError, KeyError): raise BadRequest('Event time offset missing') except ValueError: raise BadRequest('Event time offset should be a float') if event_time > 0: raise BadRequest('Event time offsets should be <= 0 to represent older events') # If reaches this point, assume success return {'ok': True, 'data': {'msg': 'Added %d events ' \ '(Simulation only - Custom events are only tracked on the game site)' % len(event_batch)}}
def compare_and_set(self, user, key, value, token): with self.lock: self.datashare_access(user) key = str(key) if not self.validate_key.match(key): raise BadRequest('Key can only contain alphanumeric characters hyphens and dots') if key in self.store: key_store = self.store[key] if key_store['access'] != self.read_and_write: raise Forbidden('Forbidden: Key "%s" is read only access (must use set for read only keys)' % key, {'reason': 'read_only'}) owner = key_store['ownedBy'] # if the key is in the store then check its token if key_store['token'] != token: raise CompareAndSetInvalidToken() else: owner = user.username # if the key is missing from the store make sure the token is unset if token: raise CompareAndSetInvalidToken() return self._set(key, value, owner, self.read_and_write)
def _get_gamesession(cls, params): """ Get the user id and project version id for this game session """ try: session = cls.game_session_list.get_session( params['gameSessionId']) except KeyError: raise BadRequest('Request is missing gameSessionId parameter') if session is None: raise InvalidGameSession('No gamesession with that id') return session
def set_properties(cls, slug, datashare_id, params=None): game = get_game_by_slug(slug) datashare = DataShareList.get(game).get(datashare_id) if 'joinable' in params: try: joinable = asbool(params['joinable']) except ValueError: raise BadRequest('Joinable must be a boolean value') datashare.set_joinable(get_current_user(), joinable) return {'ok': True}
def login(cls): username = request.params.get('username') try: login_user(str(username).lower()) except UnicodeEncodeError: raise BadRequest( 'Username "%s" is invalid. ' 'Usernames can only contain alphanumeric and hyphen characters.' % username) return {'ok': True}
def cancel_notification_by_id(cls, slug): game = _get_game(slug) _id = request.POST.get('id') if not _id: raise BadRequest('No task-id given') GameNotificationTaskListManager.cancel_notification_by_id(game, _id) return { 'ok': True }
def get_user(self, username): username_lower = username.lower() with self.lock: try: return self.users[username_lower] except KeyError: LOG.info('No user with username "%s" adding user with defaults', username) try: user = self._add_user(username_lower) self._write_users() return user except ValueError as e: raise BadRequest(str(e))
def cancel_notification_by_key(cls, slug): game = _get_game(slug) user = _get_user_name() key = request.POST.get('key') if not key: raise BadRequest('No task-key given') GameNotificationTaskListManager.cancel_notification_by_key(game, user, key) return {'ok': True}
def login_user(self, username_lower): with self.lock: if username_lower in self.users: user = self.users[username_lower] else: try: user = self._add_user(username_lower) self._write_users() except ValueError as e: raise BadRequest(str(e)) # 315569260 seconds = 10 years response.set_cookie('local', username_lower, httponly=False, max_age=315569260) return user
def read_notification_keys(cls, slug): game = _get_game(slug) try: return { 'ok': True, 'data': { 'keys': GameNotificationKeysList.get(game).to_dict() } } except GameNotificationsUnsupportedException: return {'ok': True, 'data': {'items': {}, 'resources': {}}} except ValidationException as e: raise BadRequest(str(e))
def _get_task_data(cls, slug): game = _get_game(slug) user = _get_user_name() try: data = _json_decoder.decode(request.POST['data']) except KeyError: raise BadRequest('Missing parameter "data"') except JSONDecodeError as e: raise BadRequest('Data-parameter JSON error: %s' % str(e)) if not isinstance(data, dict): raise BadRequest('Data-parameter is not a dict') # pylint: disable=E1103 get_data = data.get # pylint: enable=E1103 key = get_data('key') if not key: raise BadRequest('No notification-key given') ## check that the key actually exists on the game if key not in GameNotificationKeysList.get(game).to_dict(): raise BadRequest('Unknown key "' + key + '" given.') msg = get_data('msg') if not msg: raise BadRequest('No message given') if not msg.get('text'): raise BadRequest('No text-attribute in msg') try: delay = int(get_data('time') or 0) except ValueError: raise BadRequest('Incorrect format for time') ## filter out empty strings and if there's just nothing there, use the current user as default recipient recipient = get_data('recipient', '').strip() or user return create_id(), key, user, recipient, msg, game, delay
def _add(cls, slug, task_id, key, sender, recipient, msg, send_time, game): try: task = GameNotificationTask(slug, task_id, key, sender, recipient, msg, send_time) if GameNotificationTaskListManager.add_task(game, task): return { 'ok': True, 'id': task_id } response.status_int = 429 return { 'ok': False, 'msg': 'limit exceeded.' } except (GameNotificationTaskError, GameNotificationPathError) as e: raise BadRequest('NotificationTask could not be saved: %s' % str(e))
def set(self, user, key, value): with self.lock: self.datashare_access(user) key = str(key) if not self.validate_key.match(key): raise BadRequest('Key can only contain alphanumeric characters hyphens and dots') if key in self.store: key_store = self.store[key] if key_store['access'] != self.read_only: raise Forbidden('Forbidden: Key "%s" is read and write access' '(must use compare and set for read and write keys)' % key, {'reason': 'read_and_write'}) owner = key_store['ownedBy'] if owner != user.username: raise Forbidden('Forbidden: Key "%s" is read only' % key, {'reason': 'read_only'}) else: owner = user.username return self._set(key, value, owner, self.read_only)