apache-airflow-providers-fab 2.2.0rc1__py3-none-any.whl → 2.2.1rc2__py3-none-any.whl

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.
Files changed (28) hide show
  1. airflow/providers/fab/__init__.py +1 -1
  2. airflow/providers/fab/auth_manager/fab_auth_manager.py +6 -6
  3. airflow/providers/fab/auth_manager/security_manager/override.py +19 -0
  4. airflow/providers/fab/www/extensions/init_appbuilder.py +8 -0
  5. airflow/providers/fab/www/package-lock.json +4 -4
  6. airflow/providers/fab/www/package.json +1 -1
  7. airflow/providers/fab/www/static/dist/{743.57634ddb93717b7c8c1a.js → 743.b6629eaae7f541f4158f.js} +1 -1
  8. airflow/providers/fab/www/static/dist/{main.49c4d5787ef1f247f004.js → main.26e36c3998f451900260.js} +1 -1
  9. airflow/providers/fab/www/static/dist/manifest.json +13 -13
  10. {apache_airflow_providers_fab-2.2.0rc1.dist-info → apache_airflow_providers_fab-2.2.1rc2.dist-info}/METADATA +6 -6
  11. {apache_airflow_providers_fab-2.2.0rc1.dist-info → apache_airflow_providers_fab-2.2.1rc2.dist-info}/RECORD +28 -28
  12. /airflow/providers/fab/www/static/dist/{743.57634ddb93717b7c8c1a.js.LICENSE.txt → 743.b6629eaae7f541f4158f.js.LICENSE.txt} +0 -0
  13. /airflow/providers/fab/www/static/dist/{airflowDefaultTheme.48540e25fb1e474cef20.css → airflowDefaultTheme.5a4eda684d2f5f33fa6a.css} +0 -0
  14. /airflow/providers/fab/www/static/dist/{airflowDefaultTheme.48540e25fb1e474cef20.js → airflowDefaultTheme.5a4eda684d2f5f33fa6a.js} +0 -0
  15. /airflow/providers/fab/www/static/dist/{flash.02dea0c2ac20820e8d1b.css → flash.9f756672299e9e57a824.css} +0 -0
  16. /airflow/providers/fab/www/static/dist/{flash.02dea0c2ac20820e8d1b.js → flash.9f756672299e9e57a824.js} +0 -0
  17. /airflow/providers/fab/www/static/dist/{loadingDots.96221bc8b6345c7d65b3.css → loadingDots.fc35e1feb443bd3a8d80.css} +0 -0
  18. /airflow/providers/fab/www/static/dist/{loadingDots.96221bc8b6345c7d65b3.js → loadingDots.fc35e1feb443bd3a8d80.js} +0 -0
  19. /airflow/providers/fab/www/static/dist/{main.49c4d5787ef1f247f004.css → main.26e36c3998f451900260.css} +0 -0
  20. /airflow/providers/fab/www/static/dist/{main.49c4d5787ef1f247f004.js.LICENSE.txt → main.26e36c3998f451900260.js.LICENSE.txt} +0 -0
  21. /airflow/providers/fab/www/static/dist/{materialIcons.4fd835641d53f81af3d3.css → materialIcons.e84a12f5be6e8d456d02.css} +0 -0
  22. /airflow/providers/fab/www/static/dist/{materialIcons.4fd835641d53f81af3d3.js → materialIcons.e84a12f5be6e8d456d02.js} +0 -0
  23. /airflow/providers/fab/www/static/dist/{moment.6943aa3cca9cb1129a71.js → moment.9023635a87b836172067.js} +0 -0
  24. /airflow/providers/fab/www/static/dist/{runtime.3c1a5fcbb3c1b7c62ad7.js → runtime.78bb8f6146c25d99b9e2.js} +0 -0
  25. {apache_airflow_providers_fab-2.2.0rc1.dist-info → apache_airflow_providers_fab-2.2.1rc2.dist-info}/WHEEL +0 -0
  26. {apache_airflow_providers_fab-2.2.0rc1.dist-info → apache_airflow_providers_fab-2.2.1rc2.dist-info}/entry_points.txt +0 -0
  27. {apache_airflow_providers_fab-2.2.0rc1.dist-info → apache_airflow_providers_fab-2.2.1rc2.dist-info}/licenses/3rd-party-licenses/LICENSES-ui.txt +0 -0
  28. {apache_airflow_providers_fab-2.2.0rc1.dist-info → apache_airflow_providers_fab-2.2.1rc2.dist-info}/licenses/NOTICE +0 -0
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "2.2.0"
32
+ __version__ = "2.2.1"
33
33
 
