Browse Source

Part implement of basic access control

master
LO Kam Tao Leo 4 years ago
parent
commit
a9a4306a75
  1. 1
      .classpath
  2. 10
      src/org/leolo/web/dm/Constant.java
  3. 80
      src/org/leolo/web/dm/dao/APIKeyDao.java
  4. 31
      src/org/leolo/web/dm/dao/ProjectDao.java
  5. 5
      src/org/leolo/web/dm/model/User.java
  6. 26
      src/org/leolo/web/dm/servlet/BaseServlet.java
  7. 14
      src/org/leolo/web/dm/servlet/ProjectMetadataServlet.java
  8. 26
      src/org/leolo/web/dm/util/APIKeyGenerator.java
  9. 8
      src/org/leolo/web/dm/util/package-info.java
  10. 19
      src/test/org/leolo/web/dm/APIGeneratorTester.java

1
.classpath

@ -23,5 +23,6 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

10
src/org/leolo/web/dm/Constant.java

@ -1,6 +1,16 @@
package org.leolo.web.dm;
public class Constant {
//Session name
public static final String SESSION_USER_ID = "uid";
public static final String SESSION_USER_NAME = "uname";
//Basic user information map
public static final String BUI_KEY_USER_ID = "uid";
public static final String BUI_KEY_USER_NAME = "uname";
//System parameter map
//Common value
public static final int COM_DEFAULT_USER_ID = 1;
}

80
src/org/leolo/web/dm/dao/APIKeyDao.java

@ -0,0 +1,80 @@
package org.leolo.web.dm.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.leolo.web.dm.Constant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class APIKeyDao extends BaseDao {
private static Logger log = LoggerFactory.getLogger(APIKeyDao.class);
private static ExecutorService dbPool = Executors.newFixedThreadPool(1);
public String getUsernameByApiKey(String key) {
try(
Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement("SELECT user_name FROM api_key a JOIN user u ON a.user=u.user_id WHERE api_key = ?")
){
pstmt.setString(1, key);
try(ResultSet rs = pstmt.executeQuery()){
if(rs.next()) {
return rs.getString(1);
}
}
}catch(SQLException e) {
log.error(e.getMessage(), e);
}
return null;
}
public Map<String, Object> getBasicUserInfomationBuApiKey(String key){
try(
Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement("SELECT user_id, user_name FROM api_key a JOIN user u ON a.user=u.user_id WHERE api_key = ?")
){
pstmt.setString(1, key);
try(ResultSet rs = pstmt.executeQuery()){
if(rs.next()) {
Map<String, Object> map = new Hashtable<>();
map.put(Constant.BUI_KEY_USER_ID, rs.getInt(1));
map.put(Constant.BUI_KEY_USER_NAME, rs.getString(2));
return map;
}
}
}catch(SQLException e) {
log.error(e.getMessage(), e);
}
return null;
}
public void markKeyUsed(String key) {
final long LAST_USE_TIME = System.currentTimeMillis();
dbPool.execute(new Runnable() {
@Override
public void run() {
try(
Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement("UPDATE api_key SET last_key_use = ? WHERE api_key = ?");
){
pstmt.setTimestamp(1, new Timestamp(LAST_USE_TIME));
pstmt.setString(2, key);
pstmt.executeUpdate();
}catch(SQLException e) {
log.error(e.getMessage(), e);
}
}
});
}
}

31
src/org/leolo/web/dm/dao/ProjectDao.java

