Java tutorial
/** * * ?? * Operation * * ? * ?? * * * Copyright (c) 2015 OpenID Foundation Japan. * This is released under the MIT License, see LICENSE file. */ package jp.or.openid.eiwg.scim.operation; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Set; import java.util.TimeZone; import java.util.UUID; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jp.or.openid.eiwg.constants.MessageConstants; import jp.or.openid.eiwg.scim.util.SCIMUtil; import jp.or.openid.eiwg.scim.util.SCIMUtilException; import org.apache.commons.lang.StringUtils; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class Operation { private int errorCode = 0; private String errorType = ""; private String errorMessage = ""; /** * ?? * * @param context * @param request */ public boolean Authentication(ServletContext context, HttpServletRequest request) throws IOException { boolean result = false; // Authorization? String authorization = request.getHeader("Authorization"); if (authorization == null || StringUtils.isEmpty(authorization)) { // setError(HttpServletResponse.SC_UNAUTHORIZED, null, MessageConstants.ERROR_UNAUTHORIZED); //return false; return true; } String[] values = authorization.split(" "); // ? setError(0, null, null); if (values.length < 2) { // setError(HttpServletResponse.SC_UNAUTHORIZED, null, MessageConstants.ERROR_UNAUTHORIZED); } else { // ???????? if ("Basic".equalsIgnoreCase(values[0])) { // HTTP Basic ? String userID; String password; String[] loginInfo = SCIMUtil.decodeBase64(values[1]).split(":"); if (loginInfo.length < 2) { // setError(HttpServletResponse.SC_UNAUTHORIZED, null, MessageConstants.ERROR_INVALID_CREDENTIALS); } else { // ?? userID = loginInfo[0]; // password = loginInfo[1]; if (StringUtils.isEmpty(userID) || StringUtils.isEmpty(password)) { // setError(HttpServletResponse.SC_UNAUTHORIZED, null, MessageConstants.ERROR_INVALID_CREDENTIALS); } else { // ???? // ??? ObjectMapper mapper = new ObjectMapper(); ArrayList<LinkedHashMap<String, Object>> adminInfoList = null; try { adminInfoList = mapper.readValue(new File(context.getRealPath("/WEB-INF/Admin.json")), new TypeReference<ArrayList<LinkedHashMap<String, Object>>>() { }); } catch (IOException e) { // setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null, MessageConstants.ERROR_UNKNOWN); e.printStackTrace(); return result; } if (adminInfoList != null && !adminInfoList.isEmpty()) { Iterator<LinkedHashMap<String, Object>> adminInfoIt = adminInfoList.iterator(); while (adminInfoIt.hasNext()) { LinkedHashMap<String, Object> adminInfo = adminInfoIt.next(); Object adminID = SCIMUtil.getAttribute(adminInfo, "id"); Object adminPassword = SCIMUtil.getAttribute(adminInfo, "password"); // id???? if (adminID != null && adminID instanceof String) { if (userID.equals(adminID.toString())) { // password???? if (adminID != null && adminID instanceof String) { if (password.equals(adminPassword.toString())) { // ?? result = true; } } break; } } } if (result != true) { // setError(HttpServletResponse.SC_UNAUTHORIZED, null, MessageConstants.ERROR_INVALID_CREDENTIALS); } } else { // setError(HttpServletResponse.SC_UNAUTHORIZED, null, MessageConstants.ERROR_INVALID_CREDENTIALS); } } } } else if ("Bearer".equalsIgnoreCase(values[0])) { // OAuth2 Bearer String token = values[1]; if (StringUtils.isEmpty(token)) { // setError(HttpServletResponse.SC_UNAUTHORIZED, null, MessageConstants.ERROR_INVALID_CREDENTIALS); } else { // ?? // ??? ObjectMapper mapper = new ObjectMapper(); ArrayList<LinkedHashMap<String, Object>> adminInfoList = null; try { adminInfoList = mapper.readValue(new File(context.getRealPath("/WEB-INF/Admin.json")), new TypeReference<ArrayList<LinkedHashMap<String, Object>>>() { }); } catch (IOException e) { // setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null, MessageConstants.ERROR_UNKNOWN); e.printStackTrace(); return result; } if (adminInfoList != null && !adminInfoList.isEmpty()) { Iterator<LinkedHashMap<String, Object>> adminInfoIt = adminInfoList.iterator(); while (adminInfoIt.hasNext()) { LinkedHashMap<String, Object> adminInfo = adminInfoIt.next(); Object adminToken = SCIMUtil.getAttribute(adminInfo, "bearer"); // token???? if (adminToken != null && adminToken instanceof String) { if (token.equals(adminToken.toString())) { // ?? result = true; break; } } } if (result != true) { // setError(HttpServletResponse.SC_UNAUTHORIZED, null, MessageConstants.ERROR_INVALID_CREDENTIALS); } } else { // setError(HttpServletResponse.SC_UNAUTHORIZED, null, MessageConstants.ERROR_INVALID_CREDENTIALS); } } } else { // setError(HttpServletResponse.SC_UNAUTHORIZED, null, MessageConstants.ERROR_INVALID_CREDENTIALS); } } return result; } /** * * * @param context * @param request * @param targetId * @param attributes * @param filter * @param sortBy * @param sortOrder * @param startIndex * @param count */ public ArrayList<LinkedHashMap<String, Object>> searchUserInfo(ServletContext context, HttpServletRequest request, String targetId, String attributes, String filter, String sortBy, String sortOrder, String startIndex, String count) { ArrayList<LinkedHashMap<String, Object>> result = null; Set<String> returnAttributeNameSet = new HashSet<>(); // ? setError(0, null, null); // ?? if (attributes != null && !attributes.isEmpty()) { // String[] tempList = attributes.split(","); for (int i = 0; i < tempList.length; i++) { String attributeName = tempList[i].trim(); // ??????? LinkedHashMap<String, Object> attributeSchema = SCIMUtil.getUserAttributeInfo(context, attributeName, true); if (attributeSchema != null && !attributeSchema.isEmpty()) { returnAttributeNameSet.add(attributeName); } else { // ??????? String message = String.format(MessageConstants.ERROR_INVALID_ATTRIBUTES, attributeName); setError(HttpServletResponse.SC_BAD_REQUEST, null, message); return result; } } } // ???????? // (sortBy)? // (sortOrder)? // ?(startIndex)? // 1??(count)? // // () // result = new ArrayList<LinkedHashMap<String, Object>>(); // ? @SuppressWarnings("unchecked") ArrayList<LinkedHashMap<String, Object>> users = (ArrayList<LinkedHashMap<String, Object>>) context .getAttribute("Users"); if (users != null && !users.isEmpty()) { Iterator<LinkedHashMap<String, Object>> usersIt = users.iterator(); while (usersIt.hasNext()) { boolean isMatched = false; LinkedHashMap<String, Object> userInfo = usersIt.next(); // id??????? if (targetId != null && !targetId.isEmpty()) { Object id = SCIMUtil.getAttribute(userInfo, "id"); if (id != null && id instanceof String) { // id???? if (targetId.equals(id.toString())) { if (filter != null && !filter.isEmpty()) { // ???? boolean matched = false; try { matched = SCIMUtil.checkUserSimpleFilter(context, userInfo, filter); } catch (SCIMUtilException e) { result = null; setError(e.getCode(), e.getType(), e.getMessage()); break; } if (matched) { isMatched = true; } } else { isMatched = true; } } } } else { if (filter != null && !filter.isEmpty()) { // ???? boolean matched = false; try { matched = SCIMUtil.checkUserSimpleFilter(context, userInfo, filter); } catch (SCIMUtilException e) { result = null; setError(e.getCode(), e.getType(), e.getMessage()); break; } if (matched) { isMatched = true; } } else { isMatched = true; } } if (isMatched) { // ?? LinkedHashMap<String, Object> resultInfo = new LinkedHashMap<String, Object>(); Iterator<String> attributeIt = userInfo.keySet().iterator(); while (attributeIt.hasNext()) { // ??? String attributeName = attributeIt.next(); // ? LinkedHashMap<String, Object> attributeSchema = SCIMUtil.getUserAttributeInfo(context, attributeName, true); Object returned = attributeSchema.get("returned"); if (returned != null && returned.toString().equalsIgnoreCase("never")) { continue; } // ? Object attributeValue = userInfo.get(attributeName); resultInfo.put(attributeName, attributeValue); } result.add(resultInfo); } } } return result; } /** * ? * * @param context * @param request * @param attributes * @param requestJson */ public LinkedHashMap<String, Object> createUserInfo(ServletContext context, HttpServletRequest request, String attributes, String requestJson) { LinkedHashMap<String, Object> result = null; Set<String> returnAttributeNameSet = new HashSet<>(); // ? setError(0, null, null); // ?? if (attributes != null && !attributes.isEmpty()) { // String[] tempList = attributes.split(","); for (int i = 0; i < tempList.length; i++) { String attributeName = tempList[i].trim(); // ??????? LinkedHashMap<String, Object> attributeSchema = SCIMUtil.getUserAttributeInfo(context, attributeName, true); if (attributeSchema != null && !attributeSchema.isEmpty()) { returnAttributeNameSet.add(attributeName); } else { // ??????? String message = String.format(MessageConstants.ERROR_INVALID_ATTRIBUTES, attributeName); setError(HttpServletResponse.SC_BAD_REQUEST, null, message); return result; } } } // ? if (requestJson == null || requestJson.isEmpty()) { // setError(HttpServletResponse.SC_BAD_REQUEST, null, MessageConstants.ERROR_INVALID_REQUEST); return result; } // (JSON)? ObjectMapper mapper = new ObjectMapper(); LinkedHashMap<String, Object> requestObject = null; try { requestObject = mapper.readValue(requestJson, new TypeReference<LinkedHashMap<String, Object>>() { }); } catch (JsonParseException e) { String datailMessage = e.getMessage(); datailMessage = datailMessage.substring(0, datailMessage.indexOf('\n')); setError(HttpServletResponse.SC_BAD_REQUEST, null, MessageConstants.ERROR_INVALID_REQUEST + "(" + datailMessage + ")"); return result; } catch (JsonMappingException e) { String datailMessage = e.getMessage(); datailMessage = datailMessage.substring(0, datailMessage.indexOf('\n')); setError(HttpServletResponse.SC_BAD_REQUEST, null, MessageConstants.ERROR_INVALID_REQUEST + "(" + datailMessage + ")"); return result; } catch (IOException e) { setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null, MessageConstants.ERROR_UNKNOWN); return result; } // ? if (requestObject != null && !requestObject.isEmpty()) { Iterator<String> attributeIt = requestObject.keySet().iterator(); while (attributeIt.hasNext()) { // ??? String attributeName = attributeIt.next(); // ? LinkedHashMap<String, Object> attributeSchema = SCIMUtil.getUserAttributeInfo(context, attributeName, true); if (attributeSchema != null) { // ???? Object mutability = attributeSchema.get("mutability"); if (mutability != null && mutability.toString().equalsIgnoreCase("readOnly")) { // readOnly String message = String.format(MessageConstants.ERROR_READONLY_ATTRIBUTE, attributeName); setError(HttpServletResponse.SC_BAD_REQUEST, null, message); return result; } // ?? // () } else { // ???? String message = String.format(MessageConstants.ERROR_UNKNOWN_ATTRIBUTE, attributeName); setError(HttpServletResponse.SC_BAD_REQUEST, null, message); return result; } } } else { // setError(HttpServletResponse.SC_BAD_REQUEST, null, MessageConstants.ERROR_INVALID_REQUEST); return result; } // ? // () LinkedHashMap<String, Object> newUserInfo = new LinkedHashMap<String, Object>(); // id? UUID uuid = UUID.randomUUID(); newUserInfo.put("id", uuid.toString()); Iterator<String> attributeIt = requestObject.keySet().iterator(); while (attributeIt.hasNext()) { // ??? String attributeName = attributeIt.next(); // ? Object attributeValue = requestObject.get(attributeName); newUserInfo.put(attributeName, attributeValue); } // meta? LinkedHashMap<String, Object> metaValues = new LinkedHashMap<String, Object>(); // meta.resourceType metaValues.put("resourceType", "User"); // meta.created SimpleDateFormat xsdDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'"); xsdDateTime.setTimeZone(TimeZone.getTimeZone("UTC")); metaValues.put("created", xsdDateTime.format(new Date())); // meta.location String location = request.getScheme() + "://" + request.getServerName(); int serverPort = request.getServerPort(); if (serverPort != 80 && serverPort != 443) { location += ":" + Integer.toString(serverPort); } location += request.getContextPath(); location += "/scim/Users/" + uuid.toString(); metaValues.put("location", location); newUserInfo.put("meta", metaValues); // (??) @SuppressWarnings("unchecked") ArrayList<LinkedHashMap<String, Object>> users = (ArrayList<LinkedHashMap<String, Object>>) context .getAttribute("Users"); if (users == null) { users = new ArrayList<LinkedHashMap<String, Object>>(); } users.add(newUserInfo); context.setAttribute("Users", users); // ?? result = new LinkedHashMap<String, Object>(); attributeIt = newUserInfo.keySet().iterator(); while (attributeIt.hasNext()) { // ??? String attributeName = attributeIt.next(); // ? LinkedHashMap<String, Object> attributeSchema = SCIMUtil.getUserAttributeInfo(context, attributeName, true); Object returned = attributeSchema.get("returned"); if (returned != null && returned.toString().equalsIgnoreCase("never")) { continue; } // ? Object attributeValue = newUserInfo.get(attributeName); result.put(attributeName, attributeValue); } return result; } /** * * * @param context * @param request * @param attributes * @param requestJson */ public LinkedHashMap<String, Object> updateUserInfo(ServletContext context, HttpServletRequest request, String targetId, String attributes, String requestJson) { LinkedHashMap<String, Object> result = null; Set<String> returnAttributeNameSet = new HashSet<>(); // ? setError(0, null, null); // ?? if (attributes != null && !attributes.isEmpty()) { // String[] tempList = attributes.split(","); for (int i = 0; i < tempList.length; i++) { String attributeName = tempList[i].trim(); // ??????? LinkedHashMap<String, Object> attributeSchema = SCIMUtil.getUserAttributeInfo(context, attributeName, true); if (attributeSchema != null && !attributeSchema.isEmpty()) { returnAttributeNameSet.add(attributeName); } else { // ??????? String message = String.format(MessageConstants.ERROR_INVALID_ATTRIBUTES, attributeName); setError(HttpServletResponse.SC_BAD_REQUEST, null, message); return result; } } } // id? LinkedHashMap<String, Object> targetInfo = null; @SuppressWarnings("unchecked") ArrayList<LinkedHashMap<String, Object>> users = (ArrayList<LinkedHashMap<String, Object>>) context .getAttribute("Users"); Iterator<LinkedHashMap<String, Object>> usersIt = null; if (users != null && !users.isEmpty()) { usersIt = users.iterator(); while (usersIt.hasNext()) { LinkedHashMap<String, Object> userInfo = usersIt.next(); Object id = SCIMUtil.getAttribute(userInfo, "id"); if (id != null && id instanceof String) { if (targetId.equals(id.toString())) { targetInfo = userInfo; break; } } } } if (targetInfo == null) { setError(HttpServletResponse.SC_NOT_FOUND, null, MessageConstants.ERROR_NOT_FOUND); return result; } // ? if (requestJson == null || requestJson.isEmpty()) { // setError(HttpServletResponse.SC_BAD_REQUEST, null, MessageConstants.ERROR_INVALID_REQUEST); return result; } // (JSON)? ObjectMapper mapper = new ObjectMapper(); LinkedHashMap<String, Object> requestObject = null; try { requestObject = mapper.readValue(requestJson, new TypeReference<LinkedHashMap<String, Object>>() { }); } catch (JsonParseException e) { String datailMessage = e.getMessage(); datailMessage = datailMessage.substring(0, datailMessage.indexOf('\n')); setError(HttpServletResponse.SC_BAD_REQUEST, null, MessageConstants.ERROR_INVALID_REQUEST + "(" + datailMessage + ")"); return result; } catch (JsonMappingException e) { String datailMessage = e.getMessage(); datailMessage = datailMessage.substring(0, datailMessage.indexOf('\n')); setError(HttpServletResponse.SC_BAD_REQUEST, null, MessageConstants.ERROR_INVALID_REQUEST + "(" + datailMessage + ")"); return result; } catch (IOException e) { setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null, MessageConstants.ERROR_UNKNOWN); return result; } // ? if (requestObject != null && !requestObject.isEmpty()) { Iterator<String> attributeIt = requestObject.keySet().iterator(); while (attributeIt.hasNext()) { // ??? String attributeName = attributeIt.next(); // ? LinkedHashMap<String, Object> attributeSchema = SCIMUtil.getUserAttributeInfo(context, attributeName, false); if (attributeSchema != null) { // ???? Object mutability = attributeSchema.get("mutability"); if (mutability != null && mutability.toString().equalsIgnoreCase("readOnly")) { // readOnly String message = String.format(MessageConstants.ERROR_READONLY_ATTRIBUTE, attributeName); setError(HttpServletResponse.SC_BAD_REQUEST, null, message); return result; } // ?? // () } else { if (!attributeName.equalsIgnoreCase("schemas") && !attributeName.equalsIgnoreCase("id") && !attributeName.equalsIgnoreCase("meta")) { // ???? String message = String.format(MessageConstants.ERROR_UNKNOWN_ATTRIBUTE, attributeName); setError(HttpServletResponse.SC_BAD_REQUEST, null, message); return result; } } } } else { // setError(HttpServletResponse.SC_BAD_REQUEST, null, MessageConstants.ERROR_INVALID_REQUEST); return result; } // ? // () LinkedHashMap<String, Object> updateUserInfo = new LinkedHashMap<String, Object>(); // updateUserInfo.put("id", targetId); Iterator<String> attributeIt = requestObject.keySet().iterator(); while (attributeIt.hasNext()) { // ??? String attributeName = attributeIt.next(); // ? Object attributeValue = requestObject.get(attributeName); updateUserInfo.put(attributeName, attributeValue); } // meta Object metaObject = targetInfo.get("meta"); @SuppressWarnings("unchecked") LinkedHashMap<String, Object> metaValues = (LinkedHashMap<String, Object>) metaObject; // meta.lastModified SimpleDateFormat xsdDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'"); xsdDateTime.setTimeZone(TimeZone.getTimeZone("UTC")); metaValues.put("lastModified", xsdDateTime.format(new Date())); updateUserInfo.put("meta", metaValues); // (??) usersIt.remove(); users.add(updateUserInfo); context.setAttribute("Users", users); // ?? result = new LinkedHashMap<String, Object>(); attributeIt = updateUserInfo.keySet().iterator(); while (attributeIt.hasNext()) { // ??? String attributeName = attributeIt.next(); // ? LinkedHashMap<String, Object> attributeSchema = SCIMUtil.getUserAttributeInfo(context, attributeName, true); Object returned = attributeSchema.get("returned"); if (returned != null && returned.toString().equalsIgnoreCase("never")) { continue; } // ? Object attributeValue = updateUserInfo.get(attributeName); result.put(attributeName, attributeValue); } return result; } /** * * * @param context * @param request * @param attributes * @param requestJson */ public boolean deleteUserInfo(ServletContext context, HttpServletRequest request, String targetId) { // ? setError(0, null, null); // id? LinkedHashMap<String, Object> targetInfo = null; @SuppressWarnings("unchecked") ArrayList<LinkedHashMap<String, Object>> users = (ArrayList<LinkedHashMap<String, Object>>) context .getAttribute("Users"); Iterator<LinkedHashMap<String, Object>> usersIt = null; if (users != null && !users.isEmpty()) { usersIt = users.iterator(); while (usersIt.hasNext()) { LinkedHashMap<String, Object> userInfo = usersIt.next(); Object id = SCIMUtil.getAttribute(userInfo, "id"); if (id != null && id instanceof String) { if (targetId.equals(id.toString())) { targetInfo = userInfo; break; } } } } if (targetInfo == null) { // ??? setError(HttpServletResponse.SC_NOT_FOUND, null, MessageConstants.ERROR_NOT_FOUND); return false; } // (??) usersIt.remove(); context.setAttribute("Users", users); return true; } /** * ?? * * @param code HTTP * @param message */ private void setError(int code, String type, String message) { errorCode = code; errorType = type; errorMessage = message; } /** * ? */ public int getErrorCode() { return errorCode; } /** * ? */ public String getErrorType() { return errorType; } /** * ? */ public String getErrorMessage() { return errorMessage; } }