Project

General

Profile

1
package eu.dnetlib.openaire.usermanagement.api;
2

    
3
import com.fasterxml.jackson.core.JsonProcessingException;
4
import com.google.gson.Gson;
5
import com.google.gson.JsonArray;
6
import com.google.gson.JsonObject;
7
import com.google.gson.JsonParser;
8
import eu.dnetlib.openaire.user.dao.SQLMigrationUserDAO;
9
import eu.dnetlib.openaire.user.ldap.MUserActionsLDAP;
10
import eu.dnetlib.openaire.user.login.utils.AuthoritiesMapper;
11
import eu.dnetlib.openaire.user.pojos.migration.LDAPUser;
12
import eu.dnetlib.openaire.user.store.DataSourceConnector;
13
import org.apache.commons.io.IOUtils;
14
import org.apache.http.HttpResponse;
15
import org.apache.http.NameValuePair;
16
import org.apache.http.client.entity.UrlEncodedFormEntity;
17
import org.apache.http.client.methods.HttpPost;
18
import org.apache.http.impl.client.CloseableHttpClient;
19
import org.apache.http.impl.client.HttpClients;
20
import org.apache.http.message.BasicNameValuePair;
21
import org.apache.log4j.Logger;
22
import org.mitre.openid.connect.model.OIDCAuthenticationToken;
23
import org.mitre.openid.connect.model.UserInfo;
24
import org.springframework.beans.factory.annotation.Autowired;
25
import org.springframework.beans.factory.annotation.Value;
26
import org.springframework.http.*;
27
import org.springframework.security.access.prepost.PreAuthorize;
28
import org.springframework.security.core.context.SecurityContextHolder;
29
import org.springframework.stereotype.Component;
30
import org.springframework.web.client.DefaultResponseErrorHandler;
31
import org.springframework.web.client.RestTemplate;
32

    
33
import javax.servlet.http.HttpServletRequest;
34
import javax.ws.rs.GET;
35
import javax.ws.rs.Path;
36
import javax.ws.rs.Produces;
37
import javax.ws.rs.QueryParam;
38
import javax.ws.rs.core.Context;
39
import javax.ws.rs.core.MediaType;
40
import javax.ws.rs.core.Response;
41
import java.io.IOException;
42
import java.io.InputStream;
43
import java.io.UnsupportedEncodingException;
44
import java.nio.charset.StandardCharsets;
45
import java.util.ArrayList;
46
import java.util.List;
47

    
48
/**
49
 * Created by sofia on 24/11/2016.
50
 */
