okta-expression-parser 0.3.0__tar.gz → 0.4.1__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.
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/PKG-INFO +1 -1
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/lexer.py +11 -2
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/parser.py +57 -11
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/pyproject.toml +1 -1
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/README.md +0 -0
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/__init__.py +0 -0
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/expression_classes/__init__.py +0 -0
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/expression_classes/arrays.py +0 -0
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/expression_classes/convert.py +0 -0
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/expression_classes/groups.py +0 -0
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/expression_classes/iso3166convert.py +0 -0
- {okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/expression_classes/string.py +0 -0
{okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/lexer.py
RENAMED
|
@@ -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
|
{okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/parser.py
RENAMED
|
@@ -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
|
|
@@ -13,6 +14,19 @@ from .expression_classes.arrays import _ArrayType
|
|
|
13
14
|
from .lexer import ExpressionLexer
|
|
14
15
|
|
|
15
16
|
|
|
17
|
+
# Sly doesn't really facilitate configuring logging from the caller, so we're going to
|
|
18
|
+
# suppress all logging below the level specified in the LOG_LEVEL environment variable.
|
|
19
|
+
log_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "EXCEPTION"]
|
|
20
|
+
|
|
21
|
+
log_level = environ.get("LOG_LEVEL", "ERROR")
|
|
22
|
+
|
|
23
|
+
log_rank = log_levels.index(log_level)
|
|
24
|
+
|
|
25
|
+
for level_name in list(reversed(log_levels))[:log_rank +1]:
|
|
26
|
+
log_attr = level_name.lower()
|
|
27
|
+
setattr(sly.yacc.SlyLogger, log_attr, lambda self, msg, *args, **kwargs: None)
|
|
28
|
+
|
|
29
|
+
|
|
16
30
|
class ExpressionParser(sly.Parser):
|
|
17
31
|
#: Writes grammar rules to a file for debugging
|
|
18
32
|
debugfile = environ.get("OKTA_EXPRESSION_PARSER_LOG_FILE")
|
|
@@ -33,7 +47,7 @@ class ExpressionParser(sly.Parser):
|
|
|
33
47
|
group_ids: List[str] = [],
|
|
34
48
|
user_profile: Dict[str, Any] = {},
|
|
35
49
|
log_to_stdout: bool = False,
|
|
36
|
-
log_level: str = "
|
|
50
|
+
log_level: str = environ.get("LOG_LEVEL", "ERROR"),
|
|
37
51
|
expression_classes: ModuleType = _default_expression_classes,
|
|
38
52
|
group_data: dict = {},
|
|
39
53
|
) -> None:
|
|
@@ -49,6 +63,7 @@ class ExpressionParser(sly.Parser):
|
|
|
49
63
|
):
|
|
50
64
|
self._expression_classes.Groups.group_data = group_data
|
|
51
65
|
|
|
66
|
+
#: 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
67
|
self.group_data = group_data
|
|
53
68
|
|
|
54
69
|
self.__group_ids: str = group_ids
|
|
@@ -325,15 +340,47 @@ class ExpressionParser(sly.Parser):
|
|
|
325
340
|
|
|
326
341
|
return p.operand in self.__group_ids
|
|
327
342
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
343
|
+
@_('MEMBEROFNAME "(" operand ")"')
|
|
344
|
+
def condition(self, p: YaccProduction):
|
|
345
|
+
"""Tests if a user is a member of a group with a specific name"""
|
|
346
|
+
|
|
347
|
+
matches = [
|
|
348
|
+
v for k, v in self.group_data.items() if v["profile"]["name"] == p.operand
|
|
349
|
+
]
|
|
350
|
+
|
|
351
|
+
return bool(matches)
|
|
352
|
+
|
|
353
|
+
@_('MEMBEROFGROUPSTARTSWITH "(" operand ")"')
|
|
354
|
+
def condition(self, p: YaccProduction):
|
|
355
|
+
"""Tests if a user is a member of a group with a specific name"""
|
|
356
|
+
|
|
357
|
+
matches = [
|
|
358
|
+
v
|
|
359
|
+
for k, v in self.group_data.items()
|
|
360
|
+
if v["profile"]["name"].startswith(p.operand)
|
|
361
|
+
]
|
|
362
|
+
|
|
363
|
+
return bool(matches)
|
|
364
|
+
|
|
365
|
+
@_('MEMBEROFGROUPCONTAINS "(" operand ")"')
|
|
366
|
+
def condition(self, p: YaccProduction):
|
|
367
|
+
"""Tests if a user is a member of a group with a specific name"""
|
|
368
|
+
|
|
369
|
+
matches = [
|
|
370
|
+
v for k, v in self.group_data.items() if p.operand in v["profile"]["name"]
|
|
371
|
+
]
|
|
372
|
+
|
|
373
|
+
return bool(matches)
|
|
374
|
+
|
|
375
|
+
@_('MEMBEROFGROUPNAMEREGEX "(" operand ")"')
|
|
376
|
+
def condition(self, p: YaccProduction):
|
|
377
|
+
"""Tests if a user is a member of a group with a specific name"""
|
|
378
|
+
|
|
379
|
+
for _, group in self.group_data.items():
|
|
380
|
+
if match(p.operand, group["profile"]["name"]):
|
|
381
|
+
return True
|
|
382
|
+
|
|
383
|
+
return False
|
|
337
384
|
|
|
338
385
|
@_("operand QUESTION_MARK operand COLON operand") # noqa: 821
|
|
339
386
|
@_("condition QUESTION_MARK operand COLON operand") # noqa: 821
|
|
@@ -343,7 +390,6 @@ class ExpressionParser(sly.Parser):
|
|
|
343
390
|
if_false = p.operand1 if hasattr(p, "condition") else p.operand2
|
|
344
391
|
|
|
345
392
|
return if_true if condition else if_false
|
|
346
|
-
#return (condition, p.operand0, p.operand1)
|
|
347
393
|
|
|
348
394
|
@_("condition error") # noqa: 821
|
|
349
395
|
def operand(self, x): # noqa: 811
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "okta-expression-parser"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.1"
|
|
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"
|
|
File without changes
|
{okta_expression_parser-0.3.0 → okta_expression_parser-0.4.1}/okta_expression_parser/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|