001/* 002 * (C) Copyright 2006-2018 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nelson Silva 018 */ 019package org.nuxeo.ecm.platform.oauth2.tokens; 020 021import java.time.Instant; 022import java.util.Calendar; 023import java.util.HashMap; 024import java.util.Map; 025import java.util.concurrent.TimeUnit; 026 027import org.apache.commons.text.CharacterPredicates; 028import org.apache.commons.text.RandomStringGenerator; 029import org.apache.commons.text.RandomStringGenerator.Builder; 030import org.nuxeo.ecm.core.api.DocumentModel; 031 032import com.google.api.client.auth.oauth2.StoredCredential; 033 034public class NuxeoOAuth2Token { 035 036 private static final RandomStringGenerator GENERATOR = new Builder().filteredBy(CharacterPredicates.LETTERS, 037 CharacterPredicates.DIGITS).withinRange('0', 'z').build(); 038 039 public static final String SCHEMA = "oauth2Token"; 040 041 public static final String KEY_SERVICE_LOGIN = "serviceLogin"; 042 043 public static final String KEY_NUXEO_LOGIN = "nuxeoLogin"; 044 045 /** 046 * @since 11.1 047 */ 048 public static final String KEY_SERVICE_NAME = "serviceName"; 049 050 protected Long id; 051 052 protected String serviceName; 053 054 protected String nuxeoLogin; 055 056 protected String accessToken; 057 058 protected String clientId; 059 060 protected Calendar creationDate; 061 062 private String refreshToken; 063 064 private Long expirationTimeMilliseconds; 065 066 private boolean isShared; 067 068 protected String sharedWith; 069 070 protected String serviceLogin; 071 072 public NuxeoOAuth2Token(long expirationTimeMilliseconds, String clientId) { 073 this("", "", expirationTimeMilliseconds); 074 this.clientId = clientId; 075 refresh(); 076 } 077 078 public NuxeoOAuth2Token(String accessToken, String refreshToken, Long expirationTimeMilliseconds) { 079 this.accessToken = accessToken; 080 this.refreshToken = refreshToken; 081 this.expirationTimeMilliseconds = expirationTimeMilliseconds; 082 this.creationDate = Calendar.getInstance(); 083 this.isShared = false; 084 this.sharedWith = ""; 085 } 086 087 public NuxeoOAuth2Token(StoredCredential credential) { 088 this(credential.getAccessToken(), credential.getRefreshToken(), credential.getExpirationTimeMilliseconds()); 089 } 090 091 public NuxeoOAuth2Token(DocumentModel entry) { 092 this.id = (Long) entry.getProperty(SCHEMA, "id"); 093 this.accessToken = (String) entry.getProperty(SCHEMA, "accessToken"); 094 this.refreshToken = (String) entry.getProperty(SCHEMA, "refreshToken"); 095 this.expirationTimeMilliseconds = (Long) entry.getProperty(SCHEMA, "expirationTimeMilliseconds"); 096 this.serviceName = (String) entry.getProperty(SCHEMA, "serviceName"); 097 this.nuxeoLogin = (String) entry.getProperty(SCHEMA, "nuxeoLogin"); 098 this.clientId = (String) entry.getProperty(SCHEMA, "clientId"); 099 this.creationDate = (Calendar) entry.getProperty(SCHEMA, "creationDate"); 100 this.isShared = (Boolean) entry.getProperty(SCHEMA, "isShared"); 101 this.sharedWith = (String) entry.getProperty(SCHEMA, "sharedWith"); 102 this.serviceLogin = (String) entry.getProperty(SCHEMA, "serviceLogin"); 103 } 104 105 public static StoredCredential asCredential(DocumentModel entry) { 106 StoredCredential credential = new StoredCredential(); 107 String accessToken = (String) entry.getProperty(SCHEMA, "accessToken"); 108 String refreshToken = (String) entry.getProperty(SCHEMA, "refreshToken"); 109 Long expirationTimeMilliseconds = (Long) entry.getProperty(SCHEMA, "expirationTimeMilliseconds"); 110 credential.setAccessToken(accessToken); 111 credential.setRefreshToken(refreshToken); 112 credential.setExpirationTimeMilliseconds(expirationTimeMilliseconds); 113 return credential; 114 } 115 116 public Map<String, Object> toMap() { 117 Map<String, Object> map = new HashMap<>(); 118 map.put("serviceName", serviceName); 119 map.put("nuxeoLogin", nuxeoLogin); 120 map.put("accessToken", accessToken); 121 map.put("refreshToken", refreshToken); 122 map.put("expirationTimeMilliseconds", expirationTimeMilliseconds); 123 map.put("clientId", clientId); 124 map.put("creationDate", creationDate); 125 map.put("isShared", isShared); 126 map.put("sharedWith", sharedWith); 127 map.put("serviceLogin", serviceLogin); 128 return map; 129 } 130 131 public Map<String, Object> toJsonObject() { 132 Map<String, Object> m = new HashMap<>(); 133 m.put("access_token", accessToken); 134 m.put("refresh_token", refreshToken); 135 m.put("token_type", "bearer"); 136 // Lifetime in seconds of the access token, see https://tools.ietf.org/html/rfc6749#section-5.1. 137 // Must be a whole number otherwise some clients might fail reading the token response. 138 m.put("expires_in", TimeUnit.MILLISECONDS.toSeconds( 139 creationDate.getTimeInMillis() + expirationTimeMilliseconds - Instant.now().toEpochMilli())); 140 141 return m; 142 } 143 144 public void updateEntry(DocumentModel entry) { 145 entry.setProperty(SCHEMA, "serviceName", this.serviceName); 146 entry.setProperty(SCHEMA, "nuxeoLogin", this.nuxeoLogin); 147 entry.setProperty(SCHEMA, "accessToken", this.accessToken); 148 entry.setProperty(SCHEMA, "refreshToken", this.refreshToken); 149 entry.setProperty(SCHEMA, "expirationTimeMilliseconds", this.expirationTimeMilliseconds); 150 entry.setProperty(SCHEMA, "clientId", this.clientId); 151 entry.setProperty(SCHEMA, "isShared", this.isShared); 152 entry.setProperty(SCHEMA, "sharedWith", this.sharedWith); 153 entry.setProperty(SCHEMA, "serviceLogin", this.serviceLogin); 154 } 155 156 public void refresh() { 157 accessToken = GENERATOR.generate(32); 158 refreshToken = GENERATOR.generate(64); 159 creationDate = Calendar.getInstance(); 160 } 161 162 public boolean isExpired() { 163 return creationDate != null && creationDate.getTimeInMillis() 164 + expirationTimeMilliseconds < Calendar.getInstance().getTimeInMillis(); 165 } 166 167 public void setServiceName(String serviceName) { 168 this.serviceName = serviceName; 169 } 170 171 public void setNuxeoLogin(String userId) { 172 this.nuxeoLogin = userId; 173 } 174 175 public String getNuxeoLogin() { 176 return nuxeoLogin; 177 } 178 179 public String getAccessToken() { 180 return accessToken; 181 } 182 183 public void setAccessToken(String accessToken) { 184 this.accessToken = accessToken; 185 } 186 187 public String getRefreshToken() { 188 return refreshToken; 189 } 190 191 public void setRefreshToken(String refreshToken) { 192 this.refreshToken = refreshToken; 193 } 194 195 public Long getExpirationTimeMilliseconds() { 196 return expirationTimeMilliseconds; 197 } 198 199 public void setExpirationTimeMilliseconds(Long expirationTimeMilliseconds) { 200 this.expirationTimeMilliseconds = expirationTimeMilliseconds; 201 } 202 203 public String getServiceName() { 204 return serviceName; 205 } 206 207 public String getClientId() { 208 return clientId; 209 } 210 211 public void setClientId(String clientId) { 212 this.clientId = clientId; 213 } 214 215 public boolean isShared() { 216 return isShared; 217 } 218 219 public void setIsShared(boolean isShared) { 220 this.isShared = isShared; 221 } 222 223 public String getSharedWith() { 224 return sharedWith; 225 } 226 227 public void setSharedWith(String sharedWith) { 228 this.sharedWith = sharedWith; 229 } 230 231 public String getServiceLogin() { 232 return serviceLogin; 233 } 234 235 public void setServiceLogin(String serviceLogin) { 236 this.serviceLogin = serviceLogin; 237 } 238 239 public Calendar getCreationDate() { 240 return creationDate; 241 } 242 243 public void setCreationDate(Calendar creationDate) { 244 this.creationDate = creationDate; 245 } 246 247 public Long getId() { 248 return id; 249 } 250 251}