Beispiel #1
0
  def test_purge_expired_tokens(self):
    """ Generate tokens with current time as expiration date/time.
    That is, tokens are expired as soon as they are generated.

    """
    for user in self.users:
      token = generate_user_auth_token(user,
                                       'password hash',
                                       timeout=0)
      auth_token = lookup_user_auth_token(user, token)
      self.assertEqual(None, auth_token)

    # As expired tokens are purged from the DB just before
    # they are generated, the above should leave us with one
    # expired token in the DB
    query = Session.gql("WHERE expire_date <= :1", api.utcnow())
    expired_tokens = query.count()
    self.assertEqual(1, expired_tokens)

    # Generate another token to trigger cache purging which
    # should leave us with no expired sessions in the DB (as
    # this token is generated with a future expiration date.)
    token = generate_user_auth_token('fake user', 'password hash')

    query = Session.gql("WHERE expire_date <= :1", api.utcnow())
    expired_tokens = query.count()
    self.assertEqual(0, expired_tokens)
Beispiel #2
0
def generate_user_auth_token(nick,
                             password,
                             timeout=(14 * 24 * 60 * 60)):
  """ Generates a user authentication token and stores it in the
  database for later retrieval.

  Why store tokens in the database? Because GAE flushes memcache quite
  aggressively and this was causing users to be logged out much more
  frequently than was acceptable.

  """
  # Clear cache of expired tokens
  purge_expired_user_auth_token_keys()

  token = util.hash_generic(util.generate_uuid())
  key = generate_user_auth_token_key(nick, token)
  # Set an expiration date to enable us to purge old, inactive
  # sessions from the database. Cookie expiration dates are what
  # actually govern how long sessions last.
  expire_date = (api.utcnow() +
                 datetime.timedelta(seconds=timeout))
  session = Session(key_name=key,
                    session_data=db.Blob(password.encode("utf-8")),
                    expire_date=expire_date)
  session.put()
  return token
Beispiel #3
0
  def setUp(self):
    self.old_utcnow = api.utcnow
    self.now = api.utcnow()
    self.delta = datetime.timedelta(seconds=api.DEFAULT_TASK_EXPIRE)
    self.old_enabled = settings.QUEUE_ENABLED

    super(QueueTest, self).setUp()

    settings.QUEUE_ENABLED = True
Beispiel #4
0
def lookup_user_auth_token(request):
  """ Look up a user authentication token from the database cache. """

  if not 'data' in request.session:
    return None
  elif request.session.get_expiry_date() <= api.utcnow():
    return None
  else:
    return request.session['data'].decode("utf-8")
Beispiel #5
0
def lookup_user_auth_token(nick, token):
  """ Look up a user authentication token from the database cache. """

  key = generate_user_auth_token_key(nick, token)
  user_auth_token_blob = Session.get_by_key_name(key)
  if not user_auth_token_blob:
    return None
  elif user_auth_token_blob.expire_date <= api.utcnow():
    return None
  else:
    user_auth_token = user_auth_token_blob.session_data.decode("utf-8")
    return user_auth_token
Beispiel #6
0
def api_call(request, format="json"):
  """ the public api

  attempts to validate a request as a valid oauth request then
  builds the appropriate api_user object and tries to dispatch
  to the provided method
  """
  servertime = api.utcnow()
  try:
    kwargs = oauth_util.get_method_kwargs(request)
    json_params = kwargs.pop('json_params', None)
    if json_params:
      parsed = simplejson.loads(json_params)
      # Turn the keys from unicode to str so that they can be used as method
      # parameters.
      kwargs.update(
          dict([(str(k), v) for k, v in parsed.iteritems()]))
    method = kwargs.pop('method', '').replace('.', '_')
    if method == 'presence_send':
      method = 'post'

    if not method:
      raise exception.ApiException(exception.NO_METHOD, "No method specified")


    # Allows us to turn off authentication for testing purposes
    if not settings.API_DISABLE_VERIFICATION:
      api_user = request.user
    else:
      api_user = api.ROOT

    method_ref = api.PublicApi.get_method(method, api_user)
    if not method_ref:
      raise exception.ApiException(exception.INVALID_METHOD,
                         'Invalid method: %s' % method)

    if not api_user:
      raise exception.ApiException(0x00, 'Invalid API user')

    if getattr(api_user, 'legacy', None) and method == 'post':
      kwargs['nick'] = api_user.nick

    rv = method_ref(api_user, **kwargs)
    if rv is None:
      raise exception.ApiException(0x00, 'method %s returned None'%(method))
    return render_api_response(rv, format, servertime=servertime)
  except oauth_util.OAuthError, e:
    exc = exception.ApiException(exception.OAUTH_ERROR, e.message)
    return render_api_response(exc, format)