34
34
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
35
35
  "3.0.2"
@@ -308,9 +308,9 @@ class FabAuthManager(BaseAuthManager[User]):
308
308
 
309
309
  There are multiple scenarios:
310
310
 
311
- 1. ``dag_access`` is not provided which means the user wants to access the DAG itself and not a sub
311
+ 1. ``access_entity`` is not provided which means the user wants to access the DAG itself and not a sub
312
312
  entity (e.g. DAG runs).
313
- 2. ``dag_access`` is provided which means the user wants to access a sub entity of the DAG
313
+ 2. ``access_entity`` is provided which means the user wants to access a sub entity of the DAG
314
314
  (e.g. DAG runs).
315
315
 
316
316
  a. If ``method`` is GET, then check the user has READ permissions on the DAG and the sub entity.
@@ -564,8 +564,8 @@ class FabAuthManager(BaseAuthManager[User]):
564
564
  # Check whether the user has permissions to access a specific DAG
565
565
  resource_dag_name = permissions.resource_name(details.id, RESOURCE_DAG)
566
566
  return self._is_authorized(method=method, resource_type=resource_dag_name, user=user)
567
-
568
- return False
567
+ authorized_dags = self.get_authorized_dag_ids(user=user, method=method)
568
+ return len(authorized_dags) > 0
569
569
 