51
@Component(value = "test3service")
52
@Path("/users")
53
public class Test3Service {
54

    
55
    private static final Logger logger = Logger.getLogger(Test3Service.class);
56

    
57
    public static final String errorMessage = "{ \"status\" : \"error\", \"code\" : \"%s\", \"message\" : \"%s\", \"description\" : \"%s\" }";
58

    
59

    
60
    @Autowired
61
    private SQLMigrationUserDAO sqlMigrationUserDAO;
62

    
63
    @Autowired
64
    private MUserActionsLDAP mUserActionsLDAP;
65

    
66
    @Autowired
67
    private DataSourceConnector dataSourceConnector;
68

    
69
    @Value("${oidc.issuer}")
70
    private String issuer;
71

    
72
    @Value("${oidc.secret}")
73
    private String secret;
74

    
75
    @Value("${oidc.id}")
76
    private String id;
77

    
78
    @GET
79
    @PreAuthorize("hasAuthority('ROLE_USER')")
80
    @Path("/getRefreshToken")
81
    public Response getRefreshToken(){
82
        OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
83
        return Response.status(200).entity(authentication.getRefreshTokenValue()).build();
84
    }
85

    
86
    @GET
87
    @PreAuthorize("hasAuthority('ROLE_USER')")
88
    @Path("/getJWTToken")
89
    public Response getAccessToken(){
90
        OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
91
        return Response.status(200).entity(authentication.getAccessTokenValue()).build();
92
    }
93

    
94
    @GET
95
    @Path("/getAccessToken")
96
    @Produces(MediaType.APPLICATION_JSON)
97
    public Response getAccessTokenFromRefreshToken(@Context final HttpServletRequest request,
98
                                                   @QueryParam("refreshToken") String refreshToken){
99

    
100
        if (refreshToken == null || refreshToken.isEmpty()) {
101
            return Response.status(Response.Status.BAD_REQUEST)
102
                    .entity(String.format(errorMessage, 400, "Bad Request", "Missing refreshToken parameter"))
103
                    .type(MediaType.APPLICATION_JSON).build();
104
        }
105

    
106
        CloseableHttpClient httpclient = HttpClients.createDefault();
107
        HttpPost httppost = new HttpPost(issuer+"/token");
108

    
109
        // Request parameters and other properties.
110
        List<NameValuePair> params = new ArrayList<NameValuePair>();
111
        params.add(new BasicNameValuePair("client_id", id));
112
        params.add(new BasicNameValuePair("client_secret", secret));
113
        params.add(new BasicNameValuePair("grant_type", "refresh_token"));
114
        params.add(new BasicNameValuePair("refresh_token", refreshToken));
115
        params.add(new BasicNameValuePair("scope", "openid"));
116

    
117
        HttpResponse response = null;
118

    
119
        try {
120
            httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
121
            //Execute and get the response.
122
            response = httpclient.execute(httppost);
123
            org.apache.http.HttpEntity entity = response.getEntity();
124

    
125
            if (response.getStatusLine().getStatusCode() == 401) {
126
                return Response.status(Response.Status.UNAUTHORIZED)
127
                        .entity(String.format(errorMessage, 401, "Unauthorised", "Invalid refreshToken token " + refreshToken))
128
                        .type(MediaType.APPLICATION_JSON).build();
129
            }
130

    
131
            String serverMessage = IOUtils.toString(entity.getContent(), StandardCharsets.UTF_8.name());
132
            return Response.status(response.getStatusLine().getStatusCode())
133
                    .entity(serverMessage).type(MediaType.APPLICATION_JSON).build();
134

    
135
        }  catch (UnsupportedEncodingException uee) {
136
            logger.error(uee);
137
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(String.format(errorMessage, 500, "Fail to get access token.", uee.getMessage()))
138
                    .type(MediaType.APPLICATION_JSON).build();
139

    
140
        } catch (IOException ioe) {
141
            logger.error(ioe);
142
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(String.format(errorMessage, 500, "Fail to get access token.", ioe.getMessage()))
143
                    .type(MediaType.APPLICATION_JSON).build();
144

    
145
        }
146
    }
147

    
148
    @GET
149
    @Path("/getToken")
150
    @Produces(MediaType.APPLICATION_JSON)
151
    public Response getToken(@QueryParam("accessToken") String accessToken){
152
        logger.debug("Refresh token " + accessToken);
153
        CloseableHttpClient httpclient = HttpClients.createDefault();
154
        HttpPost httppost = new HttpPost(issuer+"/token");
155

    
156
        // Request parameters and other properties.
157
        List<NameValuePair> params = new ArrayList<NameValuePair>();
158
        params.add(new BasicNameValuePair("client_id", id));
159
        params.add(new BasicNameValuePair("client_secret", secret));
160
        params.add(new BasicNameValuePair("grant_type", "refresh_token"));
161
        params.add(new BasicNameValuePair("refresh_token", accessToken));
162
        params.add(new BasicNameValuePair("scope", "openid"));
163
        try {
164
            httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
165
            //Execute and get the response.
166
            HttpResponse response = null;
167
            response = httpclient.execute(httppost);
168
            org.apache.http.HttpEntity entity = response.getEntity();
169
            if (entity != null) {
170
                try (InputStream instream = entity.getContent()) {
171
                    logger.debug(IOUtils.toString(instream, StandardCharsets.UTF_8.name()));
172
                }
173
            }
174

    
175
        }  catch (UnsupportedEncodingException uee) {
176
            logger.error(uee);
177
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(String.format(errorMessage, 500, "Fail to get access token.", uee.getMessage()))
178
                    .type(MediaType.APPLICATION_JSON).build();
179

    
180
        } catch (IOException ioe) {
181
            logger.error(ioe);
182
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(String.format(errorMessage, 500, "Fail to get access token.", ioe.getMessage()))
183
                    .type(MediaType.APPLICATION_JSON).build();
184

    
185
        }
186

    
187
        return Response.status(200).type(MediaType.APPLICATION_JSON).build();
188
    }
189

    
190
    @GET
191
    @Path("/getUserInfo")
192
    @Produces(MediaType.APPLICATION_JSON)
193
    public Response getUserInfo(@QueryParam("accessToken") String accessToken) throws JsonProcessingException {
194
        //return Response.status(404).entity(compose404Message("This is a test message.")).type(MediaType.APPLICATION_JSON).build();
195
        // call aai with accessToken
196
        logger.info(accessToken);
197
        RestTemplate restTemplate = new RestTemplate();
198
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
199
            protected boolean hasError(HttpStatus statusCode) {
200
                return false;
201
            }});
202
        HttpHeaders headers = new HttpHeaders();
203
        headers.add("Authorization","Bearer " + accessToken);
204
        HttpEntity<String>  request = new HttpEntity<>(headers);
205
        //logger.info(restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class));
206
        ResponseEntity<String> response = restTemplate.exchange(issuer +"userinfo", HttpMethod.GET, request, String.class);
