package ubic.gemma.web.services.rest;

import gemma.gsec.authentication.UserManager;
import gemma.gsec.model.User;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import ubic.gemma.persistence.util.Settings;
import ubic.gemma.web.services.rest.util.Responder;
import ubic.gemma.web.services.rest.util.ResponseDataObject;
import ubic.gemma.web.services.rest.util.WebService;

import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

/**
 * Handles calls to the root API url and user info api
 *
 * @author tesarst
 */
@Service
@Path("/")
public class RootWebService extends WebService {

    private static final String MSG_WELCOME = "Welcome to Gemma RESTful API.";
    private static final String APIDOCS_URL = Settings.getBaseUrl() + "resources/restapidocs/";

    private UserManager userManager;

    /**
     * Required by spring
     */
    @SuppressWarnings("unused")
    public RootWebService() {
    }

    @Autowired
    public RootWebService( UserManager userManager ) {
        this.userManager = userManager;
    }

    /**
     * Returns an object with API information.
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public ResponseDataObject all( // Params:
            @Context final HttpServletResponse sr // The servlet response, needed for response code setting.
    ) {
        return Responder.code200( new ApiInfoValueObject(), sr );
    }

    /**
     * Retrieves user information. This method is pre-authorized, which means that a session login (via basic http auth)
     * is executed before this code is called. This method then checks that the given username and password match the
     * user logged in the current session, and if so, creates a response with the logged in user information.
     *
     * @param uName the username
     * @param pHash a sha256 hash of the users password
     */
    @GET
    @Path("users/{uname: [a-zA-Z0-9]+}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @PreAuthorize( "hasRole('GROUP_USER')" )
    public ResponseDataObject datasetPlatforms( // Params:
            @PathParam("uname") String uName, // Required
            @QueryParam("phash") String pHash, // Required, default 1
            @Context final HttpServletResponse sr // The servlet response, needed for response code setting.
    ) {
        return Responder.autoCode( this.checkUser(uName, pHash), sr );
    }

    private User checkUser( String uName, String pHash ) {
        User user = userManager.getCurrentUser();
        if( !user.getUserName().equals( uName ) || !DigestUtils.sha256Hex( user.getPassword() ).equals( pHash ) ) return null;
        return user;
    }

    @SuppressWarnings("unused") // Getters used during RS serialization
    private class ApiInfoValueObject {
        private String welcome = MSG_WELCOME;
        private String version = WebService.API_VERSION;
        private String docs = APIDOCS_URL;

        public String getWelcome() {
            return welcome;
        }

        public String getVersion() {
            return version;
        }

        public String getDocs() {
            return docs;
        }
    }

}

@@ -112,60 +112,8 @@
 er;%0A
-import org.apache.commons.codec.digest.DigestUtils;%0A
 impo
@@ -328,16 +328,90 @@
 ttings;%0A
+import ubic.gemma.web.controller.common.auditAndSecurity.UserValueObject;%0A
 import u
@@ -567,16 +567,80 @@
 Service;
+%0Aimport ubic.gemma.web.services.rest.util.WellComposedErrorBody;
 %0A%0Aimport
@@ -769,16 +769,50 @@
 diaType;
+%0Aimport javax.ws.rs.core.Response;
 %0A%0A/**%0A *
@@ -1134,16 +1134,140 @@
 idocs/%22;
+%0A    private static final String ERROR_MSG_USER_INFO_ACCESS = %22Inappropriate privileges. Only your user info is available.%22;
 %0A%0A    pr
@@ -2104,21 +2104,8 @@
 ame 
-and password 
 matc
@@ -2264,64 +2264,8 @@
 ame%0A
-     * @param pHash a sha256 hash of the users password%0A
     
@@ -2431,17 +2431,16 @@
 thorize(
- 
 %22hasRole
@@ -2454,17 +2454,16 @@
 _USER')%22
- 
 )%0A    pu
@@ -2490,24 +2490,16 @@
 ect 
-datasetPlatforms
+loadUser
 ( //
@@ -2569,78 +2569,8 @@
 red%0A
-            @QueryParam(%22phash%22) String pHash, // Required, default 1%0A
     
@@ -2700,28 +2700,8 @@
 turn
- Responder.autoCode(
  thi
@@ -2716,22 +2716,15 @@
 ser(
+ 
 uName,
- pHash),
  sr 
@@ -2745,20 +2745,34 @@
 private 
-User
+ResponseDataObject
  checkUs
@@ -2793,20 +2793,30 @@
 me, 
-String pHash
+HttpServletResponse sr
  ) %7B
@@ -2876,16 +2876,17 @@
       if
+ 
 ( !user.
@@ -2919,106 +2919,265 @@
 e ) 
-%7C%7C !DigestUtils.sha256Hex( user.getPassword() ).equals( pHash ) ) return null;%0A        return user
+) %7B%0A            Response.Status code = Response.Status.UNAUTHORIZED;%0A            return Responder.code( code, new WellComposedErrorBody( code, ERROR_MSG_USER_INFO_ACCESS ), sr );%0A        %7D%0A        return Responder.autoCode( new UserValueObject( user ), sr )
 ;%0A  

Fix load user endpoint