570
570
  def _is_authorized_dag_run(
571
571
  self,
@@ -590,8 +590,8 @@ class FabAuthManager(BaseAuthManager[User]):
590
590
  # Check whether the user has permissions to access a specific DAG Run permission on a DAG Level
591
591
  resource_dag_name = permissions.resource_name(details.id, RESOURCE_DAG_RUN)
592
592
  return self._is_authorized(method=method, resource_type=resource_dag_name, user=user)
593
-
594
- return False
593
+ authorized_dags = self.get_authorized_dag_ids(user=user, method=method)
594
+ return len(authorized_dags) > 0
595
595
 
596
596
  @staticmethod
597
597
  def _get_fab_action(method: ResourceMethod) -> str:
@@ -43,6 +43,7 @@ from flask_appbuilder.const import (
43
43
  )
44
44
  from flask_appbuilder.models.sqla import Base
45
45
  from flask_appbuilder.models.sqla.interface import SQLAInterface
46
+ from flask_appbuilder.security.api import SecurityApi
46
47
  from flask_appbuilder.security.registerviews import (
47
48
  RegisterUserDBView,
48
49
  RegisterUserOAuthView,
@@ -187,6 +188,10 @@ class FabAirflowSecurityManagerOverride(AirflowSecurityManagerV2):
187
188
  useroidmodelview = CustomUserOIDModelView
188
189
  userstatschartview = CustomUserStatsChartView
189
190
 
191
+ # API
192
+ security_api = SecurityApi
193
+ """ Override if you want your own Security API login endpoint """
194
+
190
195
  jwt_manager = None
191
196
  """ Flask-JWT-Extended """
192
197
  oauth = None
@@ -401,6 +406,9 @@ class FabAirflowSecurityManagerOverride(AirflowSecurityManagerV2):
401
406
  if not self.appbuilder.get_app.config.get("FAB_ADD_SECURITY_VIEWS", True):
402
407
  return
403
408
 
409
+ # Security APIs
410
+ self.appbuilder.add_api(self.security_api)
411
+
404
412
  if self.auth_user_registration:
405
413
  if self.auth_type == AUTH_DB:
406
414
  self.registeruser_view = self.registeruserdbview()
@@ -743,6 +751,15 @@ class FabAirflowSecurityManagerOverride(AirflowSecurityManagerV2):
743
751
  """Get the builtin roles."""
744
752
  return self._builtin_roles
745
753
 
754
+ @property
755
+ def api_login_allow_multiple_providers(self):
756
+ return self.appbuilder.get_app.config["AUTH_API_LOGIN_ALLOW_MULTIPLE_PROVIDERS"]
757
+
758
+ @property
759
+ def auth_type_provider_name(self):
760
+ provider_to_auth_type = {AUTH_DB: "db", AUTH_LDAP: "ldap"}
761
+ return provider_to_auth_type.get(self.auth_type)
762
+
746
763
  def _init_config(self):
747
764
  """
748
765
  Initialize config.
@@ -767,12 +784,14 @@ class FabAirflowSecurityManagerOverride(AirflowSecurityManagerV2):
767
784
 
768
785
  parsed_werkzeug_version = Version(werkzeug_version)
769
786
  if parsed_werkzeug_version < Version("3.0.0"):
787
+ app.config.setdefault("FAB_PASSWORD_HASH_METHOD", "pbkdf2:sha256")
770
788
  app.config.setdefault(
771
789
  "AUTH_DB_FAKE_PASSWORD_HASH_CHECK",
772
790
  "pbkdf2:sha256:150000$Z3t6fmj2$22da622d94a1f8118"
773
791
  "c0976a03d2f18f680bfff877c9a965db9eedc51bc0be87c",
774
792
  )
775
793
  else:
794
+ app.config.setdefault("FAB_PASSWORD_HASH_METHOD", "scrypt")
776
795
  app.config.setdefault(
777
796
  "AUTH_DB_FAKE_PASSWORD_HASH_CHECK",
778
797
  "scrypt:32768:8:1$wiDa0ruWlIPhp9LM$6e409d093e62ad54df2af895d0e125b05ff6cf6414"
@@ -525,6 +525,14 @@ class AirflowAppBuilder:
525
525
  log.warning(LOGMSG_WAR_FAB_VIEW_EXISTS, baseview.__class__.__name__)
526
526
  return baseview
527
527
 
528
+ def add_api(self, baseview):
529
+ """
530
+ Add a BaseApi class or child to AppBuilder.
531
+
532
+ :param baseview: A BaseApi type class
533
+ """
534
+ return self.add_view_no_menu(baseview)
535
+
528
536
  @property
529
537
  def get_url_for_index(self):
530
538
  return url_for(f"{self.indexview.endpoint}.{self.indexview.default_view}")
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "devDependencies": {
16
16
  "@babel/core": "^7.27.4",
17
- "@babel/eslint-parser": "^7.27.1",
17
+ "@babel/eslint-parser": "^7.27.5",
18
18
  "@babel/plugin-transform-runtime": "^7.27.4",
19
19
  "@babel/preset-env": "^7.27.2",
20
20
  "babel-loader": "^10.0.0",
@@ -112,9 +112,9 @@
112
112
  }
113
113
  },
114
114
  "node_modules/@babel/eslint-parser": {
115
- "version": "7.27.1",
116
- "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.27.1.tgz",
117
- "integrity": "sha512-q8rjOuadH0V6Zo4XLMkJ3RMQ9MSBqwaDByyYB0izsYdaIWGNLmEblbCOf1vyFHICcg16CD7Fsi51vcQnYxmt6Q==",
115
+ "version": "7.27.5",
116
+ "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.27.5.tgz",
117
+ "integrity": "sha512-HLkYQfRICudzcOtjGwkPvGc5nF1b4ljLZh1IRDj50lRZ718NAKVgQpIAUX8bfg6u/yuSKY3L7E0YzIV+OxrB8Q==",
118
118
  "dev": true,
119
119
  "license": "MIT",
120
120
  "dependencies": {
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "devDependencies": {
42
42
  "@babel/core": "^7.27.4",
43
- "@babel/eslint-parser": "^7.27.1",
43
+ "@babel/eslint-parser": "^7.27.5",
44
44
  "@babel/plugin-transform-runtime": "^7.27.4",
45
45
  "@babel/preset-env": "^7.27.2",
46
46
  "babel-loader": "^10.0.0",