浏览代码

Merge branch 'shiro' of http://git.mooctest.net/summer/main-site into shiro

csc 8 年之前
父节点
当前提交
94c5857e0b
共有 29 个文件被更改,包括 1070 次插入154 次删除
  1. 32 12
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ShiroConfiguration.java
  2. 399 58
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/realm/ShiroRealm.java
  3. 3 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/UserDao.java
  4. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/App.java
  5. 22 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/AssignedTask.java
  6. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Case.java
  7. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Group.java
  8. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Group2Worker.java
  9. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ManagerSubsiteFeature.java
  10. 18 18
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Permission.java
  11. 15 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Role2Permission.java
  12. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Task.java
  13. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Task2AssistantManager.java
  14. 21 10
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/User.java
  15. 80 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/User2Permission.java
  16. 70 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/permission/CasePermission.java
  17. 71 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/permission/GroupPermission.java
  18. 27 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/permission/MyPermissionResolver.java
  19. 78 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/permission/TaskPermission.java
  20. 31 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/util/data/EncryptionUtil.java
  21. 2 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ContestController.java
  22. 27 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/PermissionController.java
  23. 29 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/RoleController.java
  24. 24 21
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/TestController.java
  25. 15 15
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/PermissionVO.java
  26. 19 8
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/UserVO.java
  27. 5 5
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/PermissionVOWraper.java
  28. 4 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/UserVOWrapper.java
  29. 1 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/TaskLogicImpl.java

+ 32 - 12
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ShiroConfiguration.java

@@ -1,6 +1,7 @@
 package cn.iselab.mooctest.site.configure;
 
 import cn.iselab.mooctest.site.configure.realm.ShiroRealm;
+import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.spring.LifecycleBeanPostProcessor;
 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
@@ -12,6 +13,7 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.DependsOn;
 
 import javax.servlet.Filter;
