001/******************************************************************************* 002 * Copyright 2017 The MIT Internet Trust Consortium 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 *******************************************************************************/ 016package org.mitre.oauth2.view; 017 018import java.io.IOException; 019import java.io.Writer; 020import java.lang.reflect.Type; 021import java.util.Map; 022 023import javax.servlet.http.HttpServletRequest; 024import javax.servlet.http.HttpServletResponse; 025 026import org.mitre.oauth2.model.OAuth2AccessTokenEntity; 027import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; 028import org.mitre.openid.connect.view.HttpCodeView; 029import org.mitre.openid.connect.view.JsonEntityView; 030import org.slf4j.Logger; 031import org.slf4j.LoggerFactory; 032import org.springframework.http.HttpStatus; 033import org.springframework.http.MediaType; 034import org.springframework.stereotype.Component; 035import org.springframework.validation.BeanPropertyBindingResult; 036import org.springframework.web.servlet.view.AbstractView; 037 038import com.google.gson.ExclusionStrategy; 039import com.google.gson.FieldAttributes; 040import com.google.gson.Gson; 041import com.google.gson.GsonBuilder; 042import com.google.gson.JsonElement; 043import com.google.gson.JsonObject; 044import com.google.gson.JsonSerializationContext; 045import com.google.gson.JsonSerializer; 046 047@Component(TokenApiView.VIEWNAME) 048public class TokenApiView extends AbstractView { 049 050 public static final String VIEWNAME = "tokenApiView"; 051 052 /** 053 * Logger for this class 054 */ 055 private static final Logger logger = LoggerFactory.getLogger(TokenApiView.class); 056 057 private Gson gson = new GsonBuilder() 058 .setExclusionStrategies(new ExclusionStrategy() { 059 060 @Override 061 public boolean shouldSkipField(FieldAttributes f) { 062 return false; 063 } 064 065 @Override 066 public boolean shouldSkipClass(Class<?> clazz) { 067 // skip the JPA binding wrapper 068 if (clazz.equals(BeanPropertyBindingResult.class)) { 069 return true; 070 } 071 return false; 072 } 073 074 }) 075 .registerTypeAdapter(OAuth2AccessTokenEntity.class, new JsonSerializer<OAuth2AccessTokenEntity>() { 076 077 @Override 078 public JsonElement serialize(OAuth2AccessTokenEntity src, 079 Type typeOfSrc, JsonSerializationContext context) { 080 081 082 JsonObject o = new JsonObject(); 083 084 o.addProperty("value", src.getValue()); 085 o.addProperty("id", src.getId()); 086 o.addProperty("refreshTokenId", src.getRefreshToken() != null ? src.getRefreshToken().getId() : null); 087 088 o.add("scopes", context.serialize(src.getScope())); 089 090 o.addProperty("clientId", src.getClient().getClientId()); 091 o.addProperty("userId", src.getAuthenticationHolder().getAuthentication().getName()); 092 093 o.add("expiration", context.serialize(src.getExpiration())); 094 095 return o; 096 } 097 098 }) 099 .registerTypeAdapter(OAuth2RefreshTokenEntity.class, new JsonSerializer<OAuth2RefreshTokenEntity>() { 100 101 @Override 102 public JsonElement serialize(OAuth2RefreshTokenEntity src, 103 Type typeOfSrc, JsonSerializationContext context) { 104 JsonObject o = new JsonObject(); 105 106 o.addProperty("value", src.getValue()); 107 o.addProperty("id", src.getId()); 108 109 o.add("scopes", context.serialize(src.getAuthenticationHolder().getAuthentication().getOAuth2Request().getScope())); 110 111 o.addProperty("clientId", src.getClient().getClientId()); 112 o.addProperty("userId", src.getAuthenticationHolder().getAuthentication().getName()); 113 114 o.add("expiration", context.serialize(src.getExpiration())); 115 116 return o; 117 } 118 119 }) 120 .serializeNulls() 121 .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") 122 .create(); 123 124 @Override 125 protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) { 126 127 response.setContentType(MediaType.APPLICATION_JSON_VALUE); 128 129 130 HttpStatus code = (HttpStatus) model.get(HttpCodeView.CODE); 131 if (code == null) { 132 code = HttpStatus.OK; // default to 200 133 } 134 135 response.setStatus(code.value()); 136 137 try { 138 139 Writer out = response.getWriter(); 140 Object obj = model.get(JsonEntityView.ENTITY); 141 gson.toJson(obj, out); 142 143 } catch (IOException e) { 144 145 logger.error("IOException in JsonEntityView.java: ", e); 146 147 } 148 } 149 150}