datasource_access_request.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # Licensed to the Apache Software Foundation (ASF) under one
  2. # or more contributor license agreements. See the NOTICE file
  3. # distributed with this work for additional information
  4. # regarding copyright ownership. The ASF licenses this file
  5. # to you under the Apache License, Version 2.0 (the
  6. # "License"); you may not use this file except in compliance
  7. # with the License. You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing,
  12. # software distributed under the License is distributed on an
  13. # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. # KIND, either express or implied. See the License for the
  15. # specific language governing permissions and limitations
  16. # under the License.
  17. from typing import Optional, Type, TYPE_CHECKING
  18. from flask import Markup
  19. from flask_appbuilder import Model
  20. from sqlalchemy import Column, Integer, String
  21. from superset import app, db, security_manager
  22. from superset.connectors.connector_registry import ConnectorRegistry
  23. from superset.models.helpers import AuditMixinNullable
  24. from superset.utils import core as utils
  25. if TYPE_CHECKING:
  26. from superset.connectors.base.models import ( # pylint: disable=unused-import
  27. BaseDatasource,
  28. )
  29. config = app.config
  30. class DatasourceAccessRequest(Model, AuditMixinNullable):
  31. """ORM model for the access requests for datasources and dbs."""
  32. __tablename__ = "access_request"
  33. id = Column(Integer, primary_key=True) # pylint: disable=invalid-name
  34. datasource_id = Column(Integer)
  35. datasource_type = Column(String(200))
  36. ROLES_BLACKLIST = set(config["ROBOT_PERMISSION_ROLES"])
  37. @property
  38. def cls_model(self) -> Type["BaseDatasource"]:
  39. return ConnectorRegistry.sources[self.datasource_type]
  40. @property
  41. def username(self) -> Markup:
  42. return self.creator()
  43. @property
  44. def datasource(self) -> "BaseDatasource":
  45. return self.get_datasource
  46. @datasource.getter # type: ignore
  47. @utils.memoized
  48. def get_datasource(self) -> "BaseDatasource":
  49. ds = db.session.query(self.cls_model).filter_by(id=self.datasource_id).first()
  50. return ds
  51. @property
  52. def datasource_link(self) -> Optional[Markup]:
  53. return self.datasource.link # pylint: disable=no-member
  54. @property
  55. def roles_with_datasource(self) -> str:
  56. action_list = ""
  57. perm = self.datasource.perm # pylint: disable=no-member
  58. pv = security_manager.find_permission_view_menu("datasource_access", perm)
  59. for role in pv.role:
  60. if role.name in self.ROLES_BLACKLIST:
  61. continue
  62. # pylint: disable=no-member
  63. href = (
  64. f"/superset/approve?datasource_type={self.datasource_type}&"
  65. f"datasource_id={self.datasource_id}&"
  66. f"created_by={self.created_by.username}&role_to_grant={role.name}"
  67. )
  68. link = '<a href="{}">Grant {} Role</a>'.format(href, role.name)
  69. action_list = action_list + "<li>" + link + "</li>"
  70. return "<ul>" + action_list + "</ul>"
  71. @property
  72. def user_roles(self) -> str:
  73. action_list = ""
  74. for role in self.created_by.roles: # pylint: disable=no-member
  75. # pylint: disable=no-member
  76. href = (
  77. f"/superset/approve?datasource_type={self.datasource_type}&"
  78. f"datasource_id={self.datasource_id}&"
  79. f"created_by={self.created_by.username}&role_to_extend={role.name}"
  80. )
  81. link = '<a href="{}">Extend {} Role</a>'.format(href, role.name)
  82. if role.name in self.ROLES_BLACKLIST:
  83. link = "{} Role".format(role.name)
  84. action_list = action_list + "<li>" + link + "</li>"
  85. return "<ul>" + action_list + "</ul>"