<commit_before><?php

class accountActions extends sfActions
{
  // Answer for the registration question (must be lowercase)
  // - accents for spanish style languages :  Tóquio
  // - misspellings : toyko
  // - hiragana : とうきょう
  // 
  //
  const VALID_ANSWERS = '^\s*(t[oō]+u?[ky][kiy][oō]+u?|東京|とうきょう|とき[ょお]|t[óÓ][kq]u?io)\s*$';

  // period to enforce max. registrations (hours)
  const BETWEEN_REGS_TIME = 24;

  // max registrations within period
  const MAX_REGS_BETWEEN_TIME = 2;

  // returns false if max registrations within period has been reached by unique IP
  private function checkMaxRegsWithinPeriod($regip)
  {
    $time = time();
    $ts_since = $time - (60 * 60 * self::BETWEEN_REGS_TIME);

    $regcount = UsersPeer::getRegistrationCount($regip, self::BETWEEN_REGS_TIME);

    return ($regcount < self::MAX_REGS_BETWEEN_TIME);
  }

  public function executeIndex($request)
  {
    $userId = $this->getUser()->getUserId();
//    $this->redirect('account/edit');
    $user = $this->getUser()->getUserDetails();
    $this->forward404If(false === $user);

    $this->user = $user;
    $this->flashcard_count  = ReviewsPeer::getFlashcardCount($userId);
    $this->reviewed_count   = ReviewsPeer::getReviewedFlashcardCount($userId);
    $this->total_reviews    = ReviewsPeer::getTotalReviews($userId);
  }

