okta-expression-parser 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: okta-expression-parser
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Returns a boolean by passing Okta profile data to an Okta Expression using Okta Expression Language
5
5
  Author: Mathew Moon
6
6
  Author-email: me@mathewmoon.net
@@ -10,9 +10,9 @@ class ExpressionLexer(Lexer):
10
10
  # reflags = re.IGNORECASE
11
11
  # Set of token names.
12
12
  tokens = {
13
+ NAME,
13
14
  STRING,
14
15
  INT,
15
- NAME,
16
16
  NE,
17
17
  GTE,
18
18
  LTE,
@@ -28,6 +28,10 @@ class ExpressionLexer(Lexer):
28
28
  QUESTION_MARK,
29
29
  MEMBEROF,
30
30
  MEMBEROFANY,
31
+ MEMBEROFNAME,
32
+ MEMBEROFGROUPSTARTSWITH,
33
+ MEMBEROFGROUPCONTAINS,
34
+ MEMBEROFGROUPNAMEREGEX,
31
35
  USER,
32
36
  CLASS,
33
37
  }
@@ -48,7 +52,11 @@ class ExpressionLexer(Lexer):
48
52
  OR = r"or|OR|Or"
49
53
  EQ = r"(==|eq|EQ|Eq)"
50
54
  BOOL = r"(true|false|True|False|TRUE|FALSE)"
55
+ MEMBEROFGROUPCONTAINS = "isMemberOfGroupNameContains"
56
+ MEMBEROFGROUPNAMEREGEX = "isMemberOfGroupNameRegex"
57
+ MEMBEROFGROUPSTARTSWITH = "isMemberOfGroupNameStartsWith"
51
58
  MEMBEROFANY = "isMemberOfAnyGroup"
59
+ MEMBEROFNAME = "isMemberOfGroupName"
52
60
  MEMBEROF = "isMemberOfGroup"
53
61
  USER = r"user\b"
54
62
  COLON = r"\:"
@@ -57,7 +65,8 @@ class ExpressionLexer(Lexer):
57
65
  NULL = r"null|NULL|Null"
58
66
  CLASS = r"String|Arrays|Convert|Iso3166Convert|Groups"
59
67
  INT = r"\d+"
60
- STRING = r""""([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'|''|\"\""""
68
+ # STRING = r""""([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'|''|\"\""""
69
+ STRING = r'''"(?:\\.|[^"\\])*"'''
61
70
  NAME = r"[a-zA-Z_][a-zA-Z0-9\-_]*"
62
71
 
63
72
  # Line number tracking
@@ -1,6 +1,7 @@
1
1
  # pyright: reportUndefinedVariable=false
2
2
  import logging
3
3
  from os import environ
4
+ from re import match
4
5
  from sys import stdout
5
6
  from typing import Any, Dict, List, Sequence
6
7
  from types import ModuleType
@@ -49,6 +50,7 @@ class ExpressionParser(sly.Parser):
49
50
  ):
50
51
  self._expression_classes.Groups.group_data = group_data
51
52
 
53
+ #: A dict, with Group ID's as the keys and group data as the values. Used for operations that require more context than just the group ID.
52
54
  self.group_data = group_data
53
55
 
54
56
  self.__group_ids: str = group_ids
@@ -325,15 +327,47 @@ class ExpressionParser(sly.Parser):
325
327
 
326
328
  return p.operand in self.__group_ids
327
329
 
328
- #@_("turnary") # noqa: 821
329
- #def operand(self, p: YaccProduction) -> Any:
330
- # condition = p.turnary[0]
331
- # if_true = p.turnary[1]
332
- # if_false = p.turnary[2]
333
- # if condition:
334
- # return if_true
335
- # else:
336
- # return if_false
330
+ @_('MEMBEROFNAME "(" operand ")"')
331
+ def condition(self, p: YaccProduction):
332
+ """Tests if a user is a member of a group with a specific name"""
333
+
334
+ matches = [
335
+ v for k, v in self.group_data.items() if v["profile"]["name"] == p.operand
336
+ ]
337
+
338
+ return bool(matches)
339
+
340
+ @_('MEMBEROFGROUPSTARTSWITH "(" operand ")"')
341
+ def condition(self, p: YaccProduction):
342
+ """Tests if a user is a member of a group with a specific name"""
343
+
344
+ matches = [
345
+ v
346
+ for k, v in self.group_data.items()
347
+ if v["profile"]["name"].startswith(p.operand)
348
+ ]
349
+
350
+ return bool(matches)
351
+
352
+ @_('MEMBEROFGROUPCONTAINS "(" operand ")"')
353
+ def condition(self, p: YaccProduction):
354
+ """Tests if a user is a member of a group with a specific name"""
355
+
356
+ matches = [
357
+ v for k, v in self.group_data.items() if p.operand in v["profile"]["name"]
358
+ ]
359
+
360
+ return bool(matches)
361
+
362
+ @_('MEMBEROFGROUPNAMEREGEX "(" operand ")"')
363
+ def condition(self, p: YaccProduction):
364
+ """Tests if a user is a member of a group with a specific name"""
365
+
366
+ for _, group in self.group_data.items():
367
+ if match(p.operand, group["profile"]["name"]):
368
+ return True
369
+
370
+ return False
337
371
 
338
372
  @_("operand QUESTION_MARK operand COLON operand") # noqa: 821
339
373
  @_("condition QUESTION_MARK operand COLON operand") # noqa: 821
@@ -343,7 +377,6 @@ class ExpressionParser(sly.Parser):
343
377
  if_false = p.operand1 if hasattr(p, "condition") else p.operand2
344
378
 
345
379
  return if_true if condition else if_false
346
- #return (condition, p.operand0, p.operand1)
347
380
 
348
381
  @_("condition error") # noqa: 821
349
382
  def operand(self, x): # noqa: 811
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "okta-expression-parser"
3
- version = "0.3.0"
3
+ version = "0.4.0"
4
4
  description = "Returns a boolean by passing Okta profile data to an Okta Expression using Okta Expression Language"
5
5
  authors = ["Mathew Moon <me@mathewmoon.net>"]
6
6
  readme = "README.md"