org.geoserver.rest.security.UserPasswordController.java Source code

Java tutorial

Introduction

Here is the source code for org.geoserver.rest.security.UserPasswordController.java

Source

/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
 * This code is licensed under the GPL 2.0 license, available at the root
 * application directory.
 */
package org.geoserver.rest.security;

import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.lang.StringUtils;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.rest.RestBaseController;
import org.geoserver.rest.RestException;
import org.geoserver.rest.util.MediaTypeExtensions;
import org.geoserver.security.GeoServerSecurityManager;
import org.geoserver.security.GeoServerUserGroupService;
import org.geoserver.security.impl.GeoServerRole;
import org.geoserver.security.impl.GeoServerUser;
import org.geoserver.security.validation.PasswordPolicyException;
import org.geoserver.security.validation.UserGroupStoreValidationWrapper;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(path = RestBaseController.ROOT_PATH + "/security/self/password")
public class UserPasswordController extends RestBaseController {
    static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geoserver.rest");

    static final String UP_NEW_PW = "newPassword";

    static final String XML_ROOT_ELEM = "userPassword";

    @GetMapping()
    public void passwordGet() {
        throw new RestException("You can not request the password!", HttpStatus.METHOD_NOT_ALLOWED);
    }

    @PutMapping(consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE,
            MediaType.TEXT_XML_VALUE, MediaTypeExtensions.TEXT_JSON_VALUE })
    public void passwordPut(@RequestBody Map<String, String> putMap) {
        if (!getManager().checkAuthenticationForRole(SecurityContextHolder.getContext().getAuthentication(),
                GeoServerRole.AUTHENTICATED_ROLE))
            // yes, for backwards compat, it's really METHOD_NOT_ALLOWED
            throw new RestException("Amdinistrative privelges required", HttpStatus.METHOD_NOT_ALLOWED);

        try {
            // Look for the service that handles the current user
            String userName = SecurityContextHolder.getContext().getAuthentication().getName();

            GeoServerUserGroupService ugService = null;

            for (GeoServerUserGroupService service : getManager().loadUserGroupServices()) {
                if (service.getUserByUsername(userName) != null) {
                    ugService = service;
                    break;
                }
            }

            if (ugService == null) {
                throw new RestException("Cannot calculate if PUT is allowed (service not found)",
                        HttpStatus.UNPROCESSABLE_ENTITY);
            }

        } catch (IOException e) {
            throw new RestException("Cannot calculate if PUT is allowed (" + e.getMessage() + ")",
                    HttpStatus.UNPROCESSABLE_ENTITY, e);
        }
        String newpass = putMap.get(UP_NEW_PW);

        if (StringUtils.isBlank(newpass))
            throw new RestException("Missing '" + UP_NEW_PW + "'", HttpStatus.BAD_REQUEST);

        GeoServerUser user = null;
        GeoServerUserGroupService ugService = null;

        try {
            // Look for the authentication service
            String userName = SecurityContextHolder.getContext().getAuthentication().getName();

            for (GeoServerUserGroupService service : getManager().loadUserGroupServices()) {
                user = service.getUserByUsername(userName);
                if (user != null) {
                    ugService = service;
                    break;
                }
            }
        } catch (IOException e) {
            throw new RestException("Cannot retrieve user service", HttpStatus.FAILED_DEPENDENCY, e);
        }

        if (ugService == null) {
            throw new RestException("User service not found", HttpStatus.FAILED_DEPENDENCY);
        }

        // Check again if the provider allows updates
        if (!ugService.canCreateStore()) {
            throw new RestException("User service does not support changing pw", HttpStatus.FAILED_DEPENDENCY);
        }

        try {
            UserGroupStoreValidationWrapper ugStore = new UserGroupStoreValidationWrapper(ugService.createStore());

            user.setPassword(newpass);
            ugStore.updateUser(user);

            ugStore.store();
            ugService.load();

            LOGGER.log(Level.INFO, "Changed password for user {0}", user.getUsername());

        } catch (IOException e) {
            throw new RestException("Internal IO error", HttpStatus.INTERNAL_SERVER_ERROR, e);
        } catch (PasswordPolicyException e) {
            throw new RestException("Bad password", HttpStatus.UNPROCESSABLE_ENTITY, e);
        }
    }

    GeoServerSecurityManager getManager() {
        return GeoServerExtensions.bean(GeoServerSecurityManager.class);
    }
}