@ -8,6 +8,7 @@ import java.sql.Statement;
import java.util.Collection;
import java.util.Vector;
import org.leolo.web.dm.Constant;
import org.leolo.web.dm.model.Project;
import org.leolo.web.dm.model.ProjectMode;
import org.slf4j.Logger;
@ -71,7 +72,11 @@ public class ProjectDao extends BaseDao{
return null;
}
public Collection<String> getProjectPathsIgnoreCase(String path) {
@Deprecated
public Collection<String> getProjectPathsIgnoreCase(String path){
return getProjectPathsIgnoreCase(path, Constant.COM_DEFAULT_USER_ID);
}
public Collection<String> getProjectPathsIgnoreCase(String path, int userId) {
Vector<String> names = new Vector<>();
try(
Connection conn = getConnection();
@ -114,4 +119,28 @@ public class ProjectDao extends BaseDao{
}
return null;
}
public boolean canReadProject(int projectId, int userId) {
try(
Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement("SELECT read FROM project_user WHERE project_id = ? AND user_id = ?")
){
pstmt.setInt(1, projectId);
pstmt.setInt(2, userId);
try(ResultSet rs = pstmt.executeQuery()){
if(rs.next()) {
return 1 == rs.getInt(1);
}
}
pstmt.setInt(2, Constant.COM_DEFAULT_USER_ID);
try(ResultSet rs = pstmt.executeQuery()){
if(rs.next()) {
return 1 == rs.getInt(1);
}
}
}catch(SQLException e) {
log.error(e.getMessage(), e);
}
return false;//default
}
}

5
src/org/leolo/web/dm/model/User.java

@ -0,0 +1,5 @@
package org.leolo.web.dm.model;
public class User {
}

26
src/org/leolo/web/dm/servlet/BaseServlet.java

@ -1,12 +1,16 @@
package org.leolo.web.dm.servlet;
import java.io.IOException;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.leolo.web.dm.Constant;
import org.leolo.web.dm.dao.APIKeyDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -16,7 +20,10 @@ import org.slf4j.LoggerFactory;
public class BaseServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static Logger log = LoggerFactory.getLogger(BaseServlet.class);
protected String userName = null;
protected int userId = 0;//Special UID for anonymous user
/**
* @see HttpServlet#HttpServlet()
*/
@ -29,7 +36,22 @@ public class BaseServlet extends HttpServlet {
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
log.debug("Request - [GET] {}", request.getRequestURI());
log.info("Request - [GET] {}", request.getRequestURI());
if(request.getAttribute(Constant.SESSION_USER_NAME)!=null) {
userName = request.getSession().getAttribute(Constant.SESSION_USER_NAME).toString();
userId = (Integer) request.getSession().getAttribute(Constant.SESSION_USER_ID);
}
if(request.getParameter("key") != null) {
APIKeyDao apiDao = new APIKeyDao();
String key = request.getParameter("key").toString();
log.info("Using API key {}", key);
Map<String, Object> buim = apiDao.getBasicUserInfomationBuApiKey(key);
if(buim!=null) {
userName = buim.get(Constant.BUI_KEY_USER_NAME).toString();
userId = (Integer) buim.get(Constant.BUI_KEY_USER_ID);
apiDao.markKeyUsed(key);
}
}
}
/**

14
src/org/leolo/web/dm/servlet/ProjectMetadataServlet.java

@ -38,12 +38,20 @@ public class ProjectMetadataServlet extends BaseServlet {
super.doGet(request, response);
response.setContentType("application/json");
log.info("URL: {}", request.getRequestURI());
String projectPath = request.getRequestURI().substring(request.getContextPath().length()+10);
log.info("User is {}", userName);
String projectPath = request.getRequestURI().substring(request.getContextPath().length()+10).trim();
log.info("Project Requested: {}", projectPath);
JSONObject retObj = new JSONObject();
if(projectPath.length()==0) {
//list all project
retObj.put("status", "success");
//TODO: list all project
retObj.write(response.getWriter());
return;
}
ProjectDao projDao = new ProjectDao();
Project proj = projDao.getProjectByPath(projectPath);
JSONObject retObj = new JSONObject();
if(proj==null) {
if(proj==null || projDao.canReadProject(proj.getProjectId(), userId)) {
retObj.put("status", "error");
retObj.put("message", "Specified project cannot be found");
retObj.put("requested", projectPath);

26
src/org/leolo/web/dm/util/APIKeyGenerator.java

@ -0,0 +1,26 @@
package org.leolo.web.dm.util;
import java.security.SecureRandom;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class APIKeyGenerator {
private static Logger log = LoggerFactory.getLogger(APIKeyGenerator.class);
private static Random random = new SecureRandom();
public static final int DEFAULT_LENGTH = 48;
public static final char [] AVAILABLE_CHARS = "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM-_".toCharArray();
public static String generateApiKey() {
return generateApiKey(DEFAULT_LENGTH);
}
public static String generateApiKey(final int LENGTH) {
StringBuilder sb = new StringBuilder();
for(int i=0;i<LENGTH;i++) {
sb.append(AVAILABLE_CHARS[random.nextInt(AVAILABLE_CHARS.length)]);
}
return sb.toString();
}
}

8
src/org/leolo/web/dm/util/package-info.java

@ -0,0 +1,8 @@
/**
*
*/
/**
* @author user
*
*/
package org.leolo.web.dm.util;

19
src/test/org/leolo/web/dm/APIGeneratorTester.java

@ -0,0 +1,19 @@
package test.org.leolo.web.dm;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.leolo.web.dm.util.APIKeyGenerator;
class APIGeneratorTester {
@Test
void test() {
String key1 = APIKeyGenerator.generateApiKey();
String key2 = APIKeyGenerator.generateApiKey();
System.out.println("Key 1:"+key1);
System.out.println("Key 2:"+key2);
assertNotEquals(key1, key2);
}
}
Loading…
Cancel
Save