001package org.nuxeo.ecm.platform.oauth2.request; 002 003import static org.apache.commons.lang.StringUtils.isBlank; 004import static org.nuxeo.ecm.platform.ui.web.auth.oauth2.NuxeoOAuth2Filter.ERRORS.*; 005 006import java.io.UnsupportedEncodingException; 007import java.util.Date; 008import java.util.HashMap; 009import java.util.Iterator; 010import java.util.Map; 011 012import javax.servlet.http.HttpServletRequest; 013 014import org.apache.commons.lang.RandomStringUtils; 015import org.apache.commons.logging.Log; 016import org.apache.commons.logging.LogFactory; 017import org.nuxeo.ecm.directory.DirectoryException; 018import org.nuxeo.ecm.platform.oauth2.clients.ClientRegistry; 019import org.nuxeo.runtime.api.Framework; 020 021/** 022 * @author <a href="mailto:ak@nuxeo.com">Arnaud Kervern</a> 023 * @since 5.9.2 024 */ 025public class AuthorizationRequest extends Oauth2Request { 026 private static final Log log = LogFactory.getLog(AuthorizationRequest.class); 027 028 protected static Map<String, AuthorizationRequest> requests = new HashMap<>(); 029 030 protected String responseType; 031 032 protected String scope; 033 034 protected String state; 035 036 protected String sessionId; 037 038 protected Date creationDate; 039 040 protected String authorizationCode; 041 042 protected String authorizationKey; 043 044 protected String username; 045 046 public static final String RESPONSE_TYPE = "response_type"; 047 048 public static final String SCOPE = "scope"; 049 050 public static final String STATE = "state"; 051 052 public AuthorizationRequest() { 053 } 054 055 public AuthorizationRequest(HttpServletRequest request) { 056 super(request); 057 responseType = request.getParameter(RESPONSE_TYPE); 058 059 scope = request.getParameter(SCOPE); 060 state = request.getParameter(STATE); 061 sessionId = request.getSession(true).getId(); 062 063 creationDate = new Date(); 064 authorizationKey = RandomStringUtils.random(6, true, false); 065 } 066 067 public String checkError() { 068 // Check mandatory fields 069 if (isBlank(responseType) || isBlank(clientId) || isBlank(redirectUri)) { 070 return invalid_request.toString(); 071 } 072 073 // Check if client exists 074 try { 075 ClientRegistry registry = Framework.getLocalService(ClientRegistry.class); 076 if (!registry.hasClient(clientId)) { 077 return unauthorized_client.toString(); 078 } 079 } catch (DirectoryException e) { 080 log.warn(e, e); 081 return server_error.toString(); 082 } 083 084 // Check request type 085 if (!"code".equals(responseType)) { 086 return unsupported_response_type.toString(); 087 } 088 return null; 089 } 090 091 public boolean isExpired() { 092 // RFC 4.1.2, Authorization code lifetime is 10 093 return new Date().getTime() - creationDate.getTime() > 10 * 60 * 1000; 094 } 095 096 public boolean isValidState(HttpServletRequest request) { 097 return isBlank(getState()) || request.getParameter(STATE).equals(getState()); 098 } 099 100 public String getUsername() { 101 return username; 102 } 103 104 public String getResponseType() { 105 return responseType; 106 } 107 108 public String getScope() { 109 return scope; 110 } 111 112 public String getState() { 113 return state; 114 } 115 116 public String getAuthorizationCode() { 117 if (isBlank(authorizationCode)) { 118 authorizationCode = RandomStringUtils.random(10, true, true); 119 } 120 return authorizationCode; 121 } 122 123 public String getAuthorizationKey() { 124 return authorizationKey; 125 } 126 127 private static void deleteExpiredRequests() { 128 Iterator<AuthorizationRequest> iterator = requests.values().iterator(); 129 AuthorizationRequest req; 130 while (iterator.hasNext() && (req = iterator.next()) != null) { 131 if (req.isExpired()) { 132 requests.remove(req.sessionId); 133 } 134 } 135 } 136 137 public static AuthorizationRequest from(HttpServletRequest request) throws UnsupportedEncodingException { 138 deleteExpiredRequests(); 139 140 String sessionId = request.getSession(true).getId(); 141 if (requests.containsKey(sessionId)) { 142 AuthorizationRequest authRequest = requests.get(sessionId); 143 if (!authRequest.isExpired() && authRequest.isValidState(request)) { 144 return authRequest; 145 } 146 } 147 148 AuthorizationRequest authRequest = new AuthorizationRequest(request); 149 requests.put(sessionId, authRequest); 150 return authRequest; 151 } 152 153 public static AuthorizationRequest fromCode(String authorizationCode) { 154 for (AuthorizationRequest auth : requests.values()) { 155 if (auth.authorizationCode != null && auth.authorizationCode.equals(authorizationCode)) { 156 requests.remove(auth.sessionId); 157 return auth.isExpired() ? null : auth; 158 } 159 } 160 return null; 161 } 162 163 public void setUsername(String username) { 164 this.username = username; 165 } 166}