Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Limit Number Calls Bundle Laravel Package

avtonom/limit-number-calls-bundle

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require avtonom/limit-number-calls-bundle ~1.1

Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 2/3):

return [
    // ...
    Avtonom\LimitNumberCallsBundle\AvtonomLimitNumberCallsBundle::class => ['all' => true],
    Snc\RedisBundle\SncRedisBundle::class => ['all' => true],
];
  1. Redis Configuration (in config/packages/snc_redis.yaml):

    snc_redis:
        clients:
            default:
                type: predis
                dsn: redis://localhost
                alias: snc_redis_lnc
    
  2. Define Rules (in config/packages/avtonom_limit_number_calls.yaml):

    avtonom_limit_number_calls:
        rules:
            login_attempts:
                time_period: 60000000  # 1 minute in microseconds
                maximum_number: 5
                blocking_duration: 300  # 5 minutes in seconds
                subject_class: App\Entity\User
                subject_method: [getEmail]
    
  3. First Use Case: Check if a user can perform an action (e.g., login) without exceeding limits:

    use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
    
    public function loginAction(AuthorizationCheckerInterface $checker, User $user)
    {
        if (!$checker->isGranted('login_attempts', $user)) {
            throw new \RuntimeException('Too many login attempts. Try again later.', 429);
        }
        // Proceed with login logic...
    }
    

Implementation Patterns

Core Workflow

  1. Rule Definition:

    • Define rules in config/packages/avtonom_limit_number_calls.yaml with:
      • time_period: Window for allowed requests (microseconds).
      • maximum_number: Max allowed requests in time_period.
      • blocking_duration: Lockout duration if exceeded (seconds).
      • subject_class: Entity/class to extract values from (e.g., User).
      • subject_method: Method(s) to fetch unique identifiers (e.g., [getEmail], [getIp, getUserAgent]).
    • Group rules by group (e.g., sms_group) for shared logic.
  2. Integration with Security:

    • Use the Security Voter to enforce rules:
      // Symfony 4+
      if (!$this->authorizationChecker->isGranted('sms_group', $smsRequest)) {
          throw new TooManyRequestsHttpException();
      }
      
    • For custom logic, inject the service:
      $this->container->get('avtonom_limit_number_calls.checker')->check('rule_name', $object);
      
  3. Logging Requests:

    • Manually log requests (e.g., after failed logins) via CLI or service:
      php bin/console avtonom:limit-calls:add login_attempts $user->getEmail()
      
    • Or programmatically:
      $this->container->get('avtonom_limit_number_calls.logger')->log('rule_name', $value);
      
  4. Handling Blocked Requests:

    • Return 429 Too Many Requests for blocked users:
      if (!$checker->isGranted('rule_name', $object)) {
          return new JsonResponse(['error' => 'Too many requests'], 429);
      }
      
  5. Group-Based Rules:

    • Apply multiple rules to a group (e.g., sms_group):
      rules:
          sms_1m_10:
              group: sms_group
              time_period: 60000000
              maximum_number: 10
          sms_1m_1:
              group: sms_group
              time_period: 60000000
              maximum_number: 1
      
    • Check the group in your code:
      $checker->isGranted('sms_group', $smsRequest);
      

Advanced Patterns

  1. Dynamic Rule Loading:

    • Load rules from a database or API by extending the bundle or using a custom loader:
      $rules = $this->fetchRulesFromDatabase();
      $this->container->get('avtonom_limit_number_calls.manager')->setRules($rules);
      
  2. Custom Voter:

    • Extend the voter for complex logic:
      use Avtonom\LimitNumberCallsBundle\Security\Voter\LimitNumberCallsVoter;
      
      class CustomVoter extends LimitNumberCallsVoter {
          protected function supports($attribute, $subject) {
              return $attribute === 'custom_rule' && $subject instanceof CustomEntity;
          }
      }
      
    • Register it in services.yaml:
      services:
          App\Security\CustomVoter:
              tags: [security.voter]
      
  3. Event-Based Logging:

    • Listen to events (e.g., kernel.request) to auto-log requests:
      $this->container->get('avtonom_limit_number_calls.logger')->log('rule_name', $value);
      
  4. Redis Cluster Support:

    • Configure snc_redis for clustering:
      snc_redis:
          clients:
              default:
                  type: predis
                  dsn: redis://cluster-node1:6379,redis://cluster-node2:6379
      

Gotchas and Tips

Pitfalls

  1. Redis Connection Issues:

    • Ensure Redis is running and accessible. Test with:
      php bin/console snc:redis:ping
      
    • If using Docker, ensure ports are mapped correctly (6379:6379).
  2. Microsecond Precision:

    • time_period uses microseconds, not milliseconds. Convert carefully:
      # 1 minute = 60 seconds = 60 * 1,000,000 microseconds
      time_period: 60000000
      
  3. Subject Method Mismatches:

    • If subject_method returns null or invalid data, the rule may fail silently. Validate methods:
      $value = $object->getEmail(); // Ensure this returns a string/unique value
      
  4. Blocking Duration:

    • blocking_duration is in seconds, not microseconds. A value of 600 = 10 minutes.
  5. Rule Overrides:

    • Disabling a rule with enabled: false in config does not remove it from checks. Use null or omit the rule to exclude it entirely.
  6. Symfony Version Compatibility:

    • The bundle is designed for Symfony 2/3. For Symfony 4+, ensure:
      • security.authorization_checker is used (not security.context).
      • Autowiring is configured for services.
  7. Memory Leaks:

    • Redis keys are auto-pruned based on blocking_duration, but monitor memory usage with:
      php bin/console avtonom:limit-calls:status
      

Debugging Tips

  1. Check Blocked Values:

    php bin/console avtonom:limit-calls:status
    
    • Lists all blocked values and their expiry times.
  2. Clear Statistics:

    php bin/console avtonom:limit-calls:clear email@example.com
    
    • Useful for testing or resetting a user’s lock.
  3. Log Manual Requests:

    php bin/console avtonom:limit-calls:add login_attempts user@example.com
    
    • Simulate a request to test rule triggers.
  4. Enable Debugging:

    • Set logging: true in snc_redis config to log Redis operations:
      snc_redis:
          clients:
              default:
                  logging: true
      
  5. Custom Error Handling:

    • Extend the exception class for granular error messages:
      throw new \RuntimeException('Rule "login_attempts" blocked. Retry in ' . $remainingSeconds . ' seconds.', 429);
      

Extension Points

  1. Custom Storage Backend:
    • Extend the Avtonom\LimitNumberCallsBundle\Storage\StorageInterface to use PostgreSQL or Memcached:
      class CustomStorage implements StorageInterface {
          public function increment($key, $ttl) { /* ... */ }
          public function isBlocked($key) { /* ... */ }
      }
      
    • Register it in services.yaml:
      services:
          Avtonom\LimitNumberCallsBundle\Storage\
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui