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 com.unboundid.ldap.sdk.LDAPException;
10
import eu.dnetlib.openaire.user.pojos.migration.LDAPUser;
11
import eu.dnetlib.openaire.user.pojos.migration.MigrationUser;
12
import eu.dnetlib.openaire.user.pojos.migration.Role;
13
import eu.dnetlib.openaire.user.dao.RoleDAO;
14
import eu.dnetlib.openaire.user.dao.SQLMigrationUserDAO;
15
import eu.dnetlib.openaire.user.ldap.MUserActionsLDAP;
16
import eu.dnetlib.openaire.user.store.DataSourceConnector;
17
import eu.dnetlib.openaire.usermanagement.security.JWTGenerator;
18
import org.apache.log4j.Logger;
19
import org.mitre.openid.connect.model.OIDCAuthenticationToken;
20
import org.mitre.openid.connect.model.UserInfo;
21
import org.springframework.beans.factory.annotation.Autowired;
22
import org.springframework.beans.factory.annotation.Value;
23
import org.springframework.http.*;
24
import org.springframework.http.HttpMethod;
25
import org.springframework.security.core.context.SecurityContextHolder;
26
import org.springframework.stereotype.Component;
27
import org.springframework.web.client.DefaultResponseErrorHandler;
28
import org.springframework.web.client.RestTemplate;
29

    
30
import javax.ws.rs.*;
31
import javax.ws.rs.core.MediaType;
32
import javax.ws.rs.core.Response;
33
import java.sql.SQLException;
34

    
35
/**
36
 * Created by sofia on 24/11/2016.
37
 */
