Repository: kylin
Updated Branches:
  refs/heads/2.x-staging 92fdaec6a -> 3578d8b97


KYLIN-1365, Kylin ACL enhance filter unaccessabe project


Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/3578d8b9
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/3578d8b9
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/3578d8b9

Branch: refs/heads/2.x-staging
Commit: 3578d8b9772496da7ce6c7ce4428cf49ec844595
Parents: 92fdaec
Author: janzhongi <[email protected]>
Authored: Tue Jan 26 14:47:42 2016 +0800
Committer: janzhongi <[email protected]>
Committed: Tue Jan 26 14:47:55 2016 +0800

----------------------------------------------------------------------
 .../rest/controller/ProjectController.java      | 139 +++++++++++++-
 .../apache/kylin/rest/service/CubeService.java  |   2 +-
 server/src/main/resources/kylinSecurity.xml     |   2 +-
 webapp/app/js/controllers/auth.js               |   9 +-
 webapp/app/js/controllers/cubeSchema.js         |   2 +-
 webapp/app/js/controllers/models.js             |   7 +-
 webapp/app/js/controllers/page.js               |  38 +---
 webapp/app/js/controllers/projects.js           | 192 +++++++++----------
 webapp/app/js/listeners.js                      |  50 ++++-
 webapp/app/js/model/modelsManager.js            |  13 +-
 webapp/app/js/model/projectModel.js             |  21 ++
 webapp/app/js/services/projects.js              |   1 +
 webapp/app/partials/login.html                  |  16 +-
 webapp/app/partials/models/models_tree.html     |  15 +-
 14 files changed, 342 insertions(+), 165 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/server/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
----------------------------------------------------------------------
diff --git 
a/server/src/main/java/org/apache/kylin/rest/controller/ProjectController.java 
b/server/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
index a561e97..5e65b3b 100644
--- 
a/server/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
+++ 
b/server/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
@@ -19,17 +19,31 @@
 package org.apache.kylin.rest.controller;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.kylin.common.persistence.AclEntity;
+import org.apache.kylin.cube.CubeInstance;
 import org.apache.kylin.metadata.project.ProjectInstance;
+import org.apache.kylin.rest.constant.Constant;
 import org.apache.kylin.rest.exception.InternalErrorException;
 import org.apache.kylin.rest.request.CreateProjectRequest;
 import org.apache.kylin.rest.request.UpdateProjectRequest;
+import org.apache.kylin.rest.service.AccessService;
+import org.apache.kylin.rest.service.CubeService;
 import org.apache.kylin.rest.service.ProjectService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.acls.domain.GrantedAuthoritySid;
