Skip to content

Commit 38a1bda

Browse files
committed
Added sample condition handler with IF/ELSE
1 parent dfa21f2 commit 38a1bda

File tree

3 files changed

+238
-1
lines changed

3 files changed

+238
-1
lines changed

shuffle-tools/1.2.0/api.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,19 @@ actions:
12031203
example: 'ls -la'
12041204
schema:
12051205
type: string
1206+
- name: if_else_routing
1207+
description: Routes based on if-else statements
1208+
parameters:
1209+
- name: conditions
1210+
description: The conditions to be met
1211+
required: true
1212+
multiline: true
1213+
example: "REPEATING: Hello world"
1214+
schema:
1215+
type: string
1216+
returns:
1217+
schema:
1218+
type: string
12061219
#- name: parse_ioc_new
12071220
# description: Parse IOC's based on https://github.com/fhightower/ioc-finder
12081221
# parameters:

shuffle-tools/1.2.0/src/app.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2787,7 +2787,28 @@ def list_cidr_ips(self, cidr):
27872787
}
27882788

27892789
return returnvalue
2790-
2790+
2791+
def if_else_routing(self, conditions):
2792+
# True by default
2793+
to_return = {
2794+
"success": True,
2795+
"run_else": True,
2796+
}
2797+
2798+
if len(conditions) == 0:
2799+
conditions = []
2800+
2801+
for condition in conditions:
2802+
pass
2803+
2804+
# Loop conditions
2805+
# Return them without a loop to make it EASY to understand
2806+
# Validation should be:
2807+
# Continuation based on .id.valid
2808+
# .valid -> true/false
2809+
# If no id exists, use name?
2810+
2811+
return to_return
27912812

27922813
if __name__ == "__main__":
27932814
Tools.run()

