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> -
