Merge remote-tracking branch 'origin/pr/210' into develop

Signed-off-by: Andrew DeMaria <lostonamountain@gmail.com>
master
Andrew DeMaria 8 years ago
commit 0a16c2cb52
No known key found for this signature in database
GPG Key ID: 0A3F5E91F8364EDF
  1. 67
      libresonic-main/src/main/java/org/libresonic/player/command/PasswordSettingsCommand.java
  2. 12
      libresonic-main/src/main/java/org/libresonic/player/controller/LoginController.java
  3. 85
      libresonic-main/src/main/java/org/libresonic/player/controller/PasswordSettingsController.java
  4. 5
      libresonic-main/src/main/java/org/libresonic/player/security/WebSecurityConfig.java
  5. 48
      libresonic-main/src/main/java/org/libresonic/player/validator/PasswordSettingsValidator.java
  6. 1
      libresonic-main/src/main/webapp/WEB-INF/jsp/passwordSettings.jsp

@ -0,0 +1,67 @@
/*
This file is part of Libresonic.
Libresonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Libresonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Libresonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2016 (C) Libresonic Authors
Based upon Subsonic, Copyright 2009 (C) Sindre Mehus
*/
package org.libresonic.player.command;
import org.libresonic.player.controller.*;
/**
* Command used in {@link PasswordSettingsController}.
*
* @author Sindre Mehus
*/
public class PasswordSettingsCommand {
private String username;
private String password;
private String confirmPassword;
private boolean ldapAuthenticated;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getConfirmPassword() {
return confirmPassword;
}
public void setConfirmPassword(String confirmPassword) {
this.confirmPassword = confirmPassword;
}
public boolean isLdapAuthenticated() {
return ldapAuthenticated;
}
public void setLdapAuthenticated(boolean ldapAuthenticated) {
this.ldapAuthenticated = ldapAuthenticated;
}
}

@ -35,7 +35,7 @@ public class LoginController {
@Autowired @Autowired
private SettingsService settingsService; private SettingsService settingsService;
@RequestMapping(value = "/login", method = { RequestMethod.GET, RequestMethod.POST }) @RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception { public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception {
// Auto-login if "user" and "password" parameters are given. // Auto-login if "user" and "password" parameters are given.
@ -64,14 +64,4 @@ public class LoginController {
return new ModelAndView("login", "model", map); return new ModelAndView("login", "model", map);
} }
@RequestMapping(value="/logout", method = RequestMethod.GET)
public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null){
LOG.info("User "+auth.getName()+" requested logout.");
new SecurityContextLogoutHandler().logout(request, response, auth);
}
return "redirect:/login?logout";
}
} }

@ -0,0 +1,85 @@
/*
This file is part of Libresonic.
Libresonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Libresonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Libresonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2016 (C) Libresonic Authors
Based upon Subsonic, Copyright 2009 (C) Sindre Mehus
*/
package org.libresonic.player.controller;
import org.libresonic.player.command.PasswordSettingsCommand;
import org.libresonic.player.domain.User;
import org.libresonic.player.service.SecurityService;
import org.libresonic.player.validator.PasswordSettingsValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* Controller for the page used to change password.
*
* @author Sindre Mehus
*/
@org.springframework.stereotype.Controller
@RequestMapping("/passwordSettings")
public class PasswordSettingsController {
@Autowired
private SecurityService securityService;
@Autowired
private PasswordSettingsValidator passwordSettingsValidator;
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(passwordSettingsValidator);
}
@RequestMapping(method = RequestMethod.GET)
protected ModelAndView displayForm(HttpServletRequest request) throws Exception {
PasswordSettingsCommand command = new PasswordSettingsCommand();
User user = securityService.getCurrentUser(request);
command.setUsername(user.getUsername());
command.setLdapAuthenticated(user.isLdapAuthenticated());
return new ModelAndView("passwordSettings","command",command);
}
@RequestMapping(method = RequestMethod.POST)
protected String doSubmitAction(HttpServletRequest request,@ModelAttribute("command") @Validated PasswordSettingsCommand command,BindingResult bindingResult, RedirectAttributes redirectAttributes) throws Exception {
if (!bindingResult.hasErrors()) {
User user = securityService.getUserByName(command.getUsername());
user.setPassword(command.getPassword());
securityService.updateUser(user);
command.setPassword(null);
command.setConfirmPassword(null);
redirectAttributes.addFlashAttribute("settings_toast", true);
} else {
return "passwordSettings";
}
return "redirect:passwordSettings.view";
}
}

@ -10,6 +10,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@ -57,7 +58,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
"/flash/**", "/script/**", "/sonos/**", "/crossdomain.xml") "/flash/**", "/script/**", "/sonos/**", "/crossdomain.xml")
.permitAll() .permitAll()
.antMatchers("/personalSettings.view", "/passwordSettings.view", .antMatchers("/personalSettings.view", "/passwordSettings.view",
"/playerSettings.view", "/shareSettings.view") "/playerSettings.view", "/shareSettings.view","/passwordSettings.view")
.hasRole("SETTINGS") .hasRole("SETTINGS")
.antMatchers("/generalSettings.view","/advancedSettings.view","/userSettings.view", .antMatchers("/generalSettings.view","/advancedSettings.view","/userSettings.view",
"/musicFolderSettings.view","/networkSettings.view") "/musicFolderSettings.view","/networkSettings.view")
@ -86,6 +87,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.failureUrl("/login?error=1") .failureUrl("/login?error=1")
.usernameParameter("j_username") .usernameParameter("j_username")
.passwordParameter("j_password") .passwordParameter("j_password")
// see http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/reference/htmlsingle/#csrf-logout
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login?logout")
.and().rememberMe().userDetailsService(securityService).key("libresonic"); .and().rememberMe().userDetailsService(securityService).key("libresonic");
} }

@ -0,0 +1,48 @@
/*
This file is part of Libresonic.
Libresonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Libresonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Libresonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2016 (C) Libresonic Authors
Based upon Subsonic, Copyright 2009 (C) Sindre Mehus
*/
package org.libresonic.player.validator;
import org.springframework.stereotype.Component;
import org.springframework.validation.*;
import org.libresonic.player.command.*;
import org.libresonic.player.controller.*;
/**
* Validator for {@link PasswordSettingsController}.
*
* @author Sindre Mehus
*/
@Component
public class PasswordSettingsValidator implements Validator {
public boolean supports(Class clazz) {
return clazz.equals(PasswordSettingsCommand.class);
}
public void validate(Object obj, Errors errors) {
PasswordSettingsCommand command = (PasswordSettingsCommand) obj;
if (command.getPassword() == null || command.getPassword().length() == 0) {
errors.rejectValue("password", "usersettings.nopassword");
} else if (!command.getPassword().equals(command.getConfirmPassword())) {
errors.rejectValue("password", "usersettings.wrongpassword");
}
}
}

@ -23,6 +23,7 @@
<fmt:message key="passwordsettings.title" var="title"><fmt:param>${command.username}</fmt:param></fmt:message> <fmt:message key="passwordsettings.title" var="title"><fmt:param>${command.username}</fmt:param></fmt:message>
<h2>${fn:escapeXml(title)}</h2> <h2>${fn:escapeXml(title)}</h2>
<form:form method="post" action="passwordSettings.view" commandName="command"> <form:form method="post" action="passwordSettings.view" commandName="command">
<form:hidden path="username"/>
<table class="indent"> <table class="indent">
<tr> <tr>
<td><fmt:message key="usersettings.newpassword"/></td> <td><fmt:message key="usersettings.newpassword"/></td>

Loading…
Cancel
Save