+import org.springframework.security.acls.domain.PrincipalSid;
+import org.springframework.security.acls.model.AccessControlEntry;
+import org.springframework.security.acls.model.Acl;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -48,7 +62,10 @@ public class ProjectController extends BasicController {
 
     @Autowired
     private ProjectService projectService;
-
+    @Autowired
+    private AccessService accessService;
+    @Autowired
+    private CubeService cubeService;
     /**
      * Get available project list
      * 
@@ -61,6 +78,120 @@ public class ProjectController extends BasicController {
         return projectService.listAllProjects(limit, offset);
     }
 
+    @RequestMapping(value = "/readable", method = {RequestMethod.GET})
+    @ResponseBody
+    public List<ProjectInstance> getReadableProjects(@RequestParam(value = 
"limit", required = false) Integer limit, @RequestParam(value = "offset", 
required = false) Integer offset) {
+        List<ProjectInstance> readableProjects = new 
ArrayList<ProjectInstance>();
+        //list all projects first
+        List<ProjectInstance> projectInstances = 
projectService.listAllProjects(limit, offset);
+
+        //get user infomation
+        Authentication authentication = 
SecurityContextHolder.getContext().getAuthentication();
+        UserDetails userDetails = null;
+        if (authentication == null) {
+            logger.debug("authentication is null.");
+            throw new InternalErrorException("Can not find authentication 
infomation.");
+        }
+        if (authentication.getPrincipal() instanceof UserDetails) {
+            logger.debug("authentication.getPrincipal() is " + 
authentication.getPrincipal());
+            userDetails = (UserDetails) authentication.getPrincipal();
+        }
+        if (authentication.getDetails() instanceof UserDetails) {
+            logger.debug("authentication.getDetails() is " + 
authentication.getDetails());
+            userDetails = (UserDetails) authentication.getDetails();
+        }
+
+        //check if ROLE_ADMIN return all,also get user role list
+        List<String> userAuthority = new ArrayList<>();
+        for (GrantedAuthority auth : authentication.getAuthorities()) {
+            userAuthority.add(auth.getAuthority());
+            if (auth.getAuthority().equals(Constant.ROLE_ADMIN))
+                return projectInstances;
+        }
+        String userName = userDetails.getUsername();
+        for (ProjectInstance projectInstance : projectInstances) {
+
+            boolean hasProjectPermission = false;
+            AclEntity ae = accessService.getAclEntity("ProjectInstance", 
projectInstance.getId());
+            Acl projectAcl = accessService.getAcl(ae);
+            //project no Acl info will be skipped
+            if(projectAcl == null){
+                continue;
+            }
+
+            //project owner has permission
+            if 
(((PrincipalSid)projectAcl.getOwner()).getPrincipal().equals(userName)) {
+                readableProjects.add(projectInstance);
+                continue;
+            }
+
+            //check project permission and role
+            for (AccessControlEntry ace : projectAcl.getEntries()) {
+                if( ace.getSid() instanceof PrincipalSid && 
((PrincipalSid)ace.getSid()).getPrincipal().equals(userName)) {
+                    hasProjectPermission = true;
+                    readableProjects.add(projectInstance);
+                    break;
+
+                }else if(ace.getSid() instanceof GrantedAuthoritySid){
+                    String projectAuthority = ((GrantedAuthoritySid) 
ace.getSid()).getGrantedAuthority();
+                    if(userAuthority.contains(projectAuthority)){
+                        hasProjectPermission = true;
+                        readableProjects.add(projectInstance);
+                        break;
+                    }
+
+                }
+
+            }
+            if (!hasProjectPermission) {
+                List<CubeInstance> cubeInstances = 
cubeService.listAllCubes(projectInstance.getName());
+
+                for (CubeInstance cubeInstance : cubeInstances) {
+                    if(cubeInstance == null){
+                        continue;
+                    }
+                    boolean hasCubePermission = false;
+                    AclEntity cubeAe = 
accessService.getAclEntity("CubeInstance", cubeInstance.getId());
+                    Acl cubeAcl = accessService.getAcl(cubeAe);
+                    //cube no Acl info will not be used to filter project
+                    if(cubeAcl == null){
+                        continue;
+                    }
+                    //cube owner will have permission to read project
+                    if 
(((PrincipalSid)cubeAcl.getOwner()).getPrincipal().equals(userName)) {
+                        hasProjectPermission = true;
+                        break;
+                    }
+                    for (AccessControlEntry cubeAce : cubeAcl.getEntries()) {
+
+                        if (cubeAce.getSid() instanceof PrincipalSid && 
((PrincipalSid)cubeAce.getSid()).getPrincipal().equals(userName)) {
+                            hasCubePermission = true;
+                            break;
+                        }
+                        else if(cubeAce.getSid() instanceof 
GrantedAuthoritySid) {
+                            String cubeAuthority = ((GrantedAuthoritySid) 
cubeAce.getSid()).getGrantedAuthority();
+                            if(userAuthority.contains(cubeAuthority)){
+                                hasCubePermission = true;
+                                break;
+                            }
+
+                        }
+                    }
+                    if (hasCubePermission) {
+                        hasProjectPermission = true;
+                        break;
+                    }
+                }
+                if (hasProjectPermission) {
+                    readableProjects.add(projectInstance);
+                }
+            }
+
+
+        }
+        return readableProjects;
+    }
+
     @RequestMapping(value = "", method = { RequestMethod.POST })
     @ResponseBody
     public ProjectInstance saveProject(@RequestBody CreateProjectRequest 
projectRequest) {
@@ -114,5 +245,11 @@ public class ProjectController extends BasicController {
     public void setProjectService(ProjectService projectService) {
         this.projectService = projectService;
     }
+    public void setAccessService(AccessService accessService) {
+        this.accessService = accessService;
+    }
 
+    public void setCubeService(CubeService cubeService) {
+        this.cubeService = cubeService;
+    }
 }

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/server/src/main/java/org/apache/kylin/rest/service/CubeService.java
----------------------------------------------------------------------
diff --git 
a/server/src/main/java/org/apache/kylin/rest/service/CubeService.java 
b/server/src/main/java/org/apache/kylin/rest/service/CubeService.java
index a0ae6be..0d8d4d5 100644
--- a/server/src/main/java/org/apache/kylin/rest/service/CubeService.java
+++ b/server/src/main/java/org/apache/kylin/rest/service/CubeService.java
@@ -206,7 +206,7 @@ public class CubeService extends BasicService {
         return createdCube;
     }
 
-    private List<CubeInstance> listAllCubes(String projectName) {
+    public List<CubeInstance> listAllCubes(String projectName) {
         ProjectManager projectManager = getProjectManager();
         ProjectInstance project = projectManager.getProject(projectName);
         if (project == null) {

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/server/src/main/resources/kylinSecurity.xml
----------------------------------------------------------------------
diff --git a/server/src/main/resources/kylinSecurity.xml 
b/server/src/main/resources/kylinSecurity.xml
index 4a9b929..c9c0fff 100644
--- a/server/src/main/resources/kylinSecurity.xml
+++ b/server/src/main/resources/kylinSecurity.xml
@@ -192,7 +192,7 @@
                        <scr:intercept-url pattern="/api/streaming*/**" 
access="isAuthenticated()" />
                        <scr:intercept-url pattern="/api/job*/**" 
access="isAuthenticated()" />
                        <scr:intercept-url pattern="/api/admin/config" 
access="permitAll" />
-                       <scr:intercept-url pattern="/api/projects" 
access="permitAll" />
+                       <scr:intercept-url pattern="/api/projects*/*" 
access="isAuthenticated()" />
                        <scr:intercept-url pattern="/api/admin*/**" 
access="hasRole('ROLE_ADMIN')" />
                        <scr:intercept-url pattern="/api/**" 
access="isAuthenticated()" />
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/js/controllers/auth.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/auth.js 
b/webapp/app/js/controllers/auth.js
index 2e5dc75..6e5fa30 100644
--- a/webapp/app/js/controllers/auth.js
+++ b/webapp/app/js/controllers/auth.js
@@ -18,21 +18,16 @@
 
 'use strict';
 
-KylinApp.controller('LoginCtrl', function ($scope, $rootScope, $location, 
$base64, AuthenticationService, UserService) {
+KylinApp.controller('LoginCtrl', function ($scope, $rootScope, $location, 
$base64, AuthenticationService, UserService,ProjectService,ProjectModel) {
   $scope.username = null;
   $scope.password = null;
   $scope.loading = false;
 
   $scope.login = function () {
+    $rootScope.userAction.islogout = false;
     // set the basic authentication header that will be parsed in the next 
request and used to authenticate
     httpHeaders.common['Authorization'] = 'Basic ' + 
$base64.encode($scope.username + ':' + $scope.password);
     $scope.loading = true;
-    //verify project
-    if ($scope.projectModel.projects.length && 
!$scope.projectModel.selectedProject) {
-      $scope.loading = false;
-      $scope.error = "Unable to login, please select a project";
-      return;
-    }
 
     AuthenticationService.login({}, {}, function (data) {
       $scope.loading = false;

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/js/controllers/cubeSchema.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubeSchema.js 
b/webapp/app/js/controllers/cubeSchema.js
index 98ced3b..d446730 100755
--- a/webapp/app/js/controllers/cubeSchema.js
+++ b/webapp/app/js/controllers/cubeSchema.js
@@ -314,7 +314,7 @@ KylinApp.controller('CubeSchemaCtrl', function ($scope, 
QueryService, UserServic
 
     // ~ private methods
     function initProject() {
-        ProjectService.list({}, function (projects) {
+        ProjectService.listReadable({}, function (projects) {
             $scope.projects = projects;
 
             var cubeName = (!!$scope.routeParams.cubeName)? 
$scope.routeParams.cubeName:$scope.state.cubeName;

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/js/controllers/models.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/models.js 
b/webapp/app/js/controllers/models.js
index e32ccf3..0a2c31f 100644
--- a/webapp/app/js/controllers/models.js
+++ b/webapp/app/js/controllers/models.js
@@ -47,9 +47,14 @@ KylinApp.controller('ModelsCtrl', function ($scope, $q, 
$routeParams, $location,
     var defer = $q.defer();
     var queryParam = {};
     if (!$scope.projectModel.isSelectedProjectValid()) {
-      return;
+      defer.resolve([]);
+      return defer.promise;
     }
 
+    if (!$scope.projectModel.projects.length) {
+      defer.resolve([]);
+      return defer.promise;
+    }
     queryParam.projectName = $scope.projectModel.selectedProject;
     return modelsManager.list(queryParam).then(function (resp) {
       defer.resolve(resp);

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/js/controllers/page.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/page.js 
b/webapp/app/js/controllers/page.js
index 969279f..c65a264 100644
--- a/webapp/app/js/controllers/page.js
+++ b/webapp/app/js/controllers/page.js
@@ -25,7 +25,9 @@ KylinApp.controller('PageCtrl', function ($scope, $q, 
AccessService, $modal, $lo
     $log.debug(data);
     kylinConfig.initWebConfigInfo();
   });
-
+  $rootScope.userAction={
+   'islogout':false
+  }
   $scope.kylinConfig = kylinConfig;
 
   $scope.header = {show: true};
@@ -42,34 +44,12 @@ KylinApp.controller('PageCtrl', function ($scope, $q, 
AccessService, $modal, $lo
   $scope.activeTab = "";
   $scope.projectModel = ProjectModel;
   $scope.tableModel = TableModel;
-  //init
-  ProjectService.list({}, function (projects) {
-    var _projects = [];
-    angular.forEach(projects, function (project, index) {
-      $scope.listAccess(project, 'ProjectInstance');
-      _projects.push(project);
-    });
-    _projects = _.sortBy(_projects, function (i) {
-      return i.name.toLowerCase();
-    });
-
-    ProjectModel.setProjects(_projects);
-
-    var absUrl = $location.absUrl();
-
-    var projectInCookie = $cookieStore.get("project");
-    if (absUrl.indexOf("/login") == -1) {
-      var selectedProject = projectInCookie != null ? projectInCookie : null;
-      $scope.projectModel.setSelectedProject(selectedProject);
-    } else {
-      var selectedProject = $scope.projectModel.selectedProject != null ? 
$scope.projectModel.selectedProject : projectInCookie != null ? projectInCookie 
: $scope.projectModel.projects[0];
-      $scope.projectModel.setSelectedProject(selectedProject);
-    }
-  });
 
 
   // Set up common methods
   $scope.logout = function () {
+    ProjectModel.clear();
+    $rootScope.userAction.islogout = true;
     $scope.$emit('event:logoutRequest');
     $http.get(Config.service.base + 
'j_spring_security_logout').success(function () {
       UserService.setCurUser({});
@@ -110,7 +90,7 @@ KylinApp.controller('PageCtrl', function ($scope, $q, 
AccessService, $modal, $lo
   // common acl methods
   $scope.hasPermission = function (entity) {
     var curUser = UserService.getCurUser();
-    if (!curUser) {
+    if (!curUser.userDetails) {
       return curUser;
     }
 
@@ -182,8 +162,10 @@ KylinApp.controller('PageCtrl', function ($scope, $q, 
AccessService, $modal, $lo
 
   $scope.$watch('projectModel.selectedProject', function (newValue, oldValue) {
     if (newValue != oldValue) {
-      //$log.log("project updated in page controller,from:"+oldValue+" 
To:"+newValue);
-      $cookieStore.put("project", $scope.projectModel.selectedProject);
+      if(!$rootScope.userAction.islogout) {
+        //$log.log("project updated in page controller,from:"+oldValue+" 
To:"+newValue);
+        $cookieStore.put("project", $scope.projectModel.selectedProject);
+      }
     }
 
   });

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/js/controllers/projects.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/projects.js 
b/webapp/app/js/controllers/projects.js
index e0cc64d..b9dae73 100644
--- a/webapp/app/js/controllers/projects.js
+++ b/webapp/app/js/controllers/projects.js
@@ -1,96 +1,96 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-'use strict';
-
-KylinApp
-    .controller('ProjectCtrl', function ($scope, $modal, $q, ProjectService, 
MessageService,SweetAlert,$log,kylinConfig,projectConfig,ProjectModel) {
-
-        $scope.projects = [];
-        $scope.loading = false;
-        $scope.projectConfig = projectConfig;
-
-        $scope.state = { filterAttr: 'name', filterReverse: true, 
reverseColumn: 'name'};
-
-        $scope.list = function (offset, limit) {
-            offset = (!!offset) ? offset : 0;
-            limit = (!!limit) ? limit : 20;
-            var defer = $q.defer();
-            var queryParam = {offset: offset, limit: limit};
-
-            $scope.loading = true;
-            ProjectService.list(queryParam, function (projects) {
-                $scope.projects = $scope.projects.concat(projects);
-                angular.forEach(projects, function (project) {
-                    $scope.listAccess(project, 'ProjectInstance');
-                });
-                $scope.loading = false;
-                defer.resolve(projects.length);
-            });
-
-            return defer.promise;
-        }
-
-        $scope.toEdit = function(project) {
-            $modal.open({
-                templateUrl: 'project.html',
-                controller: projCtrl,
-                resolve: {
-                    projects: function () {
-                        return $scope.projects;
-                    },
-                    project: function(){
-                        return project;
-                    }
-                }
-            });
-        }
-
-        $scope.delete = function(project){
-            SweetAlert.swal({
-                title: '',
-                text: 'Are you sure to delete ?',
-                type: '',
-                showCancelButton: true,
-                confirmButtonColor: '#DD6B55',
-                confirmButtonText: "Yes",
-                closeOnConfirm: true
-            }, function(isConfirm) {
-                if(isConfirm){
-                ProjectService.delete({projecId: project.name}, function(){
-                    var pIndex = $scope.projects.indexOf(project);
-                    if (pIndex > -1) {
-                        $scope.projects.splice(pIndex, 1);
-                    }
-                ProjectModel.removeProject(project.name);
-                SweetAlert.swal('Success!',"Project [" + project.name + "] has 
been deleted successfully!", 'success');
-                },function(e){
-                    if(e.data&& e.data.exception){
-                        var message =e.data.exception;
-                        var msg = !!(message) ? message : 'Failed to take 
action.';
-                        SweetAlert.swal('Oops...', msg, 'error');
-                    }else{
-                        SweetAlert.swal('Oops...', "Failed to take action.", 
'error');
-                    }
-                });
-                }
-            });
-        }
-    }
-);
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+'use strict';
+
+KylinApp
+    .controller('ProjectCtrl', function ($scope, $modal, $q, ProjectService, 
MessageService,SweetAlert,$log,kylinConfig,projectConfig,ProjectModel) {
+
+        $scope.projects = [];
+        $scope.loading = false;
+        $scope.projectConfig = projectConfig;
+
+        $scope.state = { filterAttr: 'name', filterReverse: true, 
reverseColumn: 'name'};
+
+        $scope.list = function (offset, limit) {
+            offset = (!!offset) ? offset : 0;
+            limit = (!!limit) ? limit : 20;
+            var defer = $q.defer();
+            var queryParam = {offset: offset, limit: limit};
+
+            $scope.loading = true;
+            ProjectService.listReadable(queryParam, function (projects) {
+                $scope.projects = $scope.projects.concat(projects);
+                angular.forEach(projects, function (project) {
+                    $scope.listAccess(project, 'ProjectInstance');
+                });
+                $scope.loading = false;
+                defer.resolve(projects.length);
+            });
+
+            return defer.promise;
+        }
+
+        $scope.toEdit = function(project) {
+            $modal.open({
+                templateUrl: 'project.html',
+                controller: projCtrl,
+                resolve: {
+                    projects: function () {
+                        return $scope.projects;
+                    },
+                    project: function(){
+                        return project;
+                    }
+                }
+            });
+        }
+
+        $scope.delete = function(project){
+            SweetAlert.swal({
+                title: '',
+                text: 'Are you sure to delete ?',
+                type: '',
+                showCancelButton: true,
+                confirmButtonColor: '#DD6B55',
+                confirmButtonText: "Yes",
+                closeOnConfirm: true
+            }, function(isConfirm) {
+                if(isConfirm){
+                ProjectService.delete({projecId: project.name}, function(){
+                    var pIndex = $scope.projects.indexOf(project);
+                    if (pIndex > -1) {
+                        $scope.projects.splice(pIndex, 1);
+                    }
+                ProjectModel.removeProject(project.name);
+                SweetAlert.swal('Success!',"Project [" + project.name + "] has 
been deleted successfully!", 'success');
+                },function(e){
+                    if(e.data&& e.data.exception){
+                        var message =e.data.exception;
+                        var msg = !!(message) ? message : 'Failed to take 
action.';
+                        SweetAlert.swal('Oops...', msg, 'error');
+                    }else{
+                        SweetAlert.swal('Oops...', "Failed to take action.", 
'error');
+                    }
+                });
+                }
+            });
+        }
+    }
+);
+

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/js/listeners.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/listeners.js b/webapp/app/js/listeners.js
index 2a01fff..c35a26a 100644
--- a/webapp/app/js/listeners.js
+++ b/webapp/app/js/listeners.js
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-KylinApp.run(function ($rootScope, $http, $location, UserService, 
AuthenticationService, MessageService, loadingRequest, SweetAlert) {
+KylinApp.run(function ($rootScope, $http, $location, UserService, 
AuthenticationService, MessageService, 
$cookieStore,ProjectService,ProjectModel,AccessService,SweetAlert,loadingRequest)
 {
 
   $rootScope.permissions = {
     READ: {name: 'CUBE QUERY', value: 'READ', mask: 1},
@@ -29,10 +29,56 @@ KylinApp.run(function ($rootScope, $http, $location, 
UserService, Authentication
     AuthenticationService.ping(function (data) {
       if(!data.userDetails){
         $location.path(UserService.getHomePage());
+      }else{
+        UserService.setCurUser(data);
+        //get project info when login
+        if (!ProjectModel.projects.length&&!$rootScope.userAction.islogout) {
+
+          loadingRequest.show();
+          ProjectService.listReadable({}, function (projects) {
+            loadingRequest.hide();
+
+            if(!projects.length){
+              return;
+            }
+
+            var _projects = [];
+            _projects = _.sortBy(projects, function (i) {
+              return i.name.toLowerCase();
+            });
+            ProjectModel.setProjects(_projects);
+            var projectInCookie = $cookieStore.get("project");
+            if(projectInCookie&&ProjectModel.getIndex(projectInCookie)==-1){
+              projectInCookie = null;
+            }
+            var selectedProject = projectInCookie != null ? projectInCookie : 
null;
+            if(projectInCookie!=null){
+              selectedProject = projectInCookie;
+            }else if(UserService.hasRole('ROLE_ADMIN')){
+              selectedProject = null;
+            }else{
+              selectedProject = ProjectModel.projects[0].name
+            }
+
+            //var selectedProject = ProjectModel.selectedProject != null ? 
ProjectModel.selectedProject : projectInCookie != null ? projectInCookie : 
ProjectModel.projects[0].name;
+            ProjectModel.setSelectedProject(selectedProject);
+            angular.forEach(ProjectModel.projects, function (project, index) {
+              project.accessLoading = true;
+              AccessService.list({type: 'ProjectInstance', uuid: 
project.uuid}, function (accessEntities) {
+                project.accessLoading = false;
+                project.accessEntities = accessEntities;
+              });
+            });
+
+          },function(e){
+            loadingRequest.hide();
+            $location.path(UserService.getHomePage());
+          });
+        }
       }
-      UserService.setCurUser(data);
     });
 
+
     if ($location.url() == '' || $location.url() == '/') {
       AuthenticationService.ping(function (data) {
         UserService.setCurUser(data);

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/js/model/modelsManager.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/modelsManager.js 
b/webapp/app/js/model/modelsManager.js
index 2c3c90a..e117053 100644
--- a/webapp/app/js/model/modelsManager.js
+++ b/webapp/app/js/model/modelsManager.js
@@ -40,11 +40,14 @@ 
KylinApp.service('modelsManager',function(ModelService,CubeService,$q,AccessServ
 
             angular.forEach(_models, function (model, index) {
                 $log.info("Add model permission info");
-                modelPermission.push(
-                AccessService.list({type: "DataModelDesc", uuid: model.uuid}, 
function (accessEntities) {
-                    model.accessEntities = accessEntities;
-                }).$promise
-                )
+                if(model.uuid){
+                  modelPermission.push(
+                  AccessService.list({type: "DataModelDesc", uuid: 
model.uuid}, function (accessEntities) {
+                      model.accessEntities = accessEntities;
+                  }).$promise
+                  )
+                }
+
                 $log.info("Add cube info to model ,not detail info");
                 cubeDetail.push(
                     CubeService.list({modelName:model.name}, function (_cubes) 
{

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/js/model/projectModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/projectModel.js 
b/webapp/app/js/model/projectModel.js
index eba8273..d2d32b4 100644
--- a/webapp/app/js/model/projectModel.js
+++ b/webapp/app/js/model/projectModel.js
@@ -106,4 +106,25 @@ KylinApp.service('ProjectModel', function () {
     });
   }
 
+  this.clear = function(){
+    this.projects = [];
+    this.selectedProject = "_null";
+  }
+
+  this.clearProjects = function(){
+    this.projects = [];
+  }
+
+  this.getIndex = function(project){
+    var index = -1;
+    for (var i = 0; i < this.projects.length; i++) {
+      if (this.projects[i].name == project) {
+        index = i;
+        break;
+      }
+    }
+    return index;
+
+  }
+
 })

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/js/services/projects.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/services/projects.js 
b/webapp/app/js/services/projects.js
index 333e742..84a0a89 100644
--- a/webapp/app/js/services/projects.js
+++ b/webapp/app/js/services/projects.js
@@ -19,6 +19,7 @@
 KylinApp.factory('ProjectService', ['$resource', function ($resource, config) {
   return $resource(Config.service.url + 
'projects/:projecId/:propName/:propValue/:action', {}, {
     list: {method: 'GET', params: {}, isArray: true},
+    listReadable: {method: 'GET', params: {action:'readable'}, isArray: true},
     save: {method: 'POST', params: {}, isArray: false},
     update: {method: 'PUT', params: {}, isArray: false},
     delete: {method: 'DELETE', params: {}, isArray: false}

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/partials/login.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/login.html b/webapp/app/partials/login.html
index 79128b1..452257b 100644
--- a/webapp/app/partials/login.html
+++ b/webapp/app/partials/login.html
@@ -32,28 +32,16 @@
                             <form name="login_form" ng-submit="login()">
                                 <div class="form-group">
                                     <span class="width-100 input-icon 
input-icon-right">
-                                        <input id="username" 
class="form-control" ng-model="username" type="text" autofocus="autofocus" 
required placeholder="Username" auto-fill-sync />
+                                        <input id="username" 
class="form-control" ng-model="username" type="text" autofocus="autofocus" 
ng-required placeholder="Username" auto-fill-sync />
                                         <i class="ace-icon fa fa-user"></i>
                                     </span>
                                 </div>
                                 <div class="form-group">
                                     <span class="width-100 input-icon 
input-icon-right">
-                                        <input id="password" 
class="form-control" ng-model="password" type="password" required 
placeholder="Password" auto-fill-sync />
+                                        <input id="password" 
class="form-control" ng-model="password" type="password" ng-required 
placeholder="Password" auto-fill-sync />
                                         <i class="ace-icon fa fa-lock"></i>
                                     </span>
                                 </div>
-                                <div class="form-group">
-                                    <span>
-
-                                        <select  
ng-required="projectModel.projects.length" chosen 
ng-model="projectModel.selectedProject" 
ng-init="newAccess.permission=permissions.READ.value;"
-                                                ng-options="project.name as 
project.name for project in projectModel.projects "
-                                                style="width: 100% !important;"
-                                                data-placeholder="select a 
project"
-                                                class="chosen-select">
-                                            <option value=""></option>
-                                        </select>
-                                    </span>
-                                </div>
                                 <div class="space"></div>
                                 <div class="form-group">
                                     <a 
href="http://kylin.apache.org/community/"; target="_blank" 
class="text-muted">Login Issue?</a>

http://git-wip-us.apache.org/repos/asf/kylin/blob/3578d8b9/webapp/app/partials/models/models_tree.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/models/models_tree.html 
b/webapp/app/partials/models/models_tree.html
index 3e4a6d3..9d32c9f 100644
--- a/webapp/app/partials/models/models_tree.html
+++ b/webapp/app/partials/models/models_tree.html
@@ -25,11 +25,11 @@
           <!--<i> New </i> <span class="caret"></span>-->
         </a>
         <ul class="dropdown-menu">
-          <li ng-if="userService.hasRole('ROLE_ADMIN')">
-            <a href="models/add"  
ng-if="userService.hasRole('ROLE_MODELER')"><i class="fa fa-star"></i>New 
Model</a>
+          <li ng-if="userService.hasRole('ROLE_MODELER')">
+            <a href="models/add"><i class="fa fa-star"></i>New Model</a>
           </li>
-          <li ng-if="userService.hasRole('ROLE_ADMIN') || 
hasPermission(modelsManager.selectedModel, permissions.ADMINISTRATION.mask, 
permissions.MANAGEMENT.mask, permissions.OPERATION.mask)">
-            <a href="cubes/add" ng-if="userService.hasRole('ROLE_ADMIN')"><i 
class="fa fa-cube"></i>New Cube</a>
+          <li ng-if="userService.hasRole('ROLE_MODELER')">
+            <a href="cubes/add"><i class="fa fa-cube"></i>New Cube</a>
           </li>
 
         </ul>
@@ -51,9 +51,9 @@
 
             <div class="pull-right" showonhoverparent style="display:none;">
 
-              <a href="models/edit/{{model.name}}" data-placement="bottom" 
title="Edit Model" ng-if="userService.hasRole('ROLE_MODELER')"><span class="fa 
fa-pencil fa-lg fa-fw"></span></a>
-              <a ng-click="cloneModel(model)" title="Clone Model"  
style="cursor:pointer;margin-right: 8px;" 
ng-if="userService.hasRole('ROLE_MODELER')"><span class="fa fa-copy fa-lg 
fa-fw"></span></a>
-              <a ng-click="dropModel(model)" title="Drop Model"  
style="cursor:pointer;margin-right: 8px;" 
ng-if="userService.hasRole('ROLE_MODELER')"><span class="fa fa-trash-o fa-lg 
fa-fw"></span></a>
+              <a href="models/edit/{{model.name}}" data-placement="bottom" 
title="Edit Model" ng-if="(userService.hasRole('ROLE_ADMIN') || 
hasPermission(model, permissions.ADMINISTRATION.mask, 
permissions.MANAGEMENT.mask, permissions.OPERATION.mask))"><span class="fa 
fa-pencil fa-lg fa-fw"></span></a>
+              <a ng-click="cloneModel(model)" title="Clone Model"  
style="cursor:pointer;margin-right: 8px;" 
ng-if="(userService.hasRole('ROLE_ADMIN') || hasPermission(model, 
permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask, 
permissions.OPERATION.mask))"><span class="fa fa-copy fa-lg fa-fw"></span></a>
+              <a ng-click="dropModel(model)" title="Drop Model"  
style="cursor:pointer;margin-right: 8px;" 
ng-if="(userService.hasRole('ROLE_ADMIN') || hasPermission(model, 
permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask, 
permissions.OPERATION.mask))"><span class="fa fa-trash-o fa-lg 
fa-fw"></span></a>
             </div>
 
           </li>
@@ -64,4 +64,3 @@
 </div>
 
 <div ng-include="'partials/models/model_detail.html'"></div>
-

Reply via email to