simplesamlphp/assert
Fork of webmozart/assert that lets every assertion throw your chosen exception (or a default AssertionFailedException) instead of always InvalidArgumentException. Adds a few custom assertions aimed at XML/SAML2 use cases.
## Technical Evaluation
### **Architecture Fit**
- **Purpose Alignment**:
The package (`simplesamlphp/assert`) remains aligned with domain-specific validation for **SAML/SSO, authentication flows, or security-sensitive data**, particularly with the new **enum support** (v1.5.0) enhancing validation granularity. This is valuable for Laravel apps handling **structured data validation** (e.g., SAML attributes, OAuth scopes, or custom enums in API payloads). The **stricter regex handling** (#16) also improves robustness for **multi-line or malformed inputs**, critical for XML/SAML parsing.
- **Laravel Ecosystem Fit**:
- **Incremental Value**: The new enum support bridges a gap for Laravel apps using **enums in validation** (e.g., `Laravel\Sanctum\PersonalAccessToken` scopes or custom SAML attribute mappings). While Laravel’s `Validator` handles enums via `Rule::enum()`, this package offers **domain-specific enum validation** (e.g., validating SAML `NameID` formats as enums).
- **Overlap Mitigation**: The package’s **static methods** can coexist with Laravel’s validation by acting as **pre-checks** (e.g., validate SAML response structure with `Assert::validSAMLResponse()`, then use Laravel’s `Validator` for form data).
- **Design Philosophy**:
- The **fluent, expressive API** remains unchanged, but the **enum support** adds flexibility for **type-safe validation**. The stricter regex handling reduces false positives in **signature/token validation**, aligning with Laravel’s security-first approach.
- **Trade-off**: Still requires **manual integration** (no Laravel-specific hooks), but the new features reduce boilerplate for complex validations.
### **Integration Feasibility**
- **Dependencies**:
- No breaking changes to `webmozart/assert` (≥1.14.0). The new features are **additive**.
- **PHP 8.1+** compatibility remains intact (Laravel 10/11’s baseline).
- **API Surface**:
- **New Features**:
- **Enum Validation**: Useful for validating **fixed sets of values** (e.g., SAML `AuthnContext` classes or OAuth `grant_types`).
```php
Assert::enum($value, [AuthContext::PASSWORD, AuthContext::SAML]);
```
- **Stricter Regex**: Prevents **newline injection** in inputs (e.g., SAML metadata or JWT payloads), critical for security.
- **Usage Scenarios**:
- **Service Layer**: Validate enums in `AuthService::validateSAMLAttributes()`.
- **Form Requests**: Extend Laravel’s `rules()` with custom enum checks.
- **Middleware**: Reject malformed enums early (e.g., `ValidateSAMLContextMiddleware`).
- **Testing**:
- The package’s **PHPUnit tests** now cover enums/regex, but Laravel’s **Pest/Laravel Tests** would need updates to verify integration (e.g., testing enum validation in API endpoints).
### **Technical Risk**
- **Low Risk**:
- **Backward Compatibility**: No breaking changes; new features are additive.
- **Performance**: Enum checks and stricter regex add **negligible overhead** for most use cases.
- **Medium Risk**:
- **Enum Customization**: If the app’s enums **don’t align** with the package’s design (e.g., dynamic enums), custom wrappers may be needed.
- **Regex Strictness**: The **newline-disallowing regex** (#16) could **break existing validations** if inputs historically contained newlines (e.g., multi-line SAML descriptions). Requires **input sanitization** before assertion.
- **High Risk**:
- **Security**: The stricter regex **hardens input validation** but could **reject legitimate inputs** if not configured properly. Must be **paired with Laravel’s `trim()`/`sanitize()`** where needed.
- **Maintenance**: The package remains **unmaintained** (last release in 2024). The new features suggest **some activity**, but long-term viability is still uncertain.
### **Key Questions**
1. **Use Case Justification**:
- Does the app use **enums in security-sensitive validation** (e.g., SAML attributes, OAuth scopes)?
- Are there **multi-line inputs** (e.g., SAML metadata, XML payloads) that could be affected by the stricter regex?
2. **Alternatives**:
- Can Laravel’s `Rule::enum()` or `Validator::extend()` handle enum validation without this package?
- Are there **Laravel-specific packages** (e.g., `spatie/laravel-enum`) that integrate better with the ecosystem?
3. **Customization Needs**:
- Will the **stricter regex** require adjustments to existing inputs (e.g., trimming newlines before validation)?
- How will **custom enums** be validated if they don’t fit the package’s design?
4. **Long-Term Viability**:
- Should the team **fork the package** to ensure maintenance, or plan a **migration path** to Laravel-native solutions?
- How will **newline-handling** be managed for legacy inputs?
---
## Integration Approach
### **Stack Fit**
- **Laravel Compatibility**:
- **Pros**:
- **Enum Support**: Aligns with Laravel’s **enum usage** (PHP 8.1+) for type-safe validation.
- **Stricter Regex**: Reduces **input injection risks**, complementing Laravel’s security layers.
- **Cons**:
- **No Native Integration**: Still requires **manual wiring** (e.g., service providers, custom rules).
- **Regex Strictness**: May need **pre-processing** (e.g., `trim()`) for legacy inputs.
- **Recommended Stack Layers**:
| Layer | Integration Strategy | Example Use Case |
|---------------------|-----------------------------------------------|-------------------------------------------|
| **Validation Rules** | Extend Laravel’s `Validator` with enum checks. | `Rule::custom('valid_saml_enum', fn($val) => Assert::enum($val, [...]))` |
| **Form Requests** | Use assertions in `rules()` or `authorize()`. | Validate SAML `NameID` formats as enums. |
| **Middleware** | Reject invalid enums/regex early. | `ValidateSAMLContextMiddleware` |
| **Service Layer** | Centralize enum/assertion logic. | `SAMLService::validateResponse()` |
### **Migration Path**
1. **Assessment Phase**:
- Audit **enum usage** in validation (e.g., SAML attributes, OAuth scopes).
- Check for **multi-line inputs** that might break with the stricter regex.
2. **Pilot Integration**:
- Replace **enum validation** in one critical path (e.g., SAML attribute parsing).
- Test **regex strictness** with legacy inputs; add `trim()`/`sanitize()` if needed.
- Example:
```php
// Before (custom logic)
if (!in_array($samlContext, [AuthContext::PASSWORD, AuthContext::SAML])) {
throw new \InvalidArgumentException('Invalid context');
}
// After (using package)
Assert::enum($samlContext, [AuthContext::PASSWORD, AuthContext::SAML]);
```
3. **Full Rollout**:
- Gradually replace **enum and regex validations** across the app.
- **Refactor** custom logic into reusable assertion classes.
4. **Testing**:
- Add **unit tests** for enum/regex validations.
- Update **feature tests** to verify edge cases (e.g., newlines in inputs).
### **Compatibility**
- **Laravel-Specific Considerations**:
- **Enum Integration**: Use `Rule::custom()` to bridge the package with Laravel’s validation:
```php
use simplesamlphp\assert\Assert;
Validator::extend('valid_saml_enum', function ($attribute, $value, $parameters) {
Assert::enum($value, $parameters);
return true;
});
```
- **Regex Handling**: Add **pre-processing middleware** for inputs that may contain newlines:
```php
public function handle($request, Closure $next) {
$request->merge(['saml_metadata' => trim($request->saml_metadata)]);
return $next($request);
}
```
- **Service Container**: Bind assertion classes for DI:
```php
$this->app->bind(SAMLValidator::class, function ($app) {
return new SAMLValidator(new Assert());
});
```
- **Third-Party Packages**:
- **SAML Libraries**: Works with `onelogin/php-saml` for validating `NameID` enums.
- **API Packages**: Compatible with `laravel-sanctum` for validating token scopes as enums.
### **Sequencing**
1. **Phase 1: Enum Validation** (1 sprint)
- Replace **custom enum checks** with `Assert::enum()`.
- Focus on **high-impact areas** (e.g., authentication flows).
2. **Phase 2: Regex Strictness** (1 sprint)
- Audit **multi-line inputs** for regex compatibility.
How can I help you explore Laravel packages today?