Project

General

Profile

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

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

    
37
import javax.servlet.http.HttpServletRequest;
38
import javax.ws.rs.GET;
39
import javax.ws.rs.Path;
40
import javax.ws.rs.Produces;
41
import javax.ws.rs.QueryParam;
42
import javax.ws.rs.core.Context;
43
import javax.ws.rs.core.MediaType;
44
import javax.ws.rs.core.Response;
45
import java.io.IOException;
46
import java.io.InputStream;
47
import java.io.UnsupportedEncodingException;
48
import java.nio.charset.StandardCharsets;
49
import java.util.ArrayList;
50
import java.util.HashSet;
51
import java.util.List;
52
import java.util.Set;
53
import eu.dnetlib.openaire.user.login.utils.AuthoritiesMapper;
54

    
55
/**
56
 * Created by sofia on 24/11/2016.
57
 */
58
@Component(value = "test3service")
59
@Path("/users")
60
public class Test3Service {
61

    
62
    private static final Logger logger = Logger.getLogger(Test3Service.class);
63

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

    
66

    
67
    @Autowired
68
    private SQLMigrationUserDAO sqlMigrationUserDAO;
69

    
70
    @Autowired
71
    private MUserActionsLDAP mUserActionsLDAP;
72

    
73
    @Autowired
74
    private DataSourceConnector dataSourceConnector;
75

    
76
    @Value("${oidc.issuer}")
77
    private String issuer;
78

    
79
    @Value("${oidc.secret}")
80
    private String secret;
81

    
82
    @Value("${oidc.id}")
83
    private String id;
84

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

    
93
    @GET
94
    @PreAuthorize("hasAuthority('ROLE_USER')")
95
    @Path("/getJWTToken")
96
    public Response getAccessToken(){
97
        OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
98
        return Response.status(200).entity(authentication.getAccessTokenValue()).build();
99
    }
100

    
101
    @GET
102
    @Path("/getAccessToken")
103
    @Produces(MediaType.APPLICATION_JSON)
104
    public Response getAccessTokenFromRefreshToken(@Context final HttpServletRequest request,
105
                                                   @QueryParam("refreshToken") String refreshToken){
106

    
107
        if (refreshToken == null || refreshToken.isEmpty()) {
108
            return Response.status(Response.Status.BAD_REQUEST)
109
                    .entity(String.format(errorMessage, 400, "Bad Request", "Missing refreshToken parameter"))
110
                    .type(MediaType.APPLICATION_JSON).build();
111
        }
112

    
113
        CloseableHttpClient httpclient = HttpClients.createDefault();
114
        HttpPost httppost = new HttpPost(issuer+"/token");
115

    
116
        // Request parameters and other properties.
117
        List<NameValuePair> params = new ArrayList<NameValuePair>();
118
        params.add(new BasicNameValuePair("client_id", id));
119
        params.add(new BasicNameValuePair("client_secret", secret));
120
        params.add(new BasicNameValuePair("grant_type", "refresh_token"));
121
        params.add(new BasicNameValuePair("refresh_token", refreshToken));
122
        params.add(new BasicNameValuePair("scope", "openid"));
123

    
124
        HttpResponse response = null;
125

    
126
        try {
127
            httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
128
            //Execute and get the response.
129
            response = httpclient.execute(httppost);
130
            org.apache.http.HttpEntity entity = response.getEntity();
131

    
132
            if (response.getStatusLine().getStatusCode() == 401) {
133
                return Response.status(Response.Status.UNAUTHORIZED)
134
                        .entity(String.format(errorMessage, 401, "Unauthorised", "Invalid refreshToken token " + refreshToken))
135
                        .type(MediaType.APPLICATION_JSON).build();
136
            }
137

    
138
            String serverMessage = IOUtils.toString(entity.getContent(), StandardCharsets.UTF_8.name());
139
            return Response.status(response.getStatusLine().getStatusCode())
140
                    .entity(serverMessage).type(MediaType.APPLICATION_JSON).build();
141

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

    
147
        } catch (IOException ioe) {
148
            logger.error(ioe);
149
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(String.format(errorMessage, 500, "Fail to get access token.", ioe.getMessage()))
150
                    .type(MediaType.APPLICATION_JSON).build();
151

    
152
        }
153
    }
154

    
155
    @GET
156
    @Path("/getToken")
157
    @Produces(MediaType.APPLICATION_JSON)
158
    public Response getToken(@QueryParam("accessToken") String accessToken){
159
        logger.debug("Refresh token " + accessToken);
160
        CloseableHttpClient httpclient = HttpClients.createDefault();
161
        HttpPost httppost = new HttpPost(issuer+"/token");
162

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

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

    
187
        } catch (IOException ioe) {
188
            logger.error(ioe);
189
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(String.format(errorMessage, 500, "Fail to get access token.", ioe.getMessage()))
190
                    .type(MediaType.APPLICATION_JSON).build();
191

    
192
        }
193

    
194
        return Response.status(200).type(MediaType.APPLICATION_JSON).build();
195
    }
196

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

    
226
    }
227

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

    
247

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

    
265
/*
266
    @GET
267
    @Path("/katerina")
268
    @Produces(MediaType.APPLICATION_JSON)
269
    //@PreAuthorize("hasRole('ROLE_USER')")
270
    @PreAuthorize("hasAuthority('urn:geant:openaire.eu:group:Registered+User#aai.openaire.eu')")
271
    public Response getKaterina()  {
272
        return Response.status(200).build();
273
    }
274

    
275
    @GET
276
    @Path("/skata")
277
    @Produces(MediaType.APPLICATION_JSON)
278
    @PreAuthorize("hasRole('ROLE_USER')")
279
    public Response getKaterina2()  {
280
        return Response.status(200).build();
281
    }
282

    
283
    @GET
284
    @Path("/skata2")
285
    @Produces(MediaType.APPLICATION_JSON)
286
    @PreAuthorize("hasAuthority('skata')")
287
    public Response getKaterina3()  {
288
        return Response.status(200).build();
289
    }
290

    
291

    
292
    @GET
293
    @Path("/me")
294
    //@Produces(MediaType.APPLICATION_JSON)
295
    public Response getKaterina(@AuthenticationPrincipal UserDetails userDetails)  {
296
        //return Response.status(200).entity(userDetails).type(MediaType.APPLICATION_JSON).build();
297
        return Response.status(200).build();
298
    }
299
*/
300

    
301
    /* JSON Utility Methods */
302
    private String compose401Message(String message) {
303
        return  "{ \"status\" : \"error\", \"code\" : \"401\", \"message\" : \"  " + message +" \" }";
304
    }
305

    
306
    private String compose404Message(String message) {
307
        return  "{ \"status\" : \"error\", \"code\" : \"404\", \"message\" : \"  " + message +" \" }";
308
    }
309

    
310
    private String compose500Message(String message, Exception exception) {
311
        return  "{ \"status\" : \"fail\", \"code\" : \"500\", \"message\" : \"  " + message + "\", " +
312
                "\"description\" : \""+  exception.getMessage() +"\" }";
313
    }
314

    
315
    private String composeDataResponse(LDAPUser user) {
316
        return " { \"status\" : \"success\", \"code\": \"200\", " + "\"data\" : " + new Gson().toJson(user) + " }";
317
    }
318

    
319
    private String composeDataResponse(String fullname) {
320
        return " { \"status\" : \"success\", \"code\": \"200\", " + "\"data\" : " + new Gson().toJson(fullname) + " }";
321
    }
322
}
(2-2/2)