+import javax.sql.DataSource;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -37,8 +39,21 @@ public class ShiroConfiguration {
      */
     @Bean(name = "shiroRealm")
     @DependsOn("lifecycleBeanPostProcessor")
-    public ShiroRealm shiroRealm() {
+    public ShiroRealm shiroRealm(DataSource dataSource) {
         ShiroRealm realm = new ShiroRealm();
+        realm.setDataSource(dataSource);
+        realm.setPermissionsLookupEnabled(true);
+        realm.setAuthenticationQuery("SELECT password FROM user WHERE email = ? or mobile = ?");
+        realm.setPermissionsQuery("SELECT CONCAT_WS(':',p.resource, p.operation) " +
+                "FROM permission p, role r, role_2_permission r2p " +
+                "WHERE p.id = r2p.permission_id " +
+                "AND r.id = r2p.role_id " +
+                "AND r.name = ?");
+        realm.setUserRolesQuery("SELECT r.name " +
+                "FROM role r, user u, user_2_role u2r " +
+                "WHERE (u.email = ? OR u.mobile = ?) " +
+                "AND u.id = u2r.user_id " +
+                "AND u2r.role_id = r.id");
         return realm;
     }
 
@@ -54,12 +69,11 @@ public class ShiroConfiguration {
 
     /**
      * SecurityManager,权限管理,这个类组合了登陆,登出,权限,session的处理,是个比较重要的类。
-     *
      */
     @Bean(name = "securityManager")
-    public DefaultWebSecurityManager securityManager() {
+    public DefaultWebSecurityManager securityManager(ShiroRealm shiroRealm) {
         DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
-        securityManager.setRealm(shiroRealm());
+        securityManager.setRealm(shiroRealm);
 //        securityManager.setCacheManager(ehCacheManager());
         return securityManager;
     }
@@ -69,9 +83,9 @@ public class ShiroConfiguration {
      * 它主要保持了三项数据,securityManager,filters,filterChainDefinitionManager。
      */
     @Bean(name = "shiroFilter")
-    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
+    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
-        shiroFilterFactoryBean.setSecurityManager(securityManager());
+        shiroFilterFactoryBean.setSecurityManager(securityManager);
 
         Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
 //        LogoutFilter logoutFilter = new LogoutFilter();
@@ -80,10 +94,16 @@ public class ShiroConfiguration {
         shiroFilterFactoryBean.setFilters(filters);
 
         Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>();
-        filterChainDefinitionManager.put("/logout", "logout");
-        filterChainDefinitionManager.put("/user/**", "authc,roles[ROLE_USER]");
-        filterChainDefinitionManager.put("/events/**", "authc,roles[ROLE_ADMIN]");
-        filterChainDefinitionManager.put("/**", "anon");
+//        filterChainDefinitionManager.put("/logout", "logout");
+//        filterChainDefinitionManager.put("/user/**", "authc,roles[ROLE_USER]");
+//        filterChainDefinitionManager.put("/events/**", "authc,roles[ROLE_ADMIN]");
+        filterChainDefinitionManager.put("/api/worker/**", "roles[worker]");
+        filterChainDefinitionManager.put("/api/manager/**", "roles[manager]");
+        filterChainDefinitionManager.put("/api/admin/**", "roles[admin]");
+        filterChainDefinitionManager.put("/api/manager/task/{id}", "roles[manager], perms[task:view:{id}]");
+
+//        filterChainDefinitionManager.put("/**", "roles[worker]");
+        filterChainDefinitionManager.put("/api/common/captcha", "roles[worker]");
         shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);
 
 
@@ -108,9 +128,9 @@ public class ShiroConfiguration {
      * 内部使用AopAllianceAnnotationsAuthorizingMethodInterceptor来拦截用以下注解的方法。
      */
     @Bean
-    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
+    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
         AuthorizationAttributeSourceAdvisor aASA = new AuthorizationAttributeSourceAdvisor();
-        aASA.setSecurityManager(securityManager());
+        aASA.setSecurityManager(securityManager);
         return aASA;
     }
 

+ 399 - 58
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/realm/ShiroRealm.java

@@ -1,94 +1,435 @@
 package cn.iselab.mooctest.site.configure.realm;
+/*
+ * 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.
+ */
 
-import cn.iselab.mooctest.site.dao.PermissionDao;
-import cn.iselab.mooctest.site.dao.RoleDao;
-import cn.iselab.mooctest.site.dao.User2RoleDao;
-import cn.iselab.mooctest.site.dao.UserDao;
-import cn.iselab.mooctest.site.models.Permission;
-import cn.iselab.mooctest.site.models.Role;
-import cn.iselab.mooctest.site.models.User;
-import cn.iselab.mooctest.site.models.User2Role;
-import cn.iselab.mooctest.site.util.data.EncryptionUtil;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authc.*;
+import org.apache.shiro.authz.AuthorizationException;
 import org.apache.shiro.authz.AuthorizationInfo;
 import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.config.ConfigurationException;
 import org.apache.shiro.realm.AuthorizingRealm;
-import org.apache.shiro.session.Session;
 import org.apache.shiro.subject.PrincipalCollection;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.shiro.util.ByteSource;
+import org.apache.shiro.util.JdbcUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
 
-import java.util.ArrayList;
-import java.util.List;
 
 /**
- * Created by Liu on 2017/6/6.
+ * Realm that allows authentication and authorization via JDBC calls.  The default queries suggest a potential schema
+ * for retrieving the user's password for authentication, and querying for a user's roles and permissions.  The
+ * default queries can be overridden by setting the query properties of the realm.
+ * <p/>
+ * If the default implementation
+ * of authentication and authorization cannot handle your schema, this class can be subclassed and the
+ * appropriate methods overridden. (usually {@link #doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)},
+ * {@link #getRoleNamesForUser(java.sql.Connection, String)}, and/or {@link #getPermissions(java.sql.Connection, String, java.util.Collection)}
+ * <p/>
+ * This realm supports caching by extending from {@link org.apache.shiro.realm.AuthorizingRealm}.
+ *
+ * @since 0.2
  */
 public class ShiroRealm extends AuthorizingRealm {
 
+    //TODO - complete JavaDoc
 
-    @Autowired
-    private UserDao userDao;
-    @Autowired
-    private PermissionDao permissionDao;
-    @Autowired
-    private User2RoleDao user2RoleDao;
-    @Autowired
-    private RoleDao roleDao;
+    /*--------------------------------------------
+    |             C O N S T A N T S             |
+    ============================================*/
+    /**
+     * The default query used to retrieve account data for the user.
+     */
+    protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?";
 
-    @Override
-    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
+    /**
+     * The default query used to retrieve account data for the user when {@link #saltStyle} is COLUMN.
+     */
+    protected static final String DEFAULT_SALTED_AUTHENTICATION_QUERY = "select password, password_salt from users where username = ?";
+
+    /**
+     * The default query used to retrieve the roles that apply to a user.
+     */
+    protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?";
+
+    /**
+     * The default query used to retrieve permissions that apply to a particular role.
+     */
+    protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";
+
+    private static final Logger LOG = LoggerFactory.getLogger(ShiroRealm.class);
+
+    /**
+     * Password hash salt configuration. <ul>
+     * <li>NO_SALT - password hashes are not salted.</li>
+     * <li>CRYPT - password hashes are stored in unix crypt format.</li>
+     * <li>COLUMN - salt is in a separate column in the database.</li>
+     * <li>EXTERNAL - salt is not stored in the database. {@link #getSaltForUser(String)} will be called
+     * to get the salt</li></ul>
+     */
+    public enum SaltStyle {
+        NO_SALT, CRYPT, COLUMN, EXTERNAL
+    }
+
+    ;
+
+    /*--------------------------------------------
+    |    I N S T A N C E   V A R I A B L E S    |
+    ============================================*/
+    protected DataSource dataSource;
+
+    protected String authenticationQuery = DEFAULT_AUTHENTICATION_QUERY;
 
-        User user = userDao.findByAccount((String) principalCollection.getPrimaryPrincipal());
+    protected String userRolesQuery = DEFAULT_USER_ROLES_QUERY;
 
+    protected String permissionsQuery = DEFAULT_PERMISSIONS_QUERY;
 
-        //把principals放session中 key=userId value=principals
-        SecurityUtils.getSubject().getSession().setAttribute(String.valueOf(user.getId()), SecurityUtils.getSubject().getPrincipals());
+    protected boolean permissionsLookupEnabled = false;
 
+    protected SaltStyle saltStyle = SaltStyle.NO_SALT;
 
+    /*--------------------------------------------
+    |         C O N S T R U C T O R S           |
+    ============================================*/
 
-        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
-        List<Role> roles = new ArrayList<>();
-        for (User2Role user2Role : user2RoleDao.findByUserId(user.getId())) {
-            roles.add(roleDao.findOne(user2Role.getRoleId()));
+    /*--------------------------------------------
+    |  A C C E S S O R S / M O D I F I E R S    |
+    ============================================*/
+
+    /**
+     * Sets the datasource that should be used to retrieve connections used by this realm.
+     *
+     * @param dataSource the SQL data source.
+     */
+    public void setDataSource(DataSource dataSource) {
+        this.dataSource = dataSource;
+    }
+
+    /**
+     * Overrides the default query used to retrieve a user's password during authentication.  When using the default
+     * implementation, this query must take the user's username as a single parameter and return a single result
+     * with the user's password as the first column.  If you require a solution that does not match this query
+     * structure, you can override {@link #doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)} or
+     * just {@link #getPasswordForUser(java.sql.Connection, String)}
+     *
+     * @param authenticationQuery the query to use for authentication.
+     * @see #DEFAULT_AUTHENTICATION_QUERY
+     */
+    public void setAuthenticationQuery(String authenticationQuery) {
+        this.authenticationQuery = authenticationQuery;
+    }
+
+    /**
+     * Overrides the default query used to retrieve a user's roles during authorization.  When using the default
+     * implementation, this query must take the user's username as a single parameter and return a row
+     * per role with a single column containing the role name.  If you require a solution that does not match this query
+     * structure, you can override {@link #doGetAuthorizationInfo(PrincipalCollection)} or just
+     * {@link #getRoleNamesForUser(java.sql.Connection, String)}
+     *
+     * @param userRolesQuery the query to use for retrieving a user's roles.
+     * @see #DEFAULT_USER_ROLES_QUERY
+     */
+    public void setUserRolesQuery(String userRolesQuery) {
+        this.userRolesQuery = userRolesQuery;
+    }
+
+    /**
+     * Overrides the default query used to retrieve a user's permissions during authorization.  When using the default
+     * implementation, this query must take a role name as the single parameter and return a row
+     * per permission with three columns containing the fully qualified name of the permission class, the permission
+     * name, and the permission actions (in that order).  If you require a solution that does not match this query
+     * structure, you can override {@link #doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)} or just
+     * {@link #getPermissions(java.sql.Connection, String, java.util.Collection)}</p>
+     * <p/>
+     * <b>Permissions are only retrieved if you set {@link #permissionsLookupEnabled} to true.  Otherwise,
+     * this query is ignored.</b>
+     *
+     * @param permissionsQuery the query to use for retrieving permissions for a role.
+     * @see #DEFAULT_PERMISSIONS_QUERY
+     * @see #setPermissionsLookupEnabled(boolean)
+     */
+    public void setPermissionsQuery(String permissionsQuery) {
+        this.permissionsQuery = permissionsQuery;
+    }
+
+    /**
+     * Enables lookup of permissions during authorization.  The default is "false" - meaning that only roles
+     * are associated with a user.  Set this to true in order to lookup roles <b>and</b> permissions.
+     *
+     * @param permissionsLookupEnabled true if permissions should be looked up during authorization, or false if only
+     *                                 roles should be looked up.
+     */
+    public void setPermissionsLookupEnabled(boolean permissionsLookupEnabled) {
+        this.permissionsLookupEnabled = permissionsLookupEnabled;
+    }
+
+    /**
+     * Sets the salt style.  See {@link #saltStyle}.
+     *
+     * @param saltStyle new SaltStyle to set.
+     */
+    public void setSaltStyle(SaltStyle saltStyle) {
+        this.saltStyle = saltStyle;
+        if (saltStyle == SaltStyle.COLUMN && authenticationQuery.equals(DEFAULT_AUTHENTICATION_QUERY)) {
+            authenticationQuery = DEFAULT_SALTED_AUTHENTICATION_QUERY;
+        }
+    }
+
+    /*--------------------------------------------
+    |               M E T H O D S               |
+    ============================================*/
+
+    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
+
+        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
+        String username = upToken.getUsername();
+
+        // Null username is invalid
+        if (username == null) {
+            throw new AccountException("Null usernames are not allowed by this realm.");
         }
 
-        for (Permission permission : permissionDao.findByUserId(user.getId())) {
-            if (!StringUtils.isEmpty(permission.getName())) {
-                info.addStringPermission(permission.getName());
+        Connection conn = null;
+        SimpleAuthenticationInfo info = null;
+        try {
+            conn = dataSource.getConnection();
+
+            String password = null;
+            String salt = null;
+            switch (saltStyle) {
+                case NO_SALT:
+                    password = getPasswordForUser(conn, username)[0];
+                    break;
+                case CRYPT:
+                    // TODO: separate password and hash from getPasswordForUser[0]
+                    throw new ConfigurationException("Not implemented yet");
+                    //break;
+                case COLUMN:
+                    String[] queryResults = getPasswordForUser(conn, username);
+                    password = queryResults[0];
+                    salt = queryResults[1];
+                    break;
+                case EXTERNAL:
+                    password = getPasswordForUser(conn, username)[0];
+                    salt = getSaltForUser(username);
+            }
+
+            if (password == null) {
+                throw new UnknownAccountException("No account found for user [" + username + "]");
             }
+
+            info = new SimpleAuthenticationInfo(username, password.toCharArray(), getName());
+
+            if (salt != null) {
+                info.setCredentialsSalt(ByteSource.Util.bytes(salt));
+            }
+
+        } catch (SQLException e) {
+            final String message = "There was a SQL error while authenticating user [" + username + "]";
+            if (LOG.isErrorEnabled()) {
+                LOG.error(message, e);
+            }
+
+            // Rethrow any SQL errors as an authentication exception
+            throw new AuthenticationException(message, e);
+        } finally {
+            JdbcUtils.closeConnection(conn);
         }
-        //赋予权限
-//        for(Permission permission:permissionService.findByUserId(user.getId())){
-//            if(StringUtils.isNotBlank(permission.getPermCode()))
-//            info.addStringPermission(permission.getName());
-//        }
-
-        //设置登录次数、时间
-//        userService.updateUserLogin(user);
+
         return info;
     }
 
+    private String[] getPasswordForUser(Connection conn, String username) throws SQLException {
+
+        String[] result;
+        boolean returningSeparatedSalt = false;
+        switch (saltStyle) {
+            case NO_SALT:
+            case CRYPT:
+            case EXTERNAL:
+                result = new String[1];
+                break;
+            default:
+                result = new String[2];
+                returningSeparatedSalt = true;
+        }
+
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = conn.prepareStatement(authenticationQuery);
+            ps.setString(1, username);
+            ps.setString(2, username);
+
+            // Execute query
+            rs = ps.executeQuery();
+
+            // Loop over results - although we are only expecting one result, since usernames should be unique
+            boolean foundResult = false;
+            while (rs.next()) {
+
+                // Check to ensure only one row is processed
+                if (foundResult) {
+                    throw new AuthenticationException("More than one user row found for user [" + username + "]. Usernames must be unique.");
+                }
+
+                result[0] = rs.getString(1);
+                if (returningSeparatedSalt) {
+                    result[1] = rs.getString(2);
+                }
+
+                foundResult = true;
+            }
+        } finally {
+            JdbcUtils.closeResultSet(rs);
+            JdbcUtils.closeStatement(ps);
+        }
+
+        return result;
+    }
+
+    /**
+     * This implementation of the interface expects the principals collection to return a String username keyed off of
+     * this realm's {@link #getName() name}
+     *
+     * @see #getAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)
+     */
     @Override
-    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
+    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
 
-        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
-        String userName = token.getUsername();
+        //null usernames are invalid
+        if (principals == null) {
+            throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
+        }
 
-        User user = userDao.findByAccount(token.getUsername());
-        if (user != null) {
-            if (!user.getPassword().equals(EncryptionUtil.encryptMD5(new String(token.getPassword())))) {
-                throw new IncorrectCredentialsException();
+        String username = (String) getAvailablePrincipal(principals);
+
+        Connection conn = null;
+        Set<String> roleNames = null;
+        Set<String> permissions = null;
+        try {
+            conn = dataSource.getConnection();
+
+            // Retrieve roles and permissions from database
+            roleNames = getRoleNamesForUser(conn, username);
+            if (permissionsLookupEnabled) {
+                permissions = getPermissions(conn, username, roleNames);
             }
 
-            //设置用户session
-            Session session = SecurityUtils.getSubject().getSession();
-            session.setAttribute("user", user);
-            return new SimpleAuthenticationInfo(userName, user.getPassword(), getName());
-        } else {
-            throw new UnknownAccountException();
+        } catch (SQLException e) {
+            final String message = "There was a SQL error while authorizing user [" + username + "]";
+            if (LOG.isErrorEnabled()) {
+                LOG.error(message, e);
+            }
+
+            // Rethrow any SQL errors as an authorization exception
+            throw new AuthorizationException(message, e);
+        } finally {
+            JdbcUtils.closeConnection(conn);
         }
+
+        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
+        info.setStringPermissions(permissions);
+        return info;
+
+    }
+
+    protected Set<String> getRoleNamesForUser(Connection conn, String username) throws SQLException {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Set<String> roleNames = new LinkedHashSet<String>();
+        try {
+            ps = conn.prepareStatement(userRolesQuery);
+            ps.setString(1, username);
+            ps.setString(2, username);
+
+            // Execute query
+            rs = ps.executeQuery();
+
+            // Loop over results and add each returned role to a set
+            while (rs.next()) {
+
+                String roleName = rs.getString(1);
+
+                // Add the role to the list of names if it isn't null
+                if (roleName != null) {
+                    roleNames.add(roleName);
+                } else {
+                    if (LOG.isWarnEnabled()) {
+                        LOG.warn("Null role name found while retrieving role names for user [" + username + "]");
+                    }
+                }
+            }
+        } finally {
+            JdbcUtils.closeResultSet(rs);
+            JdbcUtils.closeStatement(ps);
+        }
+        return roleNames;
+    }
+
+    protected Set<String> getPermissions(Connection conn, String username, Collection<String> roleNames) throws SQLException {
+
+//        SecurityUtils.getSubject().isPermitted()
+        PreparedStatement ps = null;
+        Set<String> permissions = new LinkedHashSet<String>();
+        try {
+            ps = conn.prepareStatement(permissionsQuery);
+            for (String roleName : roleNames) {
+
+                ps.setString(1, roleName);
+
+                ResultSet rs = null;
+
+                try {
+                    // Execute query
+                    rs = ps.executeQuery();
+
+                    // Loop over results and add each returned role to a set
+                    while (rs.next()) {
+
+                        String permissionString = rs.getString(1);
+
+                        // Add the permission to the set of permissions
+                        permissions.add(permissionString);
+                    }
+                } finally {
+                    JdbcUtils.closeResultSet(rs);
+                }
+
+            }
+        } finally {
+            JdbcUtils.closeStatement(ps);
+        }
+
+        return permissions;
+    }
+
+    protected String getSaltForUser(String username) {
+        return username;
     }
 
-}
+}

+ 3 - 2
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/UserDao.java

@@ -1,6 +1,5 @@
 package cn.iselab.mooctest.site.dao;
 
-import cn.iselab.mooctest.site.models.Admin;
 import cn.iselab.mooctest.site.models.User;
 import org.springframework.data.repository.CrudRepository;
 
@@ -12,5 +11,7 @@ import javax.transaction.Transactional;
 @Transactional
 public interface UserDao extends CrudRepository<User, Long> {
 
-    User findByAccount(String username);
+    User findByEmail(String email);
+
+    User findByMobile(String mobile);
 }

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/App.java

@@ -44,6 +44,17 @@ public class App {
     @Column(name = "create_time")
     private Timestamp createTime = new Timestamp(System.currentTimeMillis());
 
+    @Column(name = "owner_id")
+    private Long ownerId;
+
+    public Long getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(Long ownerId) {
+        this.ownerId = ownerId;
+    }
+
     public Timestamp getCreateTime() {
         return createTime;
     }

+ 22 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/AssignedTask.java

@@ -48,6 +48,28 @@ public class AssignedTask {
     @Column(name = "task_id")
     private Long taskId;
 
+    @Column(name = "owner_id")
+    private Long ownerId;
+
+    @Column(name = "participant_id")
+    private Long participantId;
+
+    public Long getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(Long ownerId) {
+        this.ownerId = ownerId;
+    }
+
+    public Long getParticipantId() {
+        return participantId;
+    }
+
+    public void setParticipantId(Long participantId) {
+        this.participantId = participantId;
+    }
+
     public Long getId() {
         return id;
     }

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Case.java

@@ -55,6 +55,17 @@ public class Case {
     @Column(name = "is_deleted")
     private Boolean deleted = false;
 
+    @Column(name = "owner_id")
+    private Long ownerId;
+
+    public Long getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(Long ownerId) {
+        this.ownerId = ownerId;
+    }
+
     public Long getId() {
         return id;
     }

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Group.java

@@ -26,6 +26,17 @@ public class Group {
     @Column(name = "allow_join")
     private Boolean allowJoin = true;
 
+    @Column(name = "owner_id")
+    private Long ownerId;
+
+    public Long getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(Long ownerId) {
+        this.ownerId = ownerId;
+    }
+
     public Boolean getAllowJoin() {
         return allowJoin;
     }

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Group2Worker.java

@@ -22,9 +22,20 @@ public class Group2Worker {
     @Column(name = "worker_id")
     private Long workerId;
 
+    @Column(name = "participant_id")
+    private Long participantId;
+
     @Column(name = "record_create_time")
     private Timestamp recordCreateTime;
 
+    public Long getParticipantId() {
+        return participantId;
+    }
+
+    public void setParticipantId(Long participantId) {
+        this.participantId = participantId;
+    }
+
     public Long getId() {
         return id;
     }

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ManagerSubsiteFeature.java

@@ -25,6 +25,17 @@ public class ManagerSubsiteFeature {
     @Column(name = "subsite_id")
     private Long subsiteId;
 
+    @Column(name = "owner_id")
+    private Long ownerId;
+
+    public Long getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(Long ownerId) {
+        this.ownerId = ownerId;
+    }
+
     public Long getId() {
         return id;
     }

+ 18 - 18
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Permission.java

@@ -7,7 +7,7 @@ import java.sql.Timestamp;
  * Created by sean on 17/2/25.
  */
 @Entity
-@Table(name = "role")
+@Table(name = "permission")
 public class Permission {
 
     @Id
@@ -17,23 +17,15 @@ public class Permission {
     @Column(name = "name")
     private String name;
 
-    @Column(name  = "role_id")
-    private Long roleId;
+    @Column(name = "resource")
+    private String resource;
+
+    @Column(name = "operation")
+    private String operation;
 
     @Column(name = "create_time")
     private Timestamp createTime = new Timestamp(System.currentTimeMillis());
 
-    @Column(name = "url")
-    private String url;
-
-    public String getUrl() {
-        return url;
-    }
-
-    public void setUrl(String url) {
-        this.url = url;
-    }
-
     public Long getId() {
         return id;
     }
@@ -50,12 +42,20 @@ public class Permission {
         this.name = name;
     }
 
-    public Long getRoleId() {
-        return roleId;
+    public String getResource() {
+        return resource;
+    }
+
+    public void setResource(String resource) {
+        this.resource = resource;
+    }
+
+    public String getOperation() {
+        return operation;
     }
 
-    public void setRoleId(Long roleId) {
-        this.roleId = roleId;
+    public void setOperation(String operation) {
+        this.operation = operation;
     }
 
     public Timestamp getCreateTime() {

+ 15 - 2
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Role2Permission.java

@@ -1,6 +1,7 @@
 package cn.iselab.mooctest.site.models;
 
 import javax.persistence.*;
+import java.sql.Timestamp;
 
 /**
  * @author sean
@@ -13,12 +14,24 @@ public class Role2Permission {
     @Id
     @GeneratedValue
     private Long id;
-    @Column(name = "rid")
+
+    @Column(name = "role_id")
     private Long roleId;
 
-    @Column(name = "pid")
+    @Column(name = "permission_id")
     private Long permissionId;
 
+    @Column(name = "create_time")
+    private Timestamp createTime= new Timestamp(System.currentTimeMillis());
+
+    public Timestamp getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Timestamp createTime) {
+        this.createTime = createTime;
+    }
+
     public Long getId() {
         return id;
     }

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Task.java

@@ -39,6 +39,17 @@ public class Task {
     @Column(name = "subsite_id")
     private Long subsiteId;
 
+    @Column(name = "owner_id")
+    private Long ownerId;
+
+    public Long getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(Long ownerId) {
+        this.ownerId = ownerId;
+    }
+
     public Long getId() {
         return id;
     }

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Task2AssistantManager.java

@@ -24,9 +24,20 @@ public class Task2AssistantManager {
     @Column(name = "manager_id")
     private Long managerId;
 
+    @Column(name = "owner_id")
+    private Long ownerId;
+
     @Column(name = "status")
     private Integer status;
 
+    public Long getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(Long ownerId) {
+        this.ownerId = ownerId;
+    }
+
     public Long getId() {
         return id;
     }

+ 21 - 10
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/User.java

@@ -14,8 +14,11 @@ public class User {
     @GeneratedValue
     private Long id;
 
-    @Column(name = "account")
-    private String account;
+    @Column(name = "email")
+    private String email;
+
+    @Column(name = "mobile")
+    private String mobile;
 
     @Column(name = "password")
     private String password;
@@ -23,20 +26,28 @@ public class User {
     @Column(name = "create_time")
     private Timestamp createTime = new Timestamp(System.currentTimeMillis());
 
-    public Long getId() {
-        return id;
+    public String getEmail() {
+        return email;
     }
 
-    public void setId(Long id) {
-        this.id = id;
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getMobile() {
+        return mobile;
     }
 
-    public String getAccount() {
-        return account;
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
     }
 
-    public void setAccount(String account) {
-        this.account = account;
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
     }
 
     public String getPassword() {

+ 80 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/User2Permission.java

@@ -0,0 +1,80 @@
+package cn.iselab.mooctest.site.models;
+
+import javax.persistence.*;
+import java.sql.Timestamp;
+
+/**
+ * @author sean
+ * @date 2017-06-20.
+ */
+@Entity
+@Table(name = "user_2_permission")
+public class User2Permission {
+
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Column(name = "user_id")
+    private Long userId;
+
+    @Column(name = "resource")
+    private String resource;
+
+    @Column(name = "operation")
+    private String operation;
+
+    @Column(name = "instance_id")
+    private Long instanceId;
+
+    @Column(name = "create_time")
+    private Timestamp createTime = new Timestamp(System.currentTimeMillis());
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getResource() {
+        return resource;
+    }
+
+    public void setResource(String resource) {
+        this.resource = resource;
+    }
+
+    public String getOperation() {
+        return operation;
+    }
+
+    public void setOperation(String operation) {
+        this.operation = operation;
+    }
+
+    public Long getInstanceId() {
+        return instanceId;
+    }
+
+    public void setInstanceId(Long instanceId) {
+        this.instanceId = instanceId;
+    }
+
+    public Timestamp getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Timestamp createTime) {
+        this.createTime = createTime;
+    }
+}

+ 70 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/permission/CasePermission.java

@@ -0,0 +1,70 @@
+package cn.iselab.mooctest.site.permission;
+
+import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.service.CaseService;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.Permission;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author sean
+ * @date 2017-06-25.
+ */
+public class CasePermission implements Permission {
+
+    @Autowired
+    private CaseService caseService;
+
+    private String resource;
+
+    private String operation;
+
+    private String instanceId;
+
+    public CasePermission() {
+    }
+
+    public CasePermission(String permissionStr) {
+        String[] strs = permissionStr.split("\\+");
+        if (strs.length > 1) {
+            this.resource = strs[1];
+        }
+        if (this.resource == null || "".equals(this.resource)) {
+            this.resource = "*";
+        }
+        if (strs.length > 2) {
+            this.operation = strs[2];
+        }
+        if (strs.length > 3) {
+            this.instanceId = strs[3];
+        }
+        if (this.instanceId == null || "".equals(this.instanceId)) {
+            this.instanceId = "*";
+        }
+
+    }
+
+    @Override
+    public boolean implies(Permission p) {
+
+        if (!(p instanceof TaskPermission)) {
+            return false;
+        }
+        CasePermission cp = (CasePermission) p;
+        User user = (User) SecurityUtils.getSubject().getPrincipal();
+
+        if (!"*".equals(cp.resource) && !this.resource.equals(cp.resource)) {
+            return false;
+        }
+        if (!"*".equals(cp.operation) && !this.operation.equals(cp.operation)) {
+            return false;
+        }
+        if (caseService.getCaseById(Long.valueOf(instanceId)).getOwnerId() != user.getId()) {
+            return false;
+        }
+        if (caseService.getCaseById(Long.valueOf(instanceId)).getVisible() == false) {
+            return false;
+        }
+        return false;
+    }
+}

+ 71 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/permission/GroupPermission.java

@@ -0,0 +1,71 @@
+package cn.iselab.mooctest.site.permission;
+
+import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.service.GroupService;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.Permission;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author sean
+ * @date 2017-06-25.
+ */
+public class GroupPermission implements Permission {
+
+    @Autowired
+    private GroupService groupService;
+
+    private String resource;
+
+    private String operation;
+
+    private String instanceId;
+
+    public GroupPermission() {
+    }
+
+    public GroupPermission(String permissionStr) {
+        String[] strs = permissionStr.split("\\+");
+        if (strs.length > 1) {
+            this.resource = strs[1];
+        }
+        if (this.resource == null || "".equals(this.resource)) {
+            this.resource = "*";
+        }
+        if (strs.length > 2) {
+            this.operation = strs[2];
+        }
+        if (strs.length > 3) {
+            this.instanceId = strs[3];
+        }
+        if (this.instanceId == null || "".equals(this.instanceId)) {
+            this.instanceId = "*";
+        }
+
+    }
+
+    @Override
+    public boolean implies(Permission p) {
+        if (!(p instanceof TaskPermission)) {
+            return false;
+        }
+        GroupPermission gp = (GroupPermission) p;
+        User user = (User) SecurityUtils.getSubject().getPrincipal();
+
+        if (!"*".equals(gp.resource) && !this.resource.equals(gp.resource)) {
+            return false;
+        }
+        if (!"*".equals(gp.operation) && !this.operation.equals(gp.operation)) {
+            return false;
+        }
+
+        if (!groupService.checkWorkerExist(user.getId(), Long.valueOf(instanceId))) {
+            return false;
+        }
+        if (groupService.getGroup(Long.valueOf(instanceId)).getOwnerId() != user.getId()) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+}

+ 27 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/permission/MyPermissionResolver.java

@@ -0,0 +1,27 @@
+package cn.iselab.mooctest.site.permission;
+
+import org.apache.shiro.authz.Permission;
+import org.apache.shiro.authz.permission.PermissionResolver;
+import org.apache.shiro.authz.permission.WildcardPermission;
+
+/**
+ * @author sean
+ * @date 2017-06-25.
+ */
+public class MyPermissionResolver implements PermissionResolver {
+
+    @Override
+    public Permission resolvePermission(String permissionString) {
+        if (permissionString.startsWith("task")) {
+            return new TaskPermission(permissionString);
+        }
+        if (permissionString.startsWith("group")) {
+            return new GroupPermission(permissionString);
+        }
+        if (permissionString.startsWith("case")) {
+            return new CasePermission(permissionString);
+        } else {
+            return new WildcardPermission(permissionString);
+        }
+    }
+}

+ 78 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/permission/TaskPermission.java

@@ -0,0 +1,78 @@
+package cn.iselab.mooctest.site.permission;
+
+import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.service.AssignedTaskService;
+import cn.iselab.mooctest.site.service.TaskService;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.Permission;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author sean
+ * @date 2017-06-25.
+ */
+public class TaskPermission implements Permission {
+
+    @Autowired
+    private AssignedTaskService assignedTaskService;
+
+    @Autowired
+    private TaskService taskService;
+
+    private String resource;
+
+    private String operation;
+
+    private String instanceId;
+
+    public TaskPermission() {
+    }
+
+    public TaskPermission(String permissionStr) {
+        String[] strs = permissionStr.split("\\+");
+        if (strs.length > 1) {
+            this.resource = strs[1];
+        }
+        if (this.resource == null || "".equals(this.resource)) {
+            this.resource = "*";
+        }
+        if (strs.length > 2) {
+            this.operation = strs[2];
+        }
+        if (strs.length > 3) {
+            this.instanceId = strs[3];
+        }
+        if (this.instanceId == null || "".equals(this.instanceId)) {
+            this.instanceId = "*";
+        }
+
+    }
+
+
+    @Override
+    public boolean implies(Permission p) {
+        if (!(p instanceof TaskPermission)) {
+            return false;
+        }
+        TaskPermission tp = (TaskPermission) p;
+        User user = (User) SecurityUtils.getSubject().getPrincipal();
+
+        if (!"*".equals(tp.resource) && !this.resource.equals(tp.resource)) {
+            return false;
+        }
+        if (!"*".equals(tp.operation) && !this.operation.equals(tp.operation)) {
+            return false;
+        }
+        //for worker:
+        if (assignedTaskService.getAssignedTask((Long.valueOf(instanceId)), user.getId()) == null) {
+            return false;
+        }
+        //for manager
+        if (taskService.getTask(Long.valueOf(instanceId)).getOwnerId() != user.getId()) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+}

+ 31 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/util/data/EncryptionUtil.java

@@ -79,6 +79,37 @@ public class EncryptionUtil {
         }
     }
 
+    public static String transferMD5ToMD5Hex(String str) {
+
+        String value = null;
+        // 用来将字节转换成 16 进制表示的字符
+        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+        BASE64Decoder base64Decoder = new BASE64Decoder();
+        try {
+            byte[] temp = base64Decoder.decodeBuffer(str);
+            // 每个字节用 16 进制表示的话,使用两个字符
+            char hex[] = new char[16 * 2];
+
+            // 表示转换结果中对应的字符位置
+            int k = 0;
+            // 从第一个字节开始,对 MD5 的每一个字节转换成 16 进制字符的转换
+            for (int i = 0; i < 16; i++) {
+                byte b = temp[i];
+                // 取字节中高 4 位的数字转换, >>> 为逻辑右移,将符号位一起右移
+                hex[k++] = hexDigits[b >>> 4 & 0xf];
+                // 取字节中低 4 位的数字转换
+                hex[k++] = hexDigits[b & 0xf];
+            }
+
+            // 转换后的结果转换为字符串
+            value = new String(hex);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return value;
+
+    }
+
     public static String encryptDES(String content) throws Exception {
         return encryptDES(content, defaultKey);
     }

+ 2 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ContestController.java

@@ -2,7 +2,6 @@ package cn.iselab.mooctest.site.web.ctrl;
 
 import cn.iselab.mooctest.site.common.constant.UrlConstants;
 import cn.iselab.mooctest.site.util.http.RequestUtils;
-import cn.iselab.mooctest.site.web.data.ContestStatisticsVO;
 import cn.iselab.mooctest.site.web.data.ContestVO;
 import cn.iselab.mooctest.site.web.logic.ContestLogic;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -53,4 +52,6 @@ public class ContestController {
         System.out.println("同步学生信息");
         return contestLogic.sycnStudentArea();
     }
+
+
 }

+ 27 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/PermissionController.java

@@ -0,0 +1,27 @@
+package cn.iselab.mooctest.site.web.ctrl;
+
+import cn.iselab.mooctest.site.web.data.PermissionVO;
+import cn.iselab.mooctest.site.web.logic.PermissionLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author sean
+ * @date 2017-06-15.
+ */
+@RestController
+@RequestMapping("/api/test/permission")
+public class PermissionController {
+
+    @Autowired
+    private PermissionLogic permissionLogic;
+
+//    @RequiresPermissions("permission:index")
+    @ResponseBody
+    @RequestMapping(value = "/list}", method = RequestMethod.GET)
+    public List<PermissionVO> getUrlListByUserId(@PathVariable("id") Long userId) {
+        return permissionLogic.getPermissionsByUserId(userId);
+    }
+}

+ 29 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/RoleController.java

@@ -0,0 +1,29 @@
+package cn.iselab.mooctest.site.web.ctrl;
+
+import cn.iselab.mooctest.site.web.data.RoleVO;
+import cn.iselab.mooctest.site.web.logic.RoleLogic;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author sean
+ * @date 2017-06-15.
+ */
+@RestController
+@RequestMapping("/api/test/role")
+public class RoleController {
+
+    @Autowired
+    private RoleLogic roleLogic;
+
+    @RequiresPermissions("role:index")
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    @ResponseBody
+    public List<RoleVO> getRoleListByUserId(@PathVariable("id") Long userId) {
+        return roleLogic.getRolesByUserId(userId);
+    }
+
+}

+ 24 - 21
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/TestController.java

@@ -2,6 +2,7 @@ package cn.iselab.mooctest.site.web.ctrl;
 
 import cn.iselab.mooctest.site.common.enums.SessionKey;
 import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.util.data.EncryptionUtil;
 import cn.iselab.mooctest.site.web.data.PermissionVO;
 import cn.iselab.mooctest.site.web.data.RoleVO;
 import cn.iselab.mooctest.site.web.data.UserVO;
@@ -35,18 +36,20 @@ public class TestController {
     private PermissionLogic permissionLogic;
 
     @RequestMapping(value = "/api/test/getSession", method = RequestMethod.GET)
-    public String getSession(HttpSession session){
-        return session.getAttribute(SessionKey.IDENTITY.toString()) + "_" + session.getAttribute(SessionKey.ID.toString());
+    public String getSession(HttpSession session) {
+        return session.getAttribute(SessionKey.IDENTITY.toString()) + "_" +
+                session.getAttribute(SessionKey.ID.toString());
     }
 
-    @RequestMapping(value="/api/test/login",method=RequestMethod.POST)
-    public String login(@RequestBody User user, BindingResult bindingResult, RedirectAttributes redirectAttributes){
-        if(bindingResult.hasErrors()){
+    @RequestMapping(value = "/api/test/login", method = RequestMethod.POST)
+    public String login(@RequestBody User user, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
+        if (bindingResult.hasErrors()) {
             return "login";
         }
 
-        String username = user.getAccount();
-        UsernamePasswordToken token = new UsernamePasswordToken(user.getAccount(), user.getPassword());
+        String username = (user.getEmail()==null)?user.getMobile():user.getEmail();
+        UsernamePasswordToken token = new UsernamePasswordToken(username,
+                EncryptionUtil.encryptMD5(user.getPassword()));
         //获取当前的Subject
         Subject currentUser = SecurityUtils.getSubject();
         try {
@@ -56,36 +59,36 @@ public class TestController {
 //            System.out.println("对用户[" + username + "]进行登录验证..验证开始");
             currentUser.login(token);
 //            System.out.println("对用户[" + username + "]进行登录验证..验证通过");
-        }catch(UnknownAccountException uae){
+        } catch (UnknownAccountException uae) {
             System.out.println("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
             redirectAttributes.addFlashAttribute("message", "未知账户");
-        }catch(IncorrectCredentialsException ice){
+        } catch (IncorrectCredentialsException ice) {
             System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
             redirectAttributes.addFlashAttribute("message", "密码不正确");
-        }catch(LockedAccountException lae){
+        } catch (LockedAccountException lae) {
             System.out.println("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");
             redirectAttributes.addFlashAttribute("message", "账户已锁定");
-        }catch(ExcessiveAttemptsException eae){
+        } catch (ExcessiveAttemptsException eae) {
             System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");
             redirectAttributes.addFlashAttribute("message", "用户名或密码错误次数过多");
-        }catch(AuthenticationException ae){
+        } catch (AuthenticationException ae) {
             //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
             System.out.println("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");
             ae.printStackTrace();
             redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");
         }
         //验证是否登录成功
-        if(currentUser.isAuthenticated()){
+        if (currentUser.isAuthenticated()) {
             System.out.println("用户[" + username + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
             return "redirect:/api/test/user/1";
-        }else{
+        } else {
             token.clear();
             return "redirect:/api/test/login";
         }
     }
 
-    @RequestMapping(value="/api/test/logout",method=RequestMethod.GET)
-    public String logout(RedirectAttributes redirectAttributes ){
+    @RequestMapping(value = "/api/test/logout", method = RequestMethod.GET)
+    public String logout(RedirectAttributes redirectAttributes) {
         //使用权限管理工具进行用户的退出,跳出登录,给出提示信息
         SecurityUtils.getSubject().logout();
         redirectAttributes.addFlashAttribute("message", "您已安全退出");
@@ -93,13 +96,13 @@ public class TestController {
     }
 
     @RequestMapping("/api/test/403")
-    public String unauthorizedRole(){
+    public String unauthorizedRole() {
         System.out.println("------没有权限-------");
         return "403";
     }
 
     @RequestMapping(value = "/api/test/user/{userId:\\d+}", method = RequestMethod.GET)
-    public String getUserList(@PathVariable("userId") long userId){
+    public String getUserList(@PathVariable("userId") long userId) {
 //        model.put("userList", userDao.getList());
 //        User user = userDao.findOne(userId);
 //        return user.getAccount();
@@ -107,17 +110,17 @@ public class TestController {
     }
 
     @RequestMapping(value = "api/test/register", method = RequestMethod.POST)
-    public UserVO register(@RequestBody UserVO userVO){
+    public UserVO register(@RequestBody UserVO userVO) {
         return userLogic.register(userVO);
     }
 
     @RequestMapping(value = "api/test/user/{id:\\d+}/roleList", method = RequestMethod.GET)
-    public List<RoleVO> getRoleListByUserId(@PathVariable("id")Long userId){
+    public List<RoleVO> getRoleListByUserId(@PathVariable("id") Long userId) {
         return roleLogic.getRolesByUserId(userId);
     }
 
     @RequestMapping(value = "api/test/user/{id:\\d+/permissionList}", method = RequestMethod.GET)
-    public List<PermissionVO> getUrlListByUserId(@PathVariable("id")Long userId){
+    public List<PermissionVO> getUrlListByUserId(@PathVariable("id") Long userId) {
         return permissionLogic.getPermissionsByUserId(userId);
     }
 }

+ 15 - 15
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/PermissionVO.java

@@ -13,11 +13,11 @@ public class PermissionVO {
 
     private String name;
 
-    private Long roleId;
+    private String resource;
 
-    private Long createTime;
+    private String operation;
 
-    private String url;
+    private Long createTime;
 
     public Long getId() {
         return id;
@@ -35,27 +35,27 @@ public class PermissionVO {
         this.name = name;
     }
 
-    public Long getRoleId() {
-        return roleId;
+    public String getResource() {
+        return resource;
     }
 
-    public void setRoleId(Long roleId) {
-        this.roleId = roleId;
+    public void setResource(String resource) {
+        this.resource = resource;
     }
 
-    public Long getCreateTime() {
-        return createTime;
+    public String getOperation() {
+        return operation;
     }
 
-    public void setCreateTime(Long createTime) {
-        this.createTime = createTime;
+    public void setOperation(String operation) {
+        this.operation = operation;
     }
 
-    public String getUrl() {
-        return url;
+    public Long getCreateTime() {
+        return createTime;
     }
 
-    public void setUrl(String url) {
-        this.url = url;
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
     }
 }

+ 19 - 8
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/UserVO.java

@@ -11,12 +11,30 @@ public class UserVO extends BaseVO{
 
     private Long id;
 
-    private String account;
+    private String email;
+
+    private String mobile;
 
     private String password;
 
     private Long createTime;
 
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
+    }
+
     public Long getId() {
         return id;
     }
@@ -25,13 +43,6 @@ public class UserVO extends BaseVO{
         this.id = id;
     }
 
-    public String getAccount() {
-        return account;
-    }
-
-    public void setAccount(String account) {
-        this.account = account;
-    }
 
     public String getPassword() {
         return password;

+ 5 - 5
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/PermissionVOWraper.java

@@ -19,9 +19,9 @@ public class PermissionVOWraper extends BaseWrapper<PermissionVO, Permission>{
 
         permissionVO.setCreateTime(permission.getCreateTime().getTime());
         permissionVO.setId(permission.getId());
-        permission.setName(permission.getName());
-        permission.setRoleId(permission.getRoleId());
-        permission.setUrl(permission.getUrl());
+        permissionVO.setName(permission.getName());
+        permissionVO.setOperation(permission.getOperation());
+        permissionVO.setResource(permission.getResource());
         return permissionVO;
     }
 
@@ -30,8 +30,8 @@ public class PermissionVOWraper extends BaseWrapper<PermissionVO, Permission>{
         Permission permission = new Permission();
 
         permission.setCreateTime(new Timestamp(data.getCreateTime()));
-        permission.setUrl(data.getUrl());
-        permission.setRoleId(data.getRoleId());
+        permission.setOperation(data.getOperation());
+        permission.setResource(data.getResource());
         permission.setName(data.getName());
         permission.setId(data.getId());
         return permission;

+ 4 - 2
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/UserVOWrapper.java

@@ -19,8 +19,9 @@ public class UserVOWrapper extends BaseWrapper<UserVO, User> {
 
         userVO.setCreateTime(user.getCreateTime().getTime());
         userVO.setId(user.getId());
-        userVO.setAccount(user.getAccount());
         userVO.setPassword(user.getPassword());
+        userVO.setEmail(user.getEmail());
+        userVO.setMobile(user.getMobile());
         return userVO;
     }
 
@@ -31,7 +32,8 @@ public class UserVOWrapper extends BaseWrapper<UserVO, User> {
         user.setCreateTime(new Timestamp(data.getCreateTime()));
         user.setId(data.getId());
         user.setPassword(data.getPassword());
-        user.setAccount(data.getAccount());
+        user.setEmail(data.getEmail());
+        user.setMobile(data.getMobile());
         return user;
     }
 }

+ 1 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/TaskLogicImpl.java

@@ -351,6 +351,7 @@ public class TaskLogicImpl extends BaseLogic implements TaskLogic {
 			throw new HttpBadRequestException("task not belong to the manager");
 		}
 
+//		currUser.ispermitted(task(id));
 		List<AssignedTaskVO> allAssignedTasks = getAssignedTasks(taskId);
 
 		if (task.getManagerId() == managerId) {