Beispiel #7
0
def api_call(request, format="json"):
    """ the public api

  attempts to validate a request as a valid oauth request then
  builds the appropriate api_user object and tries to dispatch
  to the provided method
  """
    servertime = api.utcnow()
    try:
        kwargs = oauth_util.get_method_kwargs(request)
        json_params = kwargs.pop('json_params', None)
        if json_params:
            parsed = simplejson.loads(json_params)
            # Turn the keys from unicode to str so that they can be used as method
            # parameters.
            kwargs.update(dict([(str(k), v) for k, v in parsed.iteritems()]))
        method = kwargs.pop('method', '').replace('.', '_')
        if method == 'presence_send':
            method = 'post'

        if not method:
            raise exception.ApiException(exception.NO_METHOD,
                                         "No method specified")

        # Allows us to turn off authentication for testing purposes
        if not settings.API_DISABLE_VERIFICATION:
            api_user = request.user
        else:
            api_user = api.ROOT

        method_ref = api.PublicApi.get_method(method, api_user)
        if not method_ref:
            raise exception.ApiException(exception.INVALID_METHOD,
                                         'Invalid method: %s' % method)

        if not api_user:
            raise exception.ApiException(0x00, 'Invalid API user')

        if getattr(api_user, 'legacy', None) and method == 'post':
            kwargs['nick'] = api_user.nick

        rv = method_ref(api_user, **kwargs)
        if rv is None:
            raise exception.ApiException(0x00,
                                         'method %s returned None' % (method))
        return render_api_response(rv, format, servertime=servertime)
    except oauth_util.OAuthError, e:
        exc = exception.ApiException(exception.OAUTH_ERROR, e.message)
        return render_api_response(exc, format)
Beispiel #8
0
def purge_expired_user_auth_token_keys():
  """ Remove expired tokens from the database. """

  #TODO: Remove hard coded limit
  limit = 10
  try:
    query = Session.gql("WHERE expire_date <= :1", api.utcnow())
    expired_tokens = query.count()
    if expired_tokens:
      db.delete(query.fetch(limit))
      logging.info("Removed %d expired user authentication "
                   "tokens (%d remaining)",
                   min(limit, expired_tokens),
                   max(0, expired_tokens-limit))
  except Exception, e:
    logging.exception('Unhandled exception while removing expired tokens')
Beispiel #9
0
def api_call(request, format="json"):
    """ the public api

  attempts to validate a request as a valid oauth request then
  builds the appropriate api_user object and tries to dispatch
  to the provided method
  """
    servertime = api.utcnow()
    try:
        kwargs = oauth_util.get_method_kwargs(request)
        json_params = kwargs.pop("json_params", None)
        if json_params:
            parsed = simplejson.loads(json_params)
            # Turn the keys from unicode to str so that they can be used as method
            # parameters.
            kwargs.update(dict([(str(k), v) for k, v in parsed.iteritems()]))
        method = kwargs.pop("method", "").replace(".", "_")
        if method == "presence_send":
            method = "post"

        if not method:
            raise exception.ApiNoMethod("No method specified")

        # Allows us to turn off authentication for testing purposes
        if not settings.API_DISABLE_VERIFICATION:
            api_user = request.user
        else:
            api_user = api.ROOT

        method_ref = api.PublicApi.get_method(method, api_user)
        if not method_ref:
            raise exception.ApiInvalidMethod("Invalid method: %s" % method)

        if not api_user:
            raise exception.ApiException("Invalid API user")

        if getattr(api_user, "legacy", None) and method == "post":
            kwargs["nick"] = api_user.nick

        rv = method_ref(api_user, **kwargs)
        if rv is None:
            raise exception.ApiException("method %s returned None" % (method))
        return render_api_response(rv, format, servertime=servertime)
    except oauth_util.OAuthError, e:
        exc = exception.ApiOAuth(e.message)
        return render_api_response(exc, format)
