Browse Source

Adjust rule processing

Owen 5 months ago
parent
commit
874c67345e
1 changed files with 34 additions and 20 deletions
  1. 34 20
      server/routers/badger/verifySession.ts

+ 34 - 20
server/routers/badger/verifySession.ts

@@ -151,12 +151,22 @@ export async function verifyResourceSession(
         }
         }
 
 
         // check the rules
         // check the rules
-        if (
-            resource.applyRules &&
-            (await checkRules(resource.resourceId, clientIp, path))
-        ) {
-            logger.debug("Resource allowed because rules are satisfied");
-            return allowed(res);
+        if (resource.applyRules) {
+            const action = await checkRules(
+                resource.resourceId,
+                clientIp,
+                path
+            );
+
+            if (action == "ACCEPT") {
+                logger.debug("Resource allowed by rule");
+                return allowed(res);
+            } else if (action == "DROP") {
+                logger.debug("Resource denied by rule");
+                return notAllowed(res);
+            }
+
+            // otherwise its undefined and we pass
         }
         }
 
 
         const redirectUrl = `${config.getRawConfig().app.dashboard_url}/auth/resource/${encodeURIComponent(resource.resourceId)}?redirect=${encodeURIComponent(originalRequestURL)}`;
         const redirectUrl = `${config.getRawConfig().app.dashboard_url}/auth/resource/${encodeURIComponent(resource.resourceId)}?redirect=${encodeURIComponent(originalRequestURL)}`;
@@ -456,7 +466,7 @@ async function checkRules(
     resourceId: number,
     resourceId: number,
     clientIp: string | undefined,
     clientIp: string | undefined,
     path: string | undefined
     path: string | undefined
-): Promise<boolean> {
+): Promise<"ACCEPT" | "DROP" | undefined> {
     const ruleCacheKey = `rules:${resourceId}`;
     const ruleCacheKey = `rules:${resourceId}`;
 
 
     let rules: ResourceRule[] | undefined = cache.get(ruleCacheKey);
     let rules: ResourceRule[] | undefined = cache.get(ruleCacheKey);
@@ -472,36 +482,40 @@ async function checkRules(
 
 
     if (rules.length === 0) {
     if (rules.length === 0) {
         logger.debug("No rules found for resource", resourceId);
         logger.debug("No rules found for resource", resourceId);
-        return false;
+        return;
     }
     }
 
 
     for (const rule of rules) {
     for (const rule of rules) {
-        if (clientIp && rule.match == "IP" && isIpInCidr(clientIp, rule.value)) {
-            return rule.action == "ACCEPT"; 
+        if (
+            clientIp &&
+            rule.match == "IP" &&
+            isIpInCidr(clientIp, rule.value)
+        ) {
+            return rule.action as "ACCEPT" | "DROP";
         } else if (path && rule.match == "PATH") {
         } else if (path && rule.match == "PATH") {
             // rule.value is a regex, match on the path and see if it matches
             // rule.value is a regex, match on the path and see if it matches
             const re = urlGlobToRegex(rule.value);
             const re = urlGlobToRegex(rule.value);
             if (re.test(path)) {
             if (re.test(path)) {
-                return rule.action == "ACCEPT";
+                return rule.action as "ACCEPT" | "DROP";
             }
             }
         }
         }
     }
     }
 
 
-    return false;
+    return;
 }
 }
 
 
-function urlGlobToRegex(pattern: string): RegExp {  
+function urlGlobToRegex(pattern: string): RegExp {
     // Remove leading slash if present (we'll add it to the regex pattern)
     // Remove leading slash if present (we'll add it to the regex pattern)
-    pattern = pattern.startsWith('/') ? pattern.slice(1) : pattern;
-  
+    pattern = pattern.startsWith("/") ? pattern.slice(1) : pattern;
+
     // Escape special regex characters except *
     // Escape special regex characters except *
-    const escapedPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
-  
+    const escapedPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
+
     // Replace * with regex pattern for any valid URL segment characters
     // Replace * with regex pattern for any valid URL segment characters
-    const regexPattern = escapedPattern.replace(/\*/g, '[a-zA-Z0-9_-]+');
-  
+    const regexPattern = escapedPattern.replace(/\*/g, "[a-zA-Z0-9_-]+");
+
     // Create the final pattern that:
     // Create the final pattern that:
     // 1. Optionally matches leading slash
     // 1. Optionally matches leading slash
     // 2. Matches the entire string
     // 2. Matches the entire string
     return new RegExp(`^/?${regexPattern}$`);
     return new RegExp(`^/?${regexPattern}$`);
-  }
+}