  /**
   * Create a new account.
   * 
   * @return 
   */
  public function executeCreate($request)
  {
    //$throttler = new RequestThrottler($this->getUser(), 'badbot');
    //$throttler->setInterval(2);
    /*
    if (!$throttler->isValid()) {
      $throttler->setTimeout();
      $response->setContentType('html');
      return $this->renderPartial('misc/requestThrottleError');
    }*/
    
    $sfs = new StopForumSpam();

    // log IPs to investigate bots/spam wasting database space
    $regip = StopForumSpam::getRemoteAddress();

    // limit number of registrations per IP within a period of time
    if (!$this->checkMaxRegsWithinPeriod($regip))
    {
      // save database queries on next requests (needs testing)
      //$throttler->setInterval(60*60): // 1 hour
      //$throttler->setTimeout();

      $sfs->logActivity($regip, 'Too many registrations');

      $this->setLayout(false);
      $this->getResponse()->setStatusCode(403);
      return $this->renderText('Too many registrations within '.self::BETWEEN_REGS_TIME.'h period.');
    }  


    if ($request->getMethod() != sfRequest::POST)
    {
      // setup form

      // development
      /*
      if (CORE_ENVIRONMENT==='dev')
      {
        $request->getParameterHolder()->add(array(
          'username' => '...' . rand(1,1000),
          'email' => '...',
          'password'=>'<PASSWORD>',
          'password2'=>'<PASSWORD>',
          'location'=>'Foo Bar')
        );
      }*/
    }
    else
    {
      $validator = new coreValidator($this->getActionName());
      
      if ($validator->validate($request->getParameterHolder()->getAll()))
      {
        $this->username = trim($request->getParameter('username'));
        $email          = trim($request->getParameter('email'));
        $raw_password   = trim($request->getParameter('password'));
        
        if (UsersPeer::usernameExists($this->username))
        {
          $request->setError('username', 'Sorry, that username is taken, please use another one.');
          return sfView::SUCCESS;
        }

        $answer = trim($request->getParameter('question'));
        

        // log activity of spam bots se we know if there is abuse
        mb_regex_encoding('UTF-8');
        if (true !== mb_ereg_match(self::VALID_ANSWERS, strtolower($answer)))
        {
          if (empty($answer))
          {
            $sfs->logActivity($regip, 'NO answer to the anti-spam question');
            // on va tester un 403 au lieu du 404 (qui semble inciter le bot à doubler la requête)
            $this->getResponse()->setStatusCode(403);

            $request->setError('question', 'Woops, did you forget to answer the question?');
            return sfView::SUCCESS;
          }
          else
          {
            $request->setError('question', 'The answer is not correct, or misspelled.');
            $sfs->logActivity($regip, 'WRONG answer to the anti-spam question ("'.$answer.'")');
            return sfView::SUCCESS;
          }
        }

        // increase of spam from Russia
        if (preg_match('/\.ru$/', $email)) {
          $this->getResponse()->setStatusCode(403);
          return $this->renderText('.ru email address is not accepted (99.99% of these are spam bots)');
        }
<commit_msg>Account creation : misc small tweaks to the question<commit_after><?php

class accountActions extends sfActions
{
  // Answer for the registration question (must be lowercase)
  // - accents for spanish style languages :  Tóquio
  // - misspellings : toyko
  // - hiragana : とうきょう
  // 
  //
  const VALID_ANSWERS = '^(t[oō]+u?[ky]i?[kiy][oō]+u?|東京|とうきょう|とき[ょお]|t[óÓ][kq]u?io)$';

  // period to enforce max. registrations (hours)
  const BETWEEN_REGS_TIME = 24;

  // max registrations within period
  const MAX_REGS_BETWEEN_TIME = 2;

  // returns false if max registrations within period has been reached by unique IP
  private function checkMaxRegsWithinPeriod($regip)
  {
    $time = time();
    $ts_since = $time - (60 * 60 * self::BETWEEN_REGS_TIME);

    $regcount = UsersPeer::getRegistrationCount($regip, self::BETWEEN_REGS_TIME);

    return ($regcount < self::MAX_REGS_BETWEEN_TIME);
  }

  public function executeIndex($request)
  {
    $userId = $this->getUser()->getUserId();
//    $this->redirect('account/edit');
    $user = $this->getUser()->getUserDetails();
    $this->forward404If(false === $user);

    $this->user = $user;
    $this->flashcard_count  = ReviewsPeer::getFlashcardCount($userId);
    $this->reviewed_count   = ReviewsPeer::getReviewedFlashcardCount($userId);
    $this->total_reviews    = ReviewsPeer::getTotalReviews($userId);
  }

  /**
   * Create a new account.
   * 
   * @return 
   */
  public function executeCreate($request)
  {
    //$throttler = new RequestThrottler($this->getUser(), 'badbot');
    //$throttler->setInterval(2);
    /*
    if (!$throttler->isValid()) {
      $throttler->setTimeout();
      $response->setContentType('html');
      return $this->renderPartial('misc/requestThrottleError');
    }*/
    
    $sfs = new StopForumSpam();

    // log IPs to investigate bots/spam wasting database space
    $regip = StopForumSpam::getRemoteAddress();

    // limit number of registrations per IP within a period of time
    if (!$this->checkMaxRegsWithinPeriod($regip))
    {
      // save database queries on next requests (needs testing)
      //$throttler->setInterval(60*60): // 1 hour
      //$throttler->setTimeout();

      $sfs->logActivity($regip, 'Too many registrations');

      $this->setLayout(false);
      $this->getResponse()->setStatusCode(403);
      return $this->renderText('Too many registrations within '.self::BETWEEN_REGS_TIME.'h period.');
    }  


    if ($request->getMethod() != sfRequest::POST)
    {
      // setup form

      // development
      /*
      if (CORE_ENVIRONMENT==='dev')
      {
        $request->getParameterHolder()->add(array(
          'username' => '...' . rand(1,1000),
          'email' => '...',
          'password'=>'<PASSWORD>',
          'password2'=>'<PASSWORD>',
          'location'=>'Foo Bar')
        );
      }*/
    }
    else
    {
      $validator = new coreValidator($this->getActionName());
      
      if ($validator->validate($request->getParameterHolder()->getAll()))
      {
        $this->username = trim($request->getParameter('username'));
        $email          = trim($request->getParameter('email'));
        $raw_password   = trim($request->getParameter('password'));
        
        if (UsersPeer::usernameExists($this->username))
        {
          $request->setError('username', 'Sorry, that username is taken, please use another one.');
          return sfView::SUCCESS;
        }

        mb_regex_encoding('UTF-8');

        // ignore spaces in the answer
        $answer = mb_ereg_replace('\s+', '', $request->getParameter('question', ''));

        // log activity of spam bots se we know if there is abuse
        if (true !== mb_ereg_match(self::VALID_ANSWERS, strtolower($answer)))
        {
          if (empty($answer))
          {
            $sfs->logActivity($regip, 'NO answer to the anti-spam question');
            // on va tester un 403 au lieu du 404 (qui semble inciter le bot à doubler la requête)
            $this->getResponse()->setStatusCode(403);

            $request->setError('question', 'Woops, did you forget to answer the question?');
            return sfView::SUCCESS;
          }
          else
          {
            $request->setError('question', 'Incorrect answer (note: it\'s a city).');
            $sfs->logActivity($regip, 'WRONG answer to the anti-spam question ("'.$answer.'")');
            return sfView::SUCCESS;
          }
        }

        // increase of spam from Russia
        if (preg_match('/\.ru$/', $email)) {
          $this->getResponse()->setStatusCode(403);
          return $this->renderText('.ru email address is not accepted (99.99% of these are spam bots)');
        }

{'fraction_non_alphanumeric': 0.15455035002692516, 'fraction_numerical': 0.009046849757673668, 'mean_word_length': 2.651592607156901, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 111, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4887673', 'n_tokens_mistral': 2912, 'n_tokens_neox': 2837, 'n_words': 612}