207
        if(response.getStatusCode() == HttpStatus.OK) {
208
            JsonObject userInfo = new JsonParser().parse(response.getBody()).getAsJsonObject();
209
            JsonArray roles = new JsonArray();
210
            AuthoritiesMapper.map(userInfo.get("edu_person_entitlements").getAsJsonArray()).forEach(grantedAuthority -> {
211
                roles.add(grantedAuthority.getAuthority());
212
            });
213
            userInfo.add("roles", roles);
214
            return Response.status(response.getStatusCode().value()).entity(userInfo.toString()).type(MediaType.APPLICATION_JSON).build();
215
        } else {
216
            return Response.status(response.getStatusCode().value()).entity(response.getBody()).type(MediaType.APPLICATION_JSON).build();
217
        }
218

    
219
    }
220

    
221
    @GET
222
    @Path("/getUser")
223
    @Produces(MediaType.APPLICATION_JSON)
224
    public Response getUser()  {
225
        JsonObject userInfoJson = new JsonObject();
226
        try {
227
            OIDCAuthenticationToken authentication = null;
228
            try {
229
                authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
230
            }catch (Exception e){
231
                logger.info("Try to get User info - no context found ");
232
                return Response.status(404).entity(compose404Message("Get User info: no context found ")).type(MediaType.APPLICATION_JSON).build();
233
            }
234
            UserInfo userInfo = authentication.getUserInfo();
235
            if(userInfo == null){
236
                return Response.status(404).entity(compose404Message("Get User info: user info is null ")).type(MediaType.APPLICATION_JSON).build();
237
            }
238
            logger.info("Get User:\n name: " + authentication.getUserInfo().getGivenName() + " " + authentication.getUserInfo().getFamilyName());
239

    
240

    
241
            userInfoJson.addProperty("sub", userInfo.getSub());
242
            userInfoJson.addProperty("name", userInfo.getName());
243
            userInfoJson.addProperty("given_name", userInfo.getGivenName());
244
            userInfoJson.addProperty("family_name", userInfo.getFamilyName());
245
            userInfoJson.addProperty("email", userInfo.getEmail());
246
            JsonArray roles = new JsonArray();
247
            authentication.getAuthorities().forEach(grantedAuthority -> {
248
                roles.add(grantedAuthority.getAuthority());
249
            });
250
            userInfoJson.add("roles", roles);
251
        }catch (Exception e){
252
            logger.error("Get User info: An error occurred ",e);
253
            return Response.status(500).entity(compose500Message("Get User info: An error occurred ",e)).type(MediaType.APPLICATION_JSON).build();
254
        }
255
        return Response.status(200).entity(userInfoJson.toString()).type(MediaType.APPLICATION_JSON).build();
256
    }
257

    
258
/*
259
    @GET
260
    @Path("/katerina")
261
    @Produces(MediaType.APPLICATION_JSON)
262
    //@PreAuthorize("hasRole('ROLE_USER')")
263
    @PreAuthorize("hasAuthority('urn:geant:openaire.eu:group:Registered+User#aai.openaire.eu')")
264
    public Response getKaterina()  {
265
        return Response.status(200).build();
266
    }
267

    
268
    @GET
269
    @Path("/skata")
270
    @Produces(MediaType.APPLICATION_JSON)
271
    @PreAuthorize("hasRole('ROLE_USER')")
272
    public Response getKaterina2()  {
273
        return Response.status(200).build();
274
    }
275

    
276
    @GET
277
    @Path("/skata2")
278
    @Produces(MediaType.APPLICATION_JSON)
279
    @PreAuthorize("hasAuthority('skata')")
280
    public Response getKaterina3()  {
281
        return Response.status(200).build();
282
    }
283

    
284

    
285
    @GET
286
    @Path("/me")
287
    //@Produces(MediaType.APPLICATION_JSON)
288
    public Response getKaterina(@AuthenticationPrincipal UserDetails userDetails)  {
289
        //return Response.status(200).entity(userDetails).type(MediaType.APPLICATION_JSON).build();
290
        return Response.status(200).build();
291
    }
292
*/
293

    
294
    /* JSON Utility Methods */
295
    private String compose401Message(String message) {
296
        return  "{ \"status\" : \"error\", \"code\" : \"401\", \"message\" : \"  " + message +" \" }";
297
    }
298

    
299
    private String compose404Message(String message) {
300
        return  "{ \"status\" : \"error\", \"code\" : \"404\", \"message\" : \"  " + message +" \" }";
301
    }
302

    
303
    private String compose500Message(String message, Exception exception) {
304
        return  "{ \"status\" : \"fail\", \"code\" : \"500\", \"message\" : \"  " + message + "\", " +
305
                "\"description\" : \""+  exception.getMessage() +"\" }";
306
    }
307

    
308
    private String composeDataResponse(LDAPUser user) {
309
        return " { \"status\" : \"success\", \"code\": \"200\", " + "\"data\" : " + new Gson().toJson(user) + " }";
310
    }
311

    
312
    private String composeDataResponse(String fullname) {
313
        return " { \"status\" : \"success\", \"code\": \"200\", " + "\"data\" : " + new Gson().toJson(fullname) + " }";
314
    }
315
}
(2-2/2)