浏览代码

HUE-1506 [search] Impersonation support

Romain Rigaux 12 年之前
父节点
当前提交
8bbf825

+ 32 - 8
apps/search/src/search/api.py

@@ -31,21 +31,30 @@ from search.conf import EMPTY_QUERY, SECURITY_ENABLED
 
 LOG = logging.getLogger(__name__)
 
+DEFAULT_USER = 'hue'
+
 
 class SolrApi(object):
   """
   http://wiki.apache.org/solr/CoreAdmin#CoreAdminHandler
   """
-  def __init__(self, solr_url):
+  def __init__(self, solr_url, user):
     self._url = solr_url
+    self._user = user
     self._client = HttpClient(self._url, logger=LOG)
-    if SECURITY_ENABLED.get():
+    self.security_enabled = SECURITY_ENABLED.get()
+    if self.security_enabled:
       self._client.set_kerberos_auth()
     self._root = Resource(self._client)
 
+  def _get_params(self):
+    if self.security_enabled:
+      return (('doAs', self._user ),)
+    return (('user.name', DEFAULT_USER), ('doAs', self._user),)
+
   def query(self, solr_query, hue_core):
     try:
-      params = (
+      params = self._get_params() + (
           ('q', solr_query['q'] or EMPTY_QUERY.get()),
           ('wt', 'json'),
           ('rows', solr_query['rows']),
@@ -70,7 +79,7 @@ class SolrApi(object):
 
   def suggest(self, solr_query, hue_core):
     try:
-      params = (
+      params = self._get_params() + (
           ('q', solr_query['q']),
           ('wt', 'json'),
       )
@@ -83,7 +92,11 @@ class SolrApi(object):
 
   def collections(self):
     try:
-      response = self._root.get('zookeeper', params={'detail': 'true', 'path': '/clusterstate.json'})
+      params = self._get_params() + (
+          ('detail', 'true'),
+          ('path', '/clusterstate.json'),
+      )
+      response = self._root.get('zookeeper', params=params)
       return json.loads(response['znode']['data'])
     except RestException, e:
       raise PopupException('Error while accessing Solr: %s' % e)
@@ -103,18 +116,29 @@ class SolrApi(object):
 
   def cores(self):
     try:
-      return self._root.get('admin/cores', params={'wt': 'json'})['status']
+      params = self._get_params() + (
+          ('wt', 'json'),
+      )      
+      return self._root.get('admin/cores', params=params)['status']
     except RestException, e:
       raise PopupException('Error while accessing Solr: %s' % e)
 
   def core(self, core):
     try:
-      return self._root.get('admin/cores', params={'wt': 'json', 'core': core})
+      params = self._get_params() + (
+          ('wt', 'json'),
+          ('core', core),
+      )         
+      return self._root.get('admin/cores', params=params)
     except RestException, e:
       raise PopupException('Error while accessing Solr: %s' % e)
 
   def schema(self, core):
     try:
-      return self._root.get('%(core)s/admin/file' % {'core': core}, params={'wt': 'json', 'file': 'schema.xml'})
+      params = self._get_params() + (
+          ('wt', 'json'),
+          ('file', 'schema.xml'),
+      )       
+      return self._root.get('%(core)s/admin/file' % {'core': core}, params=params)
     except RestException, e:
       raise PopupException('Error while accessing Solr: %s' % e)

+ 6 - 8
apps/search/src/search/models.py

@@ -233,7 +233,7 @@ em {
     <div class="span12">%s</div>
   </div>
   <br/>  
-</div>""" % ' '.join(['{{%s}}' % field for field in collection.fields])
+</div>""" % ' '.join(['{{%s}}' % field for field in collection.fields(user)])
 
       result.update_from_post({'template': json.dumps(template)})
       result.save()
@@ -264,16 +264,14 @@ class Collection(models.Model):
   def get_absolute_url(self):
     return reverse('search:admin_collection', kwargs={'collection_id': self.id})
 
-  @property
-  def fields(self):
-    return sorted([field.get('name') for field in self.fields_data])
+  def fields(self, user):
+    return sorted([field.get('name') for field in self.fields_data(user)])
 
-  @property
-  def fields_data(self):
-    solr_schema = SolrApi(SOLR_URL.get()).schema(self.name)
+  def fields_data(self, user):
+    solr_schema = SolrApi(SOLR_URL.get(), user).schema(self.name)
     schema = etree.fromstring(solr_schema)
 
-    return sorted([{'name': field.get('name'),'type': field.get('type')}
+    return sorted([{'name': field.get('name'), 'type': field.get('type')}
                    for fields in schema.iter('fields') for field in fields.iter('field')])
 
 def get_facet_field_format(field, type, facets):

+ 6 - 6
apps/search/src/search/search_controller.py

@@ -37,12 +37,12 @@ class SearchController(object):
   """
   Glue the models to the views.
   """
-  def __init__(self):
-    pass
+  def __init__(self, user):
+    self.user = user
 
   def get_new_collections(self):
     try:
-      solr_collections = SolrApi(SOLR_URL.get()).collections()
+      solr_collections = SolrApi(SOLR_URL.get(), self.user).collections()
       for name in Collection.objects.values_list('name', flat=True):
         solr_collections.pop(name, None)
     except Exception, e:
@@ -53,7 +53,7 @@ class SearchController(object):
 
   def get_new_cores(self):
     try:
-      solr_cores = SolrApi(SOLR_URL.get()).cores()
+      solr_cores = SolrApi(SOLR_URL.get(), self.user).cores()
       for name in Collection.objects.values_list('name', flat=True):
         solr_cores.pop(name, None)
     except Exception, e:
@@ -120,9 +120,9 @@ class SearchController(object):
       LOG.warn('Error copying collection: %s' % e)
 
   def is_collection(self, collection_name):
-    solr_collections = SolrApi(SOLR_URL.get()).collections()
+    solr_collections = SolrApi(SOLR_URL.get(), self.user).collections()
     return collection_name in solr_collections
 
   def is_core(self, core_name):
-    solr_cores = SolrApi(SOLR_URL.get()).cores()
+    solr_cores = SolrApi(SOLR_URL.get(), self.user).cores()
     return core_name in solr_cores

+ 3 - 3
apps/search/src/search/templates/admin_collection_facets.mako

@@ -618,10 +618,10 @@ ${ commonheader(_('Search'), "search", user, "40px") | n,unicode }
 
     self.isSaveBtnVisible = ko.observable(false);
 
-    self.fields = ko.observableArray(${ hue_collection.fields | n,unicode });
+    self.fields = ko.observableArray(${ hue_collection.fields(user) | n,unicode });
 
     self.fullFields = {}
-    $.each(${ hue_collection.fields_data | n,unicode }, function(index, field) {
+    $.each(${ hue_collection.fields_data(user) | n,unicode }, function(index, field) {
       self.fullFields[field.name] = field;
     });
 
@@ -632,7 +632,7 @@ ${ commonheader(_('Search'), "search", user, "40px") | n,unicode }
     }));
 
     // Remove already selected fields
-    self.fieldFacetsList = ko.observableArray(${ hue_collection.fields | n,unicode });
+    self.fieldFacetsList = ko.observableArray(${ hue_collection.fields(user) | n,unicode });
     $.each(self.fieldFacets(), function(index, field) {
       self.fieldFacetsList.remove(field.field);
     });

+ 1 - 1
apps/search/src/search/templates/admin_collection_highlighting.mako

@@ -95,7 +95,7 @@ ${ commonheader(_('Search'), "search", user, "40px") | n,unicode }
 <script type="text/javascript">
   function ViewModel() {
     var self = this;
-    self.fields = ko.observableArray(${ hue_collection.fields | n,unicode });
+    self.fields = ko.observableArray(${ hue_collection.fields(user) | n,unicode });
 
     var highlighting = ${ hue_collection.result.get_highlighting() | n,unicode };
     var properties = ${ hue_collection.result.get_properties() | n,unicode };

+ 3 - 3
apps/search/src/search/templates/admin_collection_sorting.mako

@@ -145,7 +145,7 @@ ${ commonheader(_('Search'), "search", user, "40px") | n,unicode }
 
   function ViewModel() {
     var self = this;
-    self.fields = ko.observableArray(${ hue_collection.fields | n,unicode });
+    self.fields = ko.observableArray(${ hue_collection.fields(user) | n,unicode });
 
     self.isEnabled = ko.observable(${ hue_collection.sorting.data | n,unicode }.properties.is_enabled);
 
@@ -153,7 +153,7 @@ ${ commonheader(_('Search'), "search", user, "40px") | n,unicode }
       return new SortingField(obj.field, obj.label, obj.asc);
     }));
 
-    self.sortingFieldsList = ko.observableArray(${ hue_collection.fields | n,unicode });
+    self.sortingFieldsList = ko.observableArray(${ hue_collection.fields(user) | n,unicode });
 
     self.newFieldSelect = ko.observable();
     self.newFieldSelect.subscribe(function (newValue) {
@@ -175,7 +175,7 @@ ${ commonheader(_('Search'), "search", user, "40px") | n,unicode }
       if (self.newFieldLabel() == ""){
         self.newFieldLabel(self.newFieldSelect());
       }
-      self.sortingFields.push(new SortingField(self.newFieldSelect(), self.newFieldLabel(), self.newFieldAscDesc()=="asc"));
+      self.sortingFields.push(new SortingField(self.newFieldSelect(), self.newFieldLabel(), self.newFieldAscDesc() == "asc"));
       self.newFieldLabel("");
       self.newFieldAscDesc("asc");
       self.isEnabled(true);

+ 1 - 1
apps/search/src/search/templates/admin_collection_template.mako

@@ -483,7 +483,7 @@ ${ commonheader(_('Search'), "search", user, "40px") | n,unicode }
 
     function ViewModel() {
       var self = this;
-      self.availableFields = ko.observableArray(${ hue_collection.fields | n,unicode });
+      self.availableFields = ko.observableArray(${ hue_collection.fields(user) | n,unicode });
       self.selectedVisualField = ko.observable();
       self.selectedVisualFunction = ko.observable();
       self.selectedVisualFunction.subscribe(function (newValue) {

+ 15 - 15
apps/search/src/search/views.py

@@ -69,7 +69,7 @@ def index(request):
     try:
       hue_collection = Collection.objects.get(id=collection_id)
       solr_query['collection'] = hue_collection.name
-      response = SolrApi(SOLR_URL.get()).query(solr_query, hue_collection)
+      response = SolrApi(SOLR_URL.get(), request.user).query(solr_query, hue_collection)
     except Exception, e:
       error['message'] = unicode(str(e), "utf8")
   else:
@@ -123,7 +123,7 @@ def admin_collections(request, is_redirect=False):
 @allow_admin_only
 def admin_collections_import(request):
   if request.method == 'POST':
-    searcher = SearchController()
+    searcher = SearchController(request.user)
     status = 0
     err_message = _('Error')
     result = {
@@ -141,7 +141,7 @@ def admin_collections_import(request):
     return HttpResponse(json.dumps(result), mimetype="application/json")
   else:
     if request.GET.get('format') == 'json':
-      searcher = SearchController()
+      searcher = SearchController(request.user)
       new_solr_collections = searcher.get_new_collections()
       massaged_collections = []
       for coll in new_solr_collections:
@@ -170,7 +170,7 @@ def admin_collection_delete(request):
     raise PopupException(_('POST request required.'))
 
   id = request.POST.get('id')
-  searcher = SearchController()
+  searcher = SearchController(request.user)
   response = {
     'id': searcher.delete_collection(id)
   }
@@ -184,7 +184,7 @@ def admin_collection_copy(request):
     raise PopupException(_('POST request required.'))
 
   id = request.POST.get('id')
-  searcher = SearchController()
+  searcher = SearchController(request.user)
   response = {
     'id': searcher.copy_collection(id)
   }
@@ -195,12 +195,12 @@ def admin_collection_copy(request):
 @allow_admin_only
 def admin_collection_properties(request, collection_id):
   hue_collection = Collection.objects.get(id=collection_id)
-  solr_collection = SolrApi(SOLR_URL.get()).collection_or_core(hue_collection)
+  solr_collection = SolrApi(SOLR_URL.get(), request.user).collection_or_core(hue_collection)
 
   if request.method == 'POST':
     collection_form = CollectionForm(request.POST, instance=hue_collection)
     if collection_form.is_valid():
-      searcher = SearchController()
+      searcher = SearchController(request.user)
       hue_collection = collection_form.save(commit=False)
       hue_collection.is_core_only = not searcher.is_collection(hue_collection.name)
       hue_collection.save()
@@ -220,7 +220,7 @@ def admin_collection_properties(request, collection_id):
 @allow_admin_only
 def admin_collection_template(request, collection_id):
   hue_collection = Collection.objects.get(id=collection_id)
-  solr_collection = SolrApi(SOLR_URL.get()).collection_or_core(hue_collection)
+  solr_collection = SolrApi(SOLR_URL.get(), request.user).collection_or_core(hue_collection)
 
   if request.method == 'POST':
     hue_collection.result.update_from_post(request.POST)
@@ -235,7 +235,7 @@ def admin_collection_template(request, collection_id):
   solr_query['start'] = 0
   solr_query['facets'] = 0
 
-  response = SolrApi(SOLR_URL.get()).query(solr_query, hue_collection)
+  response = SolrApi(SOLR_URL.get(), request.user).query(solr_query, hue_collection)
 
   return render('admin_collection_template.mako', request, {
     'solr_collection': solr_collection,
@@ -247,7 +247,7 @@ def admin_collection_template(request, collection_id):
 @allow_admin_only
 def admin_collection_facets(request, collection_id):
   hue_collection = Collection.objects.get(id=collection_id)
-  solr_collection = SolrApi(SOLR_URL.get()).collection_or_core(hue_collection)
+  solr_collection = SolrApi(SOLR_URL.get(), request.user).collection_or_core(hue_collection)
 
   if request.method == 'POST':
     hue_collection.facets.update_from_post(request.POST)
@@ -263,7 +263,7 @@ def admin_collection_facets(request, collection_id):
 @allow_admin_only
 def admin_collection_sorting(request, collection_id):
   hue_collection = Collection.objects.get(id=collection_id)
-  solr_collection = SolrApi(SOLR_URL.get()).collection_or_core(hue_collection)
+  solr_collection = SolrApi(SOLR_URL.get(), request.user).collection_or_core(hue_collection)
 
   if request.method == 'POST':
     hue_collection.sorting.update_from_post(request.POST)
@@ -279,7 +279,7 @@ def admin_collection_sorting(request, collection_id):
 @allow_admin_only
 def admin_collection_highlighting(request, collection_id):
   hue_collection = Collection.objects.get(id=collection_id)
-  solr_collection = SolrApi(SOLR_URL.get()).collection_or_core(hue_collection)
+  solr_collection = SolrApi(SOLR_URL.get(), request.user).collection_or_core(hue_collection)
 
   if request.method == 'POST':
     hue_collection.result.update_from_post(request.POST)
@@ -297,7 +297,7 @@ def admin_collection_highlighting(request, collection_id):
 @allow_admin_only
 def admin_collection_solr_properties(request, collection_id):
   hue_collection = Collection.objects.get(id=collection_id)
-  solr_collection = SolrApi(SOLR_URL.get()).collection_or_core(hue_collection)
+  solr_collection = SolrApi(SOLR_URL.get(), request.user).collection_or_core(hue_collection)
 
   content = render('admin_collection_properties_solr_properties.mako', request, {
     'solr_collection': solr_collection,
@@ -310,7 +310,7 @@ def admin_collection_solr_properties(request, collection_id):
 @allow_admin_only
 def admin_collection_schema(request, collection_id):
   hue_collection = Collection.objects.get(id=collection_id)
-  solr_schema = SolrApi(SOLR_URL.get()).schema(hue_collection.name)
+  solr_schema = SolrApi(SOLR_URL.get(), request.user).schema(hue_collection.name)
 
   content = {
     'solr_schema': solr_schema.decode('utf-8')
@@ -328,7 +328,7 @@ def query_suggest(request, collection_id, query=""):
   solr_query['q'] = query
 
   try:
-    response = SolrApi(SOLR_URL.get()).suggest(solr_query, hue_collection)
+    response = SolrApi(SOLR_URL.get(), request.user).suggest(solr_query, hue_collection)
     result['message'] = response
     result['status'] = 0
   except Exception, e: