-
Notifications
You must be signed in to change notification settings - Fork 1
Closed
Labels
priority:mediumMedium priority issueMedium priority issuestatus:doneCompletedCompletedtype:enhancementNew feature or requestNew feature or request
Description
Summary
Implement comprehensive path-based and pattern-based filter rules for file transfer filtering. This issue completes the filter implementation by adding advanced matching capabilities.
Parent Epic
- Implement bssh-server with SFTP/SCP support #123 - bssh-server 추가 구현
- Depends on: Implement file transfer filtering infrastructure #138 (filter infrastructure)
Implementation Details
1. Extension Matcher
// src/server/filter/pattern.rs
/// Match by file extension
#[derive(Debug, Clone)]
pub struct ExtensionMatcher {
extensions: Vec<String>,
case_sensitive: bool,
}
impl ExtensionMatcher {
pub fn new(extensions: Vec<String>, case_sensitive: bool) -> Self {
let extensions = if case_sensitive {
extensions
} else {
extensions.into_iter().map(|e| e.to_lowercase()).collect()
};
Self { extensions, case_sensitive }
}
}
impl Matcher for ExtensionMatcher {
fn matches(&self, path: &Path) -> bool {
if let Some(ext) = path.extension() {
let ext_str = ext.to_string_lossy();
let ext_cmp = if self.case_sensitive {
ext_str.to_string()
} else {
ext_str.to_lowercase()
};
self.extensions.contains(&ext_cmp)
} else {
false
}
}
fn clone_box(&self) -> Box<dyn Matcher> {
Box::new(self.clone())
}
}2. Size-based Filter
/// Match by file size (requires stat)
#[derive(Debug, Clone)]
pub struct SizeMatcher {
min_size: Option<u64>,
max_size: Option<u64>,
}
impl SizeMatcher {
pub fn new(min: Option<u64>, max: Option<u64>) -> Self {
Self { min_size: min, max_size: max }
}
}
// Note: Size matching requires file metadata, handled differently
pub trait SizeAwareFilter: TransferFilter {
fn check_with_size(
&self,
path: &Path,
size: u64,
operation: Operation,
user: &str,
) -> FilterResult;
}3. Composite Matcher
/// Combine multiple matchers with AND/OR logic
#[derive(Debug, Clone)]
pub enum CompositeMatcher {
And(Vec<Box<dyn Matcher>>),
Or(Vec<Box<dyn Matcher>>),
Not(Box<dyn Matcher>),
}
impl Matcher for CompositeMatcher {
fn matches(&self, path: &Path) -> bool {
match self {
CompositeMatcher::And(matchers) => matchers.iter().all(|m| m.matches(path)),
CompositeMatcher::Or(matchers) => matchers.iter().any(|m| m.matches(path)),
CompositeMatcher::Not(matcher) => !matcher.matches(path),
}
}
fn clone_box(&self) -> Box<dyn Matcher> {
Box::new(self.clone())
}
}4. Directory Matcher
/// Match specific directories or patterns in directory path
#[derive(Debug, Clone)]
pub struct DirectoryMatcher {
/// Match if any component of the path contains this directory
directory_name: String,
}
impl DirectoryMatcher {
pub fn new(name: &str) -> Self {
Self { directory_name: name.to_string() }
}
}
impl Matcher for DirectoryMatcher {
fn matches(&self, path: &Path) -> bool {
path.components().any(|c| {
c.as_os_str().to_string_lossy() == self.directory_name
})
}
fn clone_box(&self) -> Box<dyn Matcher> {
Box::new(self.clone())
}
}5. Extended Configuration
filter:
enabled: true
rules:
# Match by extension
- name: "block-executables"
extensions: [exe, sh, bat, ps1]
action: deny
# Match by size (max 100MB for uploads)
- name: "limit-upload-size"
max_size: 104857600
action: deny
operations: [upload]
# Composite rule: deny .env files except in /home
- name: "protect-env-files"
composite:
type: and
matchers:
- pattern: "*.env"
- not:
path_prefix: /home/
action: deny
# Block hidden directories
- name: "block-hidden"
directory: ".git"
action: deny
# Allow specific paths only (whitelist mode)
- name: "whitelist-data"
path_prefix: /data/
action: allowFiles to Create/Modify
| File | Action |
|---|---|
src/server/filter/pattern.rs |
Modify - Add extension, composite matchers |
src/server/filter/path.rs |
Modify - Add directory matcher |
src/server/filter/policy.rs |
Modify - Support composite rules |
src/server/config/types.rs |
Modify - Extended filter config |
Testing Requirements
- Unit test: Extension matching (case sensitivity)
- Unit test: Composite AND/OR/NOT
- Unit test: Directory component matching
- Unit test: Complex rule combinations
Acceptance Criteria
- Extension matcher implementation
- Composite matcher (AND/OR/NOT)
- Directory component matcher
- Size-aware filtering interface
- Extended configuration support
- Tests passing
Metadata
Metadata
Assignees
Labels
priority:mediumMedium priority issueMedium priority issuestatus:doneCompletedCompletedtype:enhancementNew feature or requestNew feature or request