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}