Beispiel #10
0
def purge_expired_user_auth_token_keys():
  """ Remove expired tokens from the database. """

  #TODO: Remove hard coded limit
  limit = 10
  try:
    objs = Session.objects.filter(expire_date__lte=api.utcnow())
    expired_tokens = objs.count()
    if expired_tokens:
      for obj in objs[:limit]:
        obj.delete()
      logging.info("Removed %d expired user authentication "
                   "tokens (%d remaining)",
                   min(limit, expired_tokens),
                   max(0, expired_tokens-limit))
  except Exception, e:
    logging.exception('Unhandled exception while removing expired tokens')
Beispiel #11
0
  def test_settings_upload_avatar(self):
    nick = 'obligated'
    self.login(nick)

    nick = clean.nick(nick)
    old_contact_avatars = api.actor_get_contacts_avatars_since(api.ROOT, nick)
    contacts = api.actor_get_contacts(api.ROOT, nick)
    self.assertEquals(len(old_contact_avatars), len(contacts) + 1)
    old_avatar = api.actor_get(api.ROOT, nick).extra.get('icon',
                                                         'avatar_default')
    start_time = api.utcnow()
    no_contact_avatars = api.actor_get_contacts_avatars_since(api.ROOT, nick,
                                                              since_time=start_time)
    self.assertEquals(len(no_contact_avatars), 0)

    # TODO(teemu): add more tests for different file types (gif and jpg).
    # Alternatively, test those against api.avatar_upload.
    f = open('testdata/test_avatar.jpg')
    r = self.client.post('/user/obligated/settings/photo',
                         {
                           'imgfile': f,
                           '_nonce' :
                              util.create_nonce('obligated', 'change_photo'),
                         })
    r = self.assertRedirectsPrefix(r, '/user/obligated/settings/photo')

    actor_ref = api.actor_get(api.ROOT, nick)
    new_avatar = actor_ref.extra.get('icon', 'avatar_default')
    self.assertNotEquals(old_avatar, new_avatar)
    self.assertTrue(actor_ref.avatar_updated_at >= start_time)
    new_contact_avatars = api.actor_get_contacts_avatars_since(api.ROOT, nick,
                                                               since_time=start_time)
    self.assertEquals(len(new_contact_avatars), 1)
    self.assertEquals(new_contact_avatars.pop().nick, nick)

    self.assertContains(r, 'Avatar uploaded')
    self.assertTemplateUsed(r, 'actor/templates/settings_photo.html')
    self.assertTemplateUsed(r, 'common/templates/flash.html')
Beispiel #12
0
    def test_settings_upload_avatar(self):
        nick = 'obligated'
        self.login(nick)

        nick = clean.nick(nick)
        old_contact_avatars = api.actor_get_contacts_avatars_since(
            api.ROOT, nick)
        contacts = api.actor_get_contacts(api.ROOT, nick)
        self.assertEquals(len(old_contact_avatars), len(contacts) + 1)
        old_avatar = api.actor_get(api.ROOT,
                                   nick).extra.get('icon', 'avatar_default')
        start_time = api.utcnow()
        no_contact_avatars = api.actor_get_contacts_avatars_since(
            api.ROOT, nick, since_time=start_time)
        self.assertEquals(len(no_contact_avatars), 0)

        # TODO(teemu): add more tests for different file types (gif and jpg).
        # Alternatively, test those against api.avatar_upload.
        f = open('testdata/test_avatar.jpg')
        r = self.client.post(
            '/user/obligated/settings/photo', {
                'imgfile': f,
                '_nonce': util.create_nonce('obligated', 'change_photo'),
            })
        r = self.assertRedirectsPrefix(r, '/user/obligated/settings/photo')

        actor_ref = api.actor_get(api.ROOT, nick)
        new_avatar = actor_ref.extra.get('icon', 'avatar_default')
        self.assertNotEquals(old_avatar, new_avatar)
        self.assertTrue(actor_ref.avatar_updated_at >= start_time)
        new_contact_avatars = api.actor_get_contacts_avatars_since(
            api.ROOT, nick, since_time=start_time)
        self.assertEquals(len(new_contact_avatars), 1)
        self.assertEquals(new_contact_avatars.pop().nick, nick)

        self.assertContains(r, 'Avatar uploaded')
        self.assertTemplateUsed(r, 'actor/templates/settings_photo.html')
        self.assertTemplateUsed(r, 'common/templates/flash.html')