Преглед изворни кода

[raz] Allow users with access to create own home dirs (#2968)

Harsh Gupta пре 3 година
родитељ
комит
140844ba5d

+ 31 - 1
desktop/core/src/desktop/lib/fs/proxyfs.py

@@ -27,6 +27,11 @@ from useradmin.models import User
 from desktop.auth.backend import is_admin
 from desktop.conf import DEFAULT_USER, ENABLE_ORGANIZATIONS
 
+from aws.conf import is_raz_s3
+from aws.s3.s3fs import get_s3_home_directory
+
+from azure.conf import is_raz_abfs
+from azure.abfs.__init__ import get_home_dir_for_abfs
 
 if sys.version_info[0] > 2:
   from urllib.parse import urlparse as lib_urlparse
@@ -200,9 +205,34 @@ class ProxyFS(object):
     self._get_fs(path).create(path, *args, **kwargs)
 
   def create_home_dir(self, home_path=None):
+    """
+    Initially home_path will have path value for HDFS and if it is configured in Hue, try creating the user home dir for it first.
+    Then we check if S3/ABFS is configured in Hue via RAZ. If yes, try creating user home dir for them next.
+    """
     if home_path is None:
       home_path = self.get_home_dir()
-    self._get_fs(home_path).create_home_dir(home_path)
+
+    try:
+      self._get_fs(home_path).create_home_dir(home_path)
+    except Exception as e:
+      LOG.debug('Error creating HDFS home directory for path %s : %s' % (home_path, str(e)))
+
+    # Get the new home_path for S3/ABFS when RAZ is enabled.
+    if is_raz_s3():
+      home_path = get_s3_home_directory(User.objects.get(username=self.getuser()))
+    elif is_raz_abfs():
+      home_path = get_home_dir_for_abfs(User.objects.get(username=self.getuser()))
+
+    # Try getting user from the request and create home dirs. This helps when Hue admin is trying to create the dir for other users.
+    # That way only Hue admin needs authorization to create for all Hue users and not each individual user.
+    # If normal users also have authorization, then they can also create the dir for themselves if they want.
+    from crequest.middleware import CrequestMiddleware
+    request = CrequestMiddleware.get_request()
+    username = request.user.username if request and hasattr(request, 'user') and request.user.is_authenticated else self.getuser()
+
+    if is_raz_s3() or is_raz_abfs():
+      fs = self.do_as_user(username, self._get_fs, home_path)
+      fs.create_home_dir(home_path)
 
   def chown(self, path, *args, **kwargs):
     self._get_fs(path).chown(path, *args, **kwargs)

+ 10 - 2
desktop/libs/aws/src/aws/s3/s3fs.py

@@ -32,7 +32,7 @@ from boto.s3.key import Key
 from boto.s3.prefix import Prefix
 
 from aws import s3
-from aws.conf import get_default_region, get_locations, PERMISSION_ACTION_S3
+from aws.conf import get_default_region, get_locations, PERMISSION_ACTION_S3, is_raz_s3
 from aws.s3 import normpath, s3file, translate_s3_error, S3A_ROOT
 from aws.s3.s3stat import S3Stat
 
@@ -392,7 +392,15 @@ class S3FileSystem(object):
     return self._filebrowser_action
 
   def create_home_dir(self, home_path):
-    LOG.info('Create home directory is not available for S3 filesystem')
+    # When S3 raz is enabled, try to create user home dir for REMOTE_STORAGE_HOME path
+    if is_raz_s3():
+      LOG.debug('Attempting to create user directory for path: %s' % home_path)
+      try:
+        self.mkdir(home_path)
+      except Exception as e:
+        LOG.exception('Failed to create user home directory for path %s with error: %s' % (home_path, str(e)))
+    else:
+      LOG.info('Create home directory is not available for S3 filesystem')
 
   @translate_s3_error
   @auth_error_handler

+ 5 - 3
desktop/libs/azure/src/azure/conf.py

@@ -157,16 +157,18 @@ ABFS_CLUSTERS = UnspecifiedConfigSection(
   )
 )
 
+def is_raz_abfs():
+  from desktop.conf import RAZ  # Must be imported dynamically in order to have proper value
+  return (RAZ.IS_ENABLED.get() and 'default' in list(ABFS_CLUSTERS.keys()))
+
 def is_adls_enabled():
   return ('default' in list(AZURE_ACCOUNTS.keys()) and AZURE_ACCOUNTS['default'].get_raw() and AZURE_ACCOUNTS['default'].CLIENT_ID.get() \
     or (conf_idbroker.is_idbroker_enabled('azure') and has_azure_metadata())) and 'default' in list(ADLS_CLUSTERS.keys())
 
 def is_abfs_enabled():
-  from desktop.conf import RAZ  # Must be imported dynamically in order to have proper value
-
   return ('default' in list(AZURE_ACCOUNTS.keys()) and AZURE_ACCOUNTS['default'].get_raw() and AZURE_ACCOUNTS['default'].CLIENT_ID.get() \
     or (conf_idbroker.is_idbroker_enabled('azure') and has_azure_metadata())) and 'default' in list(ABFS_CLUSTERS.keys()) \
-    or (RAZ.IS_ENABLED.get() and 'default' in list(ABFS_CLUSTERS.keys()))
+    or is_raz_abfs()
 
 def has_adls_access(user):
   from desktop.conf import RAZ  # Must be imported dynamically in order to have proper value