38
@Component(value = "test3service")
39
@Path("/users")
40
public class Test3Service {
41

    
42
    private static final Logger logger = Logger.getLogger(Test3Service.class);
43

    
44
    @Autowired
45
    private SQLMigrationUserDAO sqlMigrationUserDAO;
46

    
47
    @Autowired
48
    private MUserActionsLDAP mUserActionsLDAP;
49

    
50
    @Autowired
51
    private DataSourceConnector dataSourceConnector;
52

    
53
    @Value("${oidc.issuer}")
54
    private String issuer;
55

    
56
    @GET
57
    @Path("/{userId}")
58
    @Produces(MediaType.APPLICATION_JSON)
59
    public Response getUserById(@PathParam("userId") int userId) {
60
        try {
61
            MigrationUser mUser = sqlMigrationUserDAO.fetchById(userId);
62

    
63
            // Invalide user ID
64
            if (mUser == null) {
65
                String errorMessageJson = compose404Message("Cannot find user with id " + userId + ".");
66

    
67
                return Response
68
                        .status(Response.Status.NOT_FOUND)
69
                        .entity(errorMessageJson)
70
                        .type(MediaType.APPLICATION_JSON)
71
                        .build();
72
            }
73

    
74
            return Response.status(200).entity(composeDataResponse(mUser)).build();
75
        }
76
        catch (SQLException e) {
77
            return Response
78
                    .status(Response.Status.INTERNAL_SERVER_ERROR)
79
                    .entity(compose500Message("Fail to fetch users.", e))
80
                    .type(MediaType.APPLICATION_JSON)
81
                    .build();
82
        }
83
    }
84

    
85
     /* How to check @browser ../authenticate/?username=MY_USERNAME&password=MY_PASSWORD
86
     * http://localhost:8080/uoa-user-management-1.0.0-SNAPSHOT/api/users/authenticate?username=sba&password=12345678
87
    @GET
88
    @Path("/authenticate")
89
    @Produces(MediaType.APPLICATION_JSON)
90
    public Response authenticateUserGET(@QueryParam("username") String username, @QueryParam("password") String password)
91
    {
92
        return commonAuthenticateFunction(username, password);
93

    
94
    }*/
95

    
96
    @POST
97
    @Path("/authenticates")
98
    @Produces(MediaType.APPLICATION_JSON)
99
    @Consumes(MediaType.APPLICATION_JSON)
100
    public Response authenticateUserPOST(String input) {
101
        JsonObject jsonObject = new JsonParser().parse(input).getAsJsonObject();
102

    
103
        String username = jsonObject.get("username").getAsString();
104
        String password = jsonObject.get("password").getAsString();
105

    
106
        return commonAuthenticateFunction(username, password);
107
    }
108

    
109
    private Response commonAuthenticateFunction(String username, String password)
110
    {
111
        try {
112
            boolean usernameExists = mUserActionsLDAP.usernameExists(username);
113

    
114
            // if user was not found
115
            if (!usernameExists) {
116
                String errorMessageJson = compose401Message("Wrong credentials.");
117

    
118
                return Response
119
                        .status(Response.Status.UNAUTHORIZED)
120
                        .entity(errorMessageJson)
121
                        .type(MediaType.APPLICATION_JSON)
122
                        .build();
123
            }
124

    
125
            boolean authenticated = mUserActionsLDAP.authenticate(username, password);
126

    
127
            // if user was not authenticated
128
            if (!authenticated) {
129
                return Response
130
                        .status(Response.Status.UNAUTHORIZED)
131
                        .entity(compose401Message("User " + username + " could not be authenticated."))
132
                        .type(MediaType.APPLICATION_JSON)
133
                        .build();
134
            }
135

    
136
            MigrationUser mUser = sqlMigrationUserDAO.fetchByUsername(username);
137

    
138
            // if user was not found in my db
139
            LDAPUser ldapUser = null;
140
            if (mUser == null) {
141
                mUser = new MigrationUser(username);
142
                ldapUser = mUserActionsLDAP.getUser(username);
143
                mUser.setFullname(ldapUser.getDisplayName());
144
                mUser.setEmail(ldapUser.getEmail());
145
                mUser.setRoleId(2);
146

    
147

    
148
                sqlMigrationUserDAO.insert(mUser);
149
            }
150
            return Response.status(200).entity(composeDataResponse(mUser)).type(MediaType.APPLICATION_JSON).build();
151

    
152
        } catch (LDAPException exc) {
153
            logger.error("Fail to connect to LDAP. ", exc);
154
            return Response
155
                    .status(Response.Status.INTERNAL_SERVER_ERROR)
156
                    .entity(compose500Message("LDAP error.", exc))
157
                    .type(MediaType.APPLICATION_JSON)
158
                    .build();
159

    
160
        } catch (SQLException exc) {
161
            logger.error("Fail to fetch users. ", exc);
162
            return Response
163
                    .status(Response.Status.INTERNAL_SERVER_ERROR)
164
                    .entity(compose500Message("Fail to fetch users.", exc))
165
                    .type(MediaType.APPLICATION_JSON)
166
                    .build();
167
        }
168

    
169
    }
170

    
171
    @GET
172
    @Path("/changeRole")
173
    @Produces(MediaType.APPLICATION_JSON)
174
    public Response changeRole(@QueryParam("roleId") int roleId, @QueryParam("userId") int userId)
175
    {
176
        RoleDAO roleDAO = new RoleDAO();
177
        try
178
        {
179
            Role role = roleDAO.fetchById(roleId);
180
            if (role == null)
181
            {
182
                //fetch all roleids TODO
183
                String errorMessageJson = compose404Message("Cannot find role with id" + roleId + ".");
184

    
185
                return Response
186
                        .status(Response.Status.NOT_FOUND)
187
                        .entity(errorMessageJson)
188
                        .type(MediaType.APPLICATION_JSON)
189
                        .build();
190
            }
191

    
192
            MigrationUser mUser = sqlMigrationUserDAO.fetchById(userId);
193

    
194
            if (mUser == null)
195
            {
196
                String errorMessageJson = compose404Message("Cannot find user with id " + userId + ".");
197

    
198
                return Response
199
                        .status(Response.Status.NOT_FOUND)
200
                        .entity(errorMessageJson)
201
                        .type(MediaType.APPLICATION_JSON)
202
                        .build();
203
            }
204

    
205
            mUser.setRoleId(roleId);
206
            sqlMigrationUserDAO.update(mUser);
207

    
208
            return Response.status(200).entity(composeDataResponse(mUser)).build();
209
        }
210
        catch (SQLException exc)
211
        {
212
            return Response
213
                    .status(Response.Status.INTERNAL_SERVER_ERROR)
214
                    .entity(compose500Message("Fail to fetch users.", exc))
215
                    .type(MediaType.APPLICATION_JSON)
216
                    .build();
217
        }
218
    }
219

    
220
    @GET
221
    @Path("/getUserInfo")
222
    @Produces(MediaType.APPLICATION_JSON)
223
    public Response getUserInfo(@QueryParam("accessToken") String accessToken) throws JsonProcessingException {
224
        //return Response.status(404).entity(compose404Message("This is a test message.")).type(MediaType.APPLICATION_JSON).build();
225
        // call aai with accessToken
226
        RestTemplate restTemplate = new RestTemplate();
227
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
228
            protected boolean hasError(HttpStatus statusCode) {
229
                return false;
230
            }});