shuffle-tools/1.2.0/src/switch.py

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# self, sourcevalue, condition, destinationvalue
2+
def run_validation(sourcevalue, check, destinationvalue):
3+
if check == "=" or check == "==" or check.lower() == "equals":
4+
if str(sourcevalue).lower() == str(destinationvalue).lower():
5+
return True
6+
elif check == "!=" or check.lower() == "does not equal":
7+
if str(sourcevalue).lower() != str(destinationvalue).lower():
8+
return True
9+
elif check.lower() == "startswith":
10+
if str(sourcevalue).lower().startswith(str(destinationvalue).lower()):
11+
return True
12+
13+
14+
elif check.lower() == "endswith":
15+
if str(sourcevalue).lower().endswith(str(destinationvalue).lower()):
16+
return True
17+
elif check.lower() == "contains":
18+
if destinationvalue.lower() in sourcevalue.lower():
19+
return True
20+
21+
elif check.lower() == "is empty" or check.lower() == "is_empty":
22+
try:
23+
if len(json.loads(sourcevalue)) == 0:
24+
return True
25+
except Exception as e:
26+
print("[ERROR] Failed to check if empty as list: {e}")
27+
28+
if len(str(sourcevalue)) == 0:
29+
return True
30+
31+
elif check.lower() == "contains_any_of":
32+
newvalue = [destinationvalue.lower()]
33+
if "," in destinationvalue:
34+
newvalue = destinationvalue.split(",")
35+
elif ", " in destinationvalue:
36+
newvalue = destinationvalue.split(", ")
37+
38+
for item in newvalue:
39+
if not item:
40+
continue
41+
42+
if item.strip() in sourcevalue:
43+
return True
44+
45+
elif check.lower() == "larger than" or check.lower() == "bigger than" or check == ">" or check == ">=":
46+
try:
47+
if str(sourcevalue).isdigit() and str(destinationvalue).isdigit():
48+
if int(sourcevalue) > int(destinationvalue):
49+
return True
50+
51+
except AttributeError as e:
52+
print("[WARNING] Condition larger than failed with values %s and %s: %s" % (sourcevalue, destinationvalue, e))
53+
54+
try:
55+
destinationvalue = len(json.loads(destinationvalue))
56+
except Exception as e:
57+
print("[WARNING] Failed to convert destination to list: {e}")
58+
try:
59+
# Check if it's a list in autocast and if so, check the length
60+
if len(json.loads(sourcevalue)) > int(destinationvalue):
61+
return True
62+
except Exception as e:
63+
print("[WARNING] Failed to check if larger than as list: {e}")
64+
65+
66+
elif check.lower() == "smaller than" or check.lower() == "less than" or check == "<" or check == "<=":
67+
print("In smaller than check: %s %s" % (sourcevalue, destinationvalue))
68+
69+
try:
70+
if str(sourcevalue).isdigit() and str(destinationvalue).isdigit():
71+
if int(sourcevalue) < int(destinationvalue):
72+
return True
73+
74+
except AttributeError as e:
75+
pass
76+
77+
try:
78+
destinationvalue = len(json.loads(destinationvalue))
79+
except Exception as e:
80+
print("[WARNING] Failed to convert destination to list: {e}")
81+
82+
try:
83+
# Check if it's a list in autocast and if so, check the length
84+
if len(json.loads(sourcevalue)) < int(destinationvalue):
85+
return True
86+
except Exception as e:
87+
print("[WARNING] Failed to check if smaller than as list: {e}")
88+
89+
elif check.lower() == "re" or check.lower() == "matches regex":
90+
try:
91+
found = re.search(str(destinationvalue), str(sourcevalue))
92+
except re.error as e:
93+
return False
94+
except Exception as e:
95+
return False
96+
97+
if found == None:
98+
return False
99+
100+
return True
101+
else:
102+
print("[DEBUG] Condition: can't handle %s yet. Setting to true" % check)
103+
104+
return False
105+
106+
def evaluate_conditions(condition_structure):
107+
operator = condition_structure.get('operator')
108+
109+
# Base case: Single condition
110+
if 'source' in condition_structure:
111+
source = condition_structure['source']
112+
condition = condition_structure['condition']
113+
destination = condition_structure['destination']
114+
115+
# self.
116+
return run_validation(source, condition, destination)
117+
118+
# Recursive case: Logical operator
119+
elif operator == "AND":
120+
return all(evaluate_conditions(sub_condition) for sub_condition in condition_structure['conditions'])
121+
122+
elif operator == "OR":
123+
return any(evaluate_conditions(sub_condition) for sub_condition in condition_structure['conditions'])
124+
125+
elif operator == "NOT":
126+
return not evaluate_conditions(condition_structure['conditions'][0])
127+
128+
else:
129+
raise ValueError(f"Unknown operator: {operator}")
130+
131+
132+
def switch(conditions):
133+
to_return = {
134+
"success": True,
135+
"run_else": True,
136+
}
137+
138+
for condition in conditions:
139+
if "id" not in condition:
140+
print("Condition ID not found")
141+
continue
142+
143+
evaluated = False
144+
try:
145+
evaluated = evaluate_conditions(condition)
146+
except Exception as e:
147+
print(f"Failed to evaluate condition {condition['id']}: {e}")
148+
149+
if evaluated == True:
150+
to_return["run_else"] = False
151+
152+
to_return[condition["id"]] = evaluated
153+
154+
return to_return
155+
156+
# Example usage
157+
158+
condition_structure = {
159+
"id": "lol",
160+
"operator": "AND",
161+
"conditions": [
162+
{ # true
163+
"source": "20", # age
164+
"condition": ">",
165+
"destination": 18
166+
},
167+
{ # true
168+
"operator": "OR",
169+
"conditions": [
170+
{
171+
"source": "active", # status
172+
"condition": "==",
173+
"destination": "active"
174+
},
175+
{
176+
"source": "1500", # balance
177+
"condition": ">=",
178+
"destination": 1000
179+
}
180+
]
181+
},
182+
{
183+
"operator": "NOT",
184+
"conditions": [
185+
{
186+
"source": "user", # user
187+
"condition": "==",
188+
"destination": "admin"
189+
}
190+
]
191+
}
192+
]
193+
}
194+
195+
newcondition = condition_structure.copy()
196+
testconditions = [condition_structure]
197+
newcondition['id'] = "lol2"
198+
testconditions.append(newcondition)
199+
200+
result = switch(testconditions)
201+
print()
202+
print()
203+
print("Output: ", result)

0 commit comments

Comments
 (0)