231
        HttpHeaders headers = new HttpHeaders();
232
        headers.add("Authorization","Bearer " + accessToken);
233
        HttpEntity request = new HttpEntity(null, headers);
234
        String fooResourceUrl = issuer +"userinfo";
235

    
236
        //logger.info(restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class));
237
        ResponseEntity response1 = restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class);
238
        logger.info(response1.getBody().toString());
239
        ObjectMapper mapper = new ObjectMapper();
240

    
241
        return Response.status(response1.getStatusCode().value()).entity(mapper.writeValueAsString(response1.getBody())).type(MediaType.APPLICATION_JSON).build();
242

    
243
    }
244

    
245
    @GET
246
    @Path("/getUser")
247
    @Produces(MediaType.APPLICATION_JSON)
248
    public Response getUser()  {
249
        JsonObject userInfoJson = new JsonObject();
250
        try {
251
            OIDCAuthenticationToken authentication = null;
252
            try {
253
                authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
254
            }catch (Exception e){
255
                logger.info("Try to get User info - no context found ");
256
                return Response.status(404).entity(compose404Message("Get User info: no context found ")).type(MediaType.APPLICATION_JSON).build();
257
            }
258
            UserInfo userInfo = authentication.getUserInfo();
259
            if(userInfo == null){
260
                return Response.status(404).entity(compose404Message("Get User info: user info is null ")).type(MediaType.APPLICATION_JSON).build();
261
            }
262
            logger.info("Get User:\n name: " + authentication.getUserInfo().getGivenName() + " " + authentication.getUserInfo().getFamilyName());
263

    
264

    
265
            userInfoJson.addProperty("sub", userInfo.getSub());
266
            userInfoJson.addProperty("name", userInfo.getName());
267
            userInfoJson.addProperty("given_name", userInfo.getGivenName());
268
            userInfoJson.addProperty("family_name", userInfo.getFamilyName());
269
            userInfoJson.addProperty("email", userInfo.getEmail());
270

    
271
            JsonArray roles = new JsonArray();
272
            JsonObject source = authentication.getUserInfo().getSource();
273
            roles = source.getAsJsonArray("edu_person_entitlements");
274
            userInfoJson.add("edu_person_entitlements", roles);
275
        }catch (Exception e){
276
            logger.error("Get User info: An error occured ",e);
277
            return Response.status(500).entity(compose500Message("Get User info: An error occured ",e)).type(MediaType.APPLICATION_JSON).build();
278
        }
279
        return Response.status(200).entity(userInfoJson.toString()).type(MediaType.APPLICATION_JSON).build();
280
    }
281
    /* JSON Utility Methods */
282

    
283
    private String compose401Message(String message) {
284
        return  "{ \"status\" : \"error\", \"code\" : \"401\", \"message\" : \"  " + message +" \" }";
285
    }
286

    
287
    private String compose404Message(String message) {
288
        return  "{ \"status\" : \"error\", \"code\" : \"404\", \"message\" : \"  " + message +" \" }";
289
    }
290

    
291
    private String compose500Message(String message, Exception exception) {
292
        return  "{ \"status\" : \"fail\", \"code\" : \"500\", \"message\" : \"  " + message + "\", " +
293
                "\"description\" : \""+  exception.getMessage() +"\" }";
294
    }
295

    
296
    private String composeDataResponse(UserInfo user) {
297
        return "{ \"status\" : \"success\", \"code\": \"200\", " + "\"data\" : \"" + JWTGenerator.generateToken(user, "my-very-secret") + "\" }";
298
    }
299

    
300
    private String composeDataResponse(MigrationUser user) {
301
        //return "{ \"status\" : \"success\", \"code\": \"200\", " + "\"data\" : " + new Gson().toJson(user) + " }";
302
        return "{ \"status\" : \"success\", \"code\": \"200\", " + "\"data\" : \"" + JWTGenerator.generateToken(user, "my-very-secret") + "\" }";
303
    }
304

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

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

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

    
317
    public String getIssuer() {
318
        return issuer;
319
    }
320

    
321
    public void setIssuer(String issuer) {
322
        this.issuer = issuer;
323
    }
324
}
    (1-1/1)