From 53dc138574778606621608c9b43e9fdb11d6fbb4 Mon Sep 17 00:00:00 2001 From: Andrew DeMaria Date: Sun, 15 May 2016 21:05:37 -0600 Subject: [PATCH 1/8] Update to spring 3.X.X temporarily Signed-off-by: Andrew DeMaria --- libresonic-booter/pom.xml | 1 - libresonic-main/pom.xml | 28 ++-------------------------- pom.xml | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/libresonic-booter/pom.xml b/libresonic-booter/pom.xml index 451198ff..b8bf1a68 100644 --- a/libresonic-booter/pom.xml +++ b/libresonic-booter/pom.xml @@ -55,7 +55,6 @@ org.springframework spring - 2.5.6 diff --git a/libresonic-main/pom.xml b/libresonic-main/pom.xml index 3ecbe9f6..449f002f 100644 --- a/libresonic-main/pom.xml +++ b/libresonic-main/pom.xml @@ -28,36 +28,12 @@ org.springframework - spring - 2.5.6 + spring-webmvc org.springframework - spring-webmvc - 2.5.6 - - - org.springframework - spring-beans - - - org.springframework - spring-core - - - org.springframework - spring-context - - - org.springframework - spring-context-support - - - org.springframework - spring-web - - + spring-jdbc diff --git a/pom.xml b/pom.xml index 3ecb5b92..b8e6b250 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,7 @@ true iso-8859-1 2.4.2 + 3.2.17.RELEASE @@ -91,6 +92,21 @@ + + + + org.springframework + spring-webmvc + ${spring.version} + + + org.springframework + spring-jdbc + ${spring.version} + + + + From 3213b3f1151fb125771b9f9817bfe5b0395606c0 Mon Sep 17 00:00:00 2001 From: Andrew DeMaria Date: Sun, 15 May 2016 21:06:20 -0600 Subject: [PATCH 2/8] Update dao layer to use update spring-jdbc 3/4 api Signed-off-by: Andrew DeMaria --- .../org/libresonic/player/dao/AlbumDao.java | 3 +-- .../org/libresonic/player/dao/ArtistDao.java | 3 +-- .../org/libresonic/player/dao/AvatarDao.java | 6 ++--- .../libresonic/player/dao/BookmarkDao.java | 6 ++--- .../player/dao/InternetRadioDao.java | 6 ++--- .../libresonic/player/dao/MediaFileDao.java | 23 +++++++------------ .../libresonic/player/dao/MusicFolderDao.java | 11 ++++----- .../libresonic/player/dao/PlayQueueDao.java | 3 +-- .../org/libresonic/player/dao/PlayerDao.java | 23 ++++++------------- .../libresonic/player/dao/PlaylistDao.java | 3 +-- .../org/libresonic/player/dao/PodcastDao.java | 5 ++-- .../org/libresonic/player/dao/ShareDao.java | 8 +++---- .../libresonic/player/dao/TranscodingDao.java | 6 ++--- .../org/libresonic/player/dao/UserDao.java | 19 ++++++--------- 14 files changed, 49 insertions(+), 76 deletions(-) diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java index 71515156..71cffec2 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java @@ -29,7 +29,6 @@ import java.util.Map; import org.apache.commons.lang.ObjectUtils; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import org.libresonic.player.domain.Album; import org.libresonic.player.domain.MediaFile; @@ -346,7 +345,7 @@ public class AlbumDao extends AbstractDao { return queryForDate("select created from starred_album where album_id=? and username=?", null, albumId, username); } - private static class AlbumMapper implements ParameterizedRowMapper { + private static class AlbumMapper implements RowMapper { public Album mapRow(ResultSet rs, int rowNum) throws SQLException { return new Album( rs.getInt(1), diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java index ea98c9c3..f7b44367 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java @@ -24,7 +24,6 @@ import org.libresonic.player.domain.Artist; import org.libresonic.player.domain.MusicFolder; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import java.sql.ResultSet; import java.sql.SQLException; @@ -199,7 +198,7 @@ public class ArtistDao extends AbstractDao { return queryForDate("select created from starred_artist where artist_id=? and username=?", null, artistId, username); } - private static class ArtistMapper implements ParameterizedRowMapper { + private static class ArtistMapper implements RowMapper { public Artist mapRow(ResultSet rs, int rowNum) throws SQLException { return new Artist( rs.getInt(1), diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/AvatarDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/AvatarDao.java index b571ffc2..118816ce 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/AvatarDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/AvatarDao.java @@ -20,7 +20,7 @@ package org.libresonic.player.dao; import org.libresonic.player.domain.Avatar; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; +import org.springframework.jdbc.core.RowMapper; import java.sql.ResultSet; import java.sql.SQLException; @@ -85,11 +85,11 @@ public class AvatarDao extends AbstractDao { } } - private static class AvatarRowMapper implements ParameterizedRowMapper { + private static class AvatarRowMapper implements RowMapper { public Avatar mapRow(ResultSet rs, int rowNum) throws SQLException { return new Avatar(rs.getInt(1), rs.getString(2), rs.getTimestamp(3), rs.getString(4), rs.getInt(5), rs.getInt(6), rs.getBytes(7)); } } -} \ No newline at end of file +} diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java index de7a976f..1ea9ac44 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java @@ -19,12 +19,12 @@ */ package org.libresonic.player.dao; +import org.springframework.jdbc.core.RowMapper; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; - import org.libresonic.player.domain.Bookmark; /** @@ -81,7 +81,7 @@ public class BookmarkDao extends AbstractDao { update("delete from bookmark where username=? and media_file_id=?", username, mediaFileId); } - private static class BookmarkRowMapper implements ParameterizedRowMapper { + private static class BookmarkRowMapper implements RowMapper { public Bookmark mapRow(ResultSet rs, int rowNum) throws SQLException { return new Bookmark(rs.getInt(1), rs.getInt(2), rs.getLong(3), rs.getString(4), rs.getString(5), rs.getTimestamp(6), rs.getTimestamp(7)); diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/InternetRadioDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/InternetRadioDao.java index b1a1d4d4..385e4a90 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/InternetRadioDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/InternetRadioDao.java @@ -19,12 +19,12 @@ */ package org.libresonic.player.dao; +import org.springframework.jdbc.core.RowMapper; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; - import org.libresonic.player.Logger; import org.libresonic.player.domain.InternetRadio; @@ -81,7 +81,7 @@ public class InternetRadioDao extends AbstractDao { update(sql, radio.getName(), radio.getStreamUrl(), radio.getHomepageUrl(), radio.isEnabled(), radio.getChanged(), radio.getId()); } - private static class InternetRadioRowMapper implements ParameterizedRowMapper { + private static class InternetRadioRowMapper implements RowMapper { public InternetRadio mapRow(ResultSet rs, int rowNum) throws SQLException { return new InternetRadio(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getBoolean(5), rs.getTimestamp(6)); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java index 25968340..78dd0b47 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java @@ -19,22 +19,15 @@ */ package org.libresonic.player.dao; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import org.apache.commons.lang.StringUtils; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; - import org.libresonic.player.domain.Genre; import org.libresonic.player.domain.MediaFile; import org.libresonic.player.domain.MusicFolder; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; import static org.libresonic.player.domain.MediaFile.MediaType; import static org.libresonic.player.domain.MediaFile.MediaType.*; @@ -568,7 +561,7 @@ public class MediaFileDao extends AbstractDao { update("checkpoint"); } - private static class MediaFileMapper implements ParameterizedRowMapper { + private static class MediaFileMapper implements RowMapper { public MediaFile mapRow(ResultSet rs, int rowNum) throws SQLException { return new MediaFile( rs.getInt(1), @@ -604,7 +597,7 @@ public class MediaFileDao extends AbstractDao { } } - private static class MusicFileInfoMapper implements ParameterizedRowMapper { + private static class MusicFileInfoMapper implements RowMapper { public MediaFile mapRow(ResultSet rs, int rowNum) throws SQLException { MediaFile file = new MediaFile(); file.setPlayCount(rs.getInt(1)); @@ -614,7 +607,7 @@ public class MediaFileDao extends AbstractDao { } } - private static class GenreMapper implements ParameterizedRowMapper { + private static class GenreMapper implements RowMapper { public Genre mapRow(ResultSet rs, int rowNum) throws SQLException { return new Genre(rs.getString(1), rs.getInt(2), rs.getInt(3)); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/MusicFolderDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/MusicFolderDao.java index ca997b45..49dcdc3e 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/MusicFolderDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/MusicFolderDao.java @@ -19,16 +19,15 @@ */ package org.libresonic.player.dao; +import org.libresonic.player.Logger; +import org.libresonic.player.domain.MusicFolder; +import org.springframework.jdbc.core.RowMapper; + import java.io.File; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; - -import org.libresonic.player.Logger; -import org.libresonic.player.domain.MusicFolder; - /** * Provides database services for music folders. * @@ -99,7 +98,7 @@ public class MusicFolderDao extends AbstractDao { } } - private static class MusicFolderRowMapper implements ParameterizedRowMapper { + private static class MusicFolderRowMapper implements RowMapper { public MusicFolder mapRow(ResultSet rs, int rowNum) throws SQLException { return new MusicFolder(rs.getInt(1), new File(rs.getString(2)), rs.getString(3), rs.getBoolean(4), rs.getTimestamp(5)); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java index f56bd232..a098c43b 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java @@ -23,7 +23,6 @@ import java.sql.SQLException; import java.util.List; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import org.libresonic.player.domain.SavedPlayQueue; @@ -60,7 +59,7 @@ public class PlayQueueDao extends AbstractDao { } } - private static class PlayQueueMapper implements ParameterizedRowMapper { + private static class PlayQueueMapper implements RowMapper { public SavedPlayQueue mapRow(ResultSet rs, int rowNum) throws SQLException { return new SavedPlayQueue(rs.getInt(1), rs.getString(2), diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java index be855e61..4530fd35 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java @@ -19,22 +19,13 @@ */ package org.libresonic.player.dao; +import org.libresonic.player.Logger; +import org.libresonic.player.domain.*; +import org.springframework.jdbc.core.RowMapper; + import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Calendar; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; - -import org.libresonic.player.Logger; -import org.libresonic.player.domain.CoverArtScheme; -import org.libresonic.player.domain.Player; -import org.libresonic.player.domain.PlayerTechnology; -import org.libresonic.player.domain.PlayQueue; -import org.libresonic.player.domain.TranscodeScheme; +import java.util.*; /** * Provides player-related database services. @@ -95,7 +86,7 @@ public class PlayerDao extends AbstractDao { * @param player The player to create. */ public synchronized void createPlayer(Player player) { - int id = getJdbcTemplate().queryForInt("select max(id) from player") + 1; + int id = getJdbcTemplate().queryForObject("select max(id) from player", Integer.class) + 1; player.setId(String.valueOf(id)); String sql = "insert into player (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")"; update(sql, player.getId(), player.getName(), player.getType(), player.getUsername(), @@ -169,7 +160,7 @@ public class PlayerDao extends AbstractDao { player.setPlayQueue(playQueue); } - private class PlayerRowMapper implements ParameterizedRowMapper { + private class PlayerRowMapper implements RowMapper { public Player mapRow(ResultSet rs, int rowNum) throws SQLException { Player player = new Player(); int col = 1; diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java index 996d84eb..e41e3781 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java @@ -23,7 +23,6 @@ import org.libresonic.player.Logger; import org.libresonic.player.domain.MediaFile; import org.libresonic.player.domain.Playlist; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import java.sql.ResultSet; import java.sql.SQLException; @@ -125,7 +124,7 @@ public class PlaylistDao extends AbstractDao { new Date(), playlist.getImportedFrom(), playlist.getId()); } - private static class PlaylistMapper implements ParameterizedRowMapper { + private static class PlaylistMapper implements RowMapper { public Playlist mapRow(ResultSet rs, int rowNum) throws SQLException { return new Playlist( rs.getInt(1), diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java index ca84b044..b61d870b 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java @@ -24,7 +24,6 @@ import java.sql.SQLException; import java.util.List; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import org.libresonic.player.domain.PodcastChannel; import org.libresonic.player.domain.PodcastEpisode; @@ -55,7 +54,7 @@ public class PodcastDao extends AbstractDao { update(sql, null, channel.getUrl(), channel.getTitle(), channel.getDescription(), channel.getImageUrl(), channel.getStatus().name(), channel.getErrorMessage()); - return getJdbcTemplate().queryForInt("select max(id) from podcast_channel"); + return getJdbcTemplate().queryForObject("select max(id) from podcast_channel", Integer.class); } /** @@ -182,7 +181,7 @@ public class PodcastDao extends AbstractDao { } } - private static class PodcastEpisodeRowMapper implements ParameterizedRowMapper { + private static class PodcastEpisodeRowMapper implements RowMapper { public PodcastEpisode mapRow(ResultSet rs, int rowNum) throws SQLException { return new PodcastEpisode(rs.getInt(1), rs.getInt(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6), rs.getTimestamp(7), rs.getString(8), (Long) rs.getObject(9), diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java index 15ca4fa3..702e4965 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java @@ -26,7 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; +import org.springframework.jdbc.core.RowMapper; import org.libresonic.player.domain.MusicFolder; import org.libresonic.player.domain.Share; @@ -53,7 +53,7 @@ public class ShareDao extends AbstractDao { update(sql, null, share.getName(), share.getDescription(), share.getUsername(), share.getCreated(), share.getExpires(), share.getLastVisited(), share.getVisitCount()); - int id = getJdbcTemplate().queryForInt("select max(id) from share"); + int id = getJdbcTemplate().queryForObject("select max(id) from share", Integer.class); share.setId(id); } @@ -129,14 +129,14 @@ public class ShareDao extends AbstractDao { update("delete from share where id=?", id); } - private static class ShareRowMapper implements ParameterizedRowMapper { + private static class ShareRowMapper implements RowMapper { public Share mapRow(ResultSet rs, int rowNum) throws SQLException { return new Share(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getTimestamp(5), rs.getTimestamp(6), rs.getTimestamp(7), rs.getInt(8)); } } - private static class ShareFileRowMapper implements ParameterizedRowMapper { + private static class ShareFileRowMapper implements RowMapper { public String mapRow(ResultSet rs, int rowNum) throws SQLException { return rs.getString(1); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java index bfd43b1f..5ca8a3e9 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java @@ -23,7 +23,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; +import org.springframework.jdbc.core.RowMapper; import org.libresonic.player.Logger; import org.libresonic.player.domain.Transcoding; @@ -82,7 +82,7 @@ public class TranscodingDao extends AbstractDao { * @param transcoding The transcoding to create. */ public synchronized void createTranscoding(Transcoding transcoding) { - int id = getJdbcTemplate().queryForInt("select max(id) + 1 from transcoding2"); + int id = getJdbcTemplate().queryForObject("select max(id) + 1 from transcoding2", Integer.class); transcoding.setId(id); String sql = "insert into transcoding2 (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")"; update(sql, transcoding.getId(), transcoding.getName(), transcoding.getSourceFormats(), @@ -115,7 +115,7 @@ public class TranscodingDao extends AbstractDao { transcoding.getStep3(), transcoding.isDefaultActive(), transcoding.getId()); } - private static class TranscodingRowMapper implements ParameterizedRowMapper { + private static class TranscodingRowMapper implements RowMapper { public Transcoding mapRow(ResultSet rs, int rowNum) throws SQLException { return new Transcoding(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6), rs.getString(7), rs.getBoolean(8)); diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java index 8af3216e..abd1ac2e 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java @@ -19,20 +19,15 @@ */ package org.libresonic.player.dao; +import org.libresonic.player.Logger; +import org.libresonic.player.domain.*; +import org.libresonic.player.util.StringUtil; +import org.springframework.jdbc.core.RowMapper; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; - -import org.libresonic.player.Logger; -import org.libresonic.player.domain.AlbumListType; -import org.libresonic.player.domain.AvatarScheme; -import org.libresonic.player.domain.TranscodeScheme; -import org.libresonic.player.domain.User; -import org.libresonic.player.domain.UserSettings; -import org.libresonic.player.util.StringUtil; - /** * Provides user-related database services. * @@ -296,7 +291,7 @@ public class UserDao extends AbstractDao { } } - private class UserRowMapper implements ParameterizedRowMapper { + private class UserRowMapper implements RowMapper { public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(rs.getString(1), decrypt(rs.getString(2)), rs.getString(3), rs.getBoolean(4), rs.getLong(5), rs.getLong(6), rs.getLong(7)); @@ -305,7 +300,7 @@ public class UserDao extends AbstractDao { } } - private static class UserSettingsRowMapper implements ParameterizedRowMapper { + private static class UserSettingsRowMapper implements RowMapper { public UserSettings mapRow(ResultSet rs, int rowNum) throws SQLException { int col = 1; UserSettings settings = new UserSettings(rs.getString(col++)); From 6f54dc05d590cf9ffb0fed393f0b03295f4b57ce Mon Sep 17 00:00:00 2001 From: Andrew DeMaria Date: Mon, 16 May 2016 22:32:48 -0600 Subject: [PATCH 3/8] Fixed issue with null Integer id return value Signed-off-by: Andrew DeMaria --- .../src/main/java/org/libresonic/player/dao/PlayerDao.java | 6 +++++- .../java/org/libresonic/player/dao/TranscodingDao.java | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java index 4530fd35..d470452d 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java @@ -86,7 +86,11 @@ public class PlayerDao extends AbstractDao { * @param player The player to create. */ public synchronized void createPlayer(Player player) { - int id = getJdbcTemplate().queryForObject("select max(id) from player", Integer.class) + 1; + Integer existingMax = getJdbcTemplate().queryForObject("select max(id) from player", Integer.class); + if(existingMax == null) { + existingMax = 0; + } + int id = existingMax + 1; player.setId(String.valueOf(id)); String sql = "insert into player (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")"; update(sql, player.getId(), player.getName(), player.getType(), player.getUsername(), diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java index 5ca8a3e9..d3d11720 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java @@ -82,8 +82,11 @@ public class TranscodingDao extends AbstractDao { * @param transcoding The transcoding to create. */ public synchronized void createTranscoding(Transcoding transcoding) { - int id = getJdbcTemplate().queryForObject("select max(id) + 1 from transcoding2", Integer.class); - transcoding.setId(id); + Integer existingMax = getJdbcTemplate().queryForObject("select max(id) from transcoding2", Integer.class); + if(existingMax == null) { + existingMax = 0; + } + transcoding.setId(existingMax + 1); String sql = "insert into transcoding2 (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")"; update(sql, transcoding.getId(), transcoding.getName(), transcoding.getSourceFormats(), transcoding.getTargetFormat(), transcoding.getStep1(), From 1e81ae70d42c6056a943e5ea39ae88ae59f145ec Mon Sep 17 00:00:00 2001 From: Andrew DeMaria Date: Tue, 31 May 2016 23:27:22 -0600 Subject: [PATCH 4/8] Added missing dependencies Signed-off-by: Andrew DeMaria --- libresonic-main/pom.xml | 20 ++++++++++++++++++++ pom.xml | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/libresonic-main/pom.xml b/libresonic-main/pom.xml index 449f002f..8eeb6e45 100644 --- a/libresonic-main/pom.xml +++ b/libresonic-main/pom.xml @@ -31,11 +31,31 @@ spring-webmvc + + org.springframework + spring-web + + org.springframework spring-jdbc + + org.springframework + spring-tx + + + + org.springframework + spring-context + + + + org.springframework + spring-beans + + org.acegisecurity acegi-security diff --git a/pom.xml b/pom.xml index b8e6b250..5a18cf41 100644 --- a/pom.xml +++ b/pom.xml @@ -99,11 +99,31 @@ spring-webmvc ${spring.version} + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-web + ${spring.version} + org.springframework spring-jdbc ${spring.version} + + org.springframework + spring-tx + ${spring.version} + + + org.springframework + spring-beans + ${spring.version} + From 04f0167f66a625584e58064f2674bf5beddd801c Mon Sep 17 00:00:00 2001 From: Andrew DeMaria Date: Wed, 19 Oct 2016 20:25:02 -0600 Subject: [PATCH 5/8] Migrate from acegisecurity to spring security Signed-off-by: Andrew DeMaria --- libresonic-main/pom.xml | 33 +- .../player/controller/MultiController.java | 42 ++- .../ldap/LibresonicLdapBindAuthenticator.java | 132 -------- ...tailsServiceBasedAuthoritiesPopulator.java | 51 --- .../LibresonicApplicationEventListener.java | 6 +- .../RESTRequestParameterProcessingFilter.java | 27 +- .../player/service/SecurityService.java | 40 ++- .../WEB-INF/applicationContext-security.xml | 305 ++++-------------- .../src/main/webapp/WEB-INF/jsp/login.jsp | 6 +- .../src/main/webapp/WEB-INF/jsp/top.jsp | 2 +- .../src/main/webapp/WEB-INF/web.xml | 10 +- pom.xml | 17 + 12 files changed, 147 insertions(+), 524 deletions(-) delete mode 100644 libresonic-main/src/main/java/org/libresonic/player/ldap/LibresonicLdapBindAuthenticator.java delete mode 100644 libresonic-main/src/main/java/org/libresonic/player/ldap/UserDetailsServiceBasedAuthoritiesPopulator.java diff --git a/libresonic-main/pom.xml b/libresonic-main/pom.xml index 8eeb6e45..70abbc5c 100644 --- a/libresonic-main/pom.xml +++ b/libresonic-main/pom.xml @@ -57,27 +57,18 @@ - org.acegisecurity - acegi-security - 1.0.5 - - - org.springframework - spring-core - - - org.springframework - spring-remoting - - - org.springframework - spring-jdbc - - - org.springframework - spring-support - - + org.springframework.security + spring-security-web + + + + org.springframework.security + spring-security-ldap + + + + org.springframework.security + spring-security-config diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java index 8564e46e..00e318aa 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java @@ -19,30 +19,19 @@ */ package org.libresonic.player.controller; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Date; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import javax.mail.Message; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; - +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import net.tanesha.recaptcha.ReCaptcha; +import net.tanesha.recaptcha.ReCaptchaFactory; +import net.tanesha.recaptcha.ReCaptchaResponse; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; -import org.springframework.web.bind.ServletRequestUtils; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.multiaction.MultiActionController; -import org.springframework.web.servlet.view.RedirectView; - import org.libresonic.player.Logger; import org.libresonic.player.domain.Playlist; import org.libresonic.player.domain.User; @@ -51,9 +40,16 @@ import org.libresonic.player.service.PlaylistService; import org.libresonic.player.service.SecurityService; import org.libresonic.player.service.SettingsService; import org.libresonic.player.util.StringUtil; -import net.tanesha.recaptcha.ReCaptcha; -import net.tanesha.recaptcha.ReCaptchaFactory; -import net.tanesha.recaptcha.ReCaptchaResponse; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.bind.ServletRequestUtils; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.multiaction.MultiActionController; +import org.springframework.web.servlet.view.RedirectView; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; /** * Multi-controller used for simple pages. @@ -76,8 +72,10 @@ public class MultiController extends MultiActionController { if (username != null && password != null) { username = StringUtil.urlEncode(username); password = StringUtil.urlEncode(password); - return new ModelAndView(new RedirectView("j_acegi_security_check?j_username=" + username + - "&j_password=" + password + "&_acegi_security_remember_me=checked")); + return new ModelAndView(new RedirectView("/j_spring_security_check?"+ + UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY+"=" + username + + "&"+UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_PASSWORD_KEY+"=" + password + )); } Map map = new HashMap(); @@ -296,4 +294,4 @@ public class MultiController extends MultiActionController { public void setPlaylistService(PlaylistService playlistService) { this.playlistService = playlistService; } -} \ No newline at end of file +} diff --git a/libresonic-main/src/main/java/org/libresonic/player/ldap/LibresonicLdapBindAuthenticator.java b/libresonic-main/src/main/java/org/libresonic/player/ldap/LibresonicLdapBindAuthenticator.java deleted file mode 100644 index 3591f944..00000000 --- a/libresonic-main/src/main/java/org/libresonic/player/ldap/LibresonicLdapBindAuthenticator.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - 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 . - - Copyright 2016 (C) Libresonic Authors - Based upon Subsonic, Copyright 2009 (C) Sindre Mehus - */ -package org.libresonic.player.ldap; - -import org.libresonic.player.Logger; -import org.libresonic.player.domain.User; -import org.libresonic.player.service.SecurityService; -import org.libresonic.player.service.SettingsService; -import org.acegisecurity.BadCredentialsException; -import org.acegisecurity.ldap.DefaultInitialDirContextFactory; -import org.acegisecurity.ldap.search.FilterBasedLdapUserSearch; -import org.acegisecurity.providers.ldap.LdapAuthenticator; -import org.acegisecurity.providers.ldap.authenticator.BindAuthenticator; -import org.acegisecurity.userdetails.ldap.LdapUserDetails; -import org.apache.commons.lang.StringUtils; - -import java.util.HashMap; -import java.util.Map; - -/** - * LDAP authenticator which uses a delegate {@link BindAuthenticator}, and which - * supports dynamically changing LDAP provider URL and search filter. - * - * @author Sindre Mehus - */ -public class LibresonicLdapBindAuthenticator implements LdapAuthenticator { - - private static final Logger LOG = Logger.getLogger(LibresonicLdapBindAuthenticator.class); - - private SecurityService securityService; - private SettingsService settingsService; - - private long authenticatorTimestamp; - private BindAuthenticator delegateAuthenticator; - - public LdapUserDetails authenticate(String username, String password) { - - // LDAP authentication must be enabled on the system. - if (!settingsService.isLdapEnabled()) { - throw new BadCredentialsException("LDAP authentication disabled."); - } - - // User must be defined in Libresonic, unless auto-shadowing is enabled. - User user = securityService.getUserByName(username); - if (user == null && !settingsService.isLdapAutoShadowing()) { - throw new BadCredentialsException("User does not exist."); - } - - // LDAP authentication must be enabled for the given user. - if (user != null && !user.isLdapAuthenticated()) { - throw new BadCredentialsException("LDAP authentication disabled for user."); - } - - try { - createDelegate(); - LdapUserDetails details = delegateAuthenticator.authenticate(username, password); - if (details != null) { - LOG.info("User '" + username + "' successfully authenticated in LDAP. DN: " + details.getDn()); - - if (user == null) { - User newUser = new User(username, "", null, true, 0L, 0L, 0L); - newUser.setStreamRole(true); - newUser.setSettingsRole(true); - securityService.createUser(newUser); - LOG.info("Created local user '" + username + "' for DN " + details.getDn()); - } - } - - return details; - } catch (RuntimeException x) { - LOG.info("Failed to authenticate user '" + username + "' in LDAP.", x); - throw x; - } - } - - /** - * Creates the delegate {@link BindAuthenticator}. - */ - private synchronized void createDelegate() { - - // Only create it if necessary. - if (delegateAuthenticator == null || authenticatorTimestamp < settingsService.getSettingsChanged()) { - - DefaultInitialDirContextFactory contextFactory = new DefaultInitialDirContextFactory(settingsService.getLdapUrl()); - - String managerDn = settingsService.getLdapManagerDn(); - String managerPassword = settingsService.getLdapManagerPassword(); - if (StringUtils.isNotEmpty(managerDn) && StringUtils.isNotEmpty(managerPassword)) { - contextFactory.setManagerDn(managerDn); - contextFactory.setManagerPassword(managerPassword); - } - - Map extraEnvVars = new HashMap(); - extraEnvVars.put("java.naming.referral", "follow"); - contextFactory.setExtraEnvVars(extraEnvVars); - - FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch("", settingsService.getLdapSearchFilter(), contextFactory); - userSearch.setSearchSubtree(true); - userSearch.setDerefLinkFlag(true); - - delegateAuthenticator = new BindAuthenticator(contextFactory); - delegateAuthenticator.setUserSearch(userSearch); - - authenticatorTimestamp = settingsService.getSettingsChanged(); - } - } - - public void setSecurityService(SecurityService securityService) { - this.securityService = securityService; - } - - public void setSettingsService(SettingsService settingsService) { - this.settingsService = settingsService; - } -} diff --git a/libresonic-main/src/main/java/org/libresonic/player/ldap/UserDetailsServiceBasedAuthoritiesPopulator.java b/libresonic-main/src/main/java/org/libresonic/player/ldap/UserDetailsServiceBasedAuthoritiesPopulator.java deleted file mode 100644 index 81f4e3ef..00000000 --- a/libresonic-main/src/main/java/org/libresonic/player/ldap/UserDetailsServiceBasedAuthoritiesPopulator.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - 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 . - - Copyright 2016 (C) Libresonic Authors - Based upon Subsonic, Copyright 2009 (C) Sindre Mehus - */ -package org.libresonic.player.ldap; - -import org.acegisecurity.GrantedAuthority; -import org.acegisecurity.ldap.LdapDataAccessException; -import org.acegisecurity.providers.ldap.LdapAuthoritiesPopulator; -import org.acegisecurity.userdetails.UserDetailsService; -import org.acegisecurity.userdetails.UserDetails; -import org.acegisecurity.userdetails.ldap.LdapUserDetails; - -/** - * An {@link LdapAuthoritiesPopulator} that retrieves the roles from the - * database using the {@link UserDetailsService} instead of retrieving the roles - * from LDAP. An instance of this class can be configured for the - * {@link org.acegisecurity.providers.ldap.LdapAuthenticationProvider} when - * authentication should be done using LDAP and authorization using the - * information stored in the database. - * - * @author Thomas M. Hofmann - */ -public class UserDetailsServiceBasedAuthoritiesPopulator implements LdapAuthoritiesPopulator { - - private UserDetailsService userDetailsService; - - public GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetails) throws LdapDataAccessException { - UserDetails details = userDetailsService.loadUserByUsername(userDetails.getUsername()); - return details.getAuthorities(); - } - - public void setUserDetailsService(UserDetailsService userDetailsService) { - this.userDetailsService = userDetailsService; - } -} \ No newline at end of file diff --git a/libresonic-main/src/main/java/org/libresonic/player/security/LibresonicApplicationEventListener.java b/libresonic-main/src/main/java/org/libresonic/player/security/LibresonicApplicationEventListener.java index 48469d42..dfeaee5f 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/security/LibresonicApplicationEventListener.java +++ b/libresonic-main/src/main/java/org/libresonic/player/security/LibresonicApplicationEventListener.java @@ -19,11 +19,11 @@ package org.libresonic.player.security; -import org.acegisecurity.event.authentication.AbstractAuthenticationFailureEvent; -import org.acegisecurity.providers.AbstractAuthenticationToken; -import org.acegisecurity.ui.WebAuthenticationDetails; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent; +import org.springframework.security.web.authentication.WebAuthenticationDetails; /** * @author Sindre Mehus diff --git a/libresonic-main/src/main/java/org/libresonic/player/security/RESTRequestParameterProcessingFilter.java b/libresonic-main/src/main/java/org/libresonic/player/security/RESTRequestParameterProcessingFilter.java index 9081c372..efa374b6 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/security/RESTRequestParameterProcessingFilter.java +++ b/libresonic-main/src/main/java/org/libresonic/player/security/RESTRequestParameterProcessingFilter.java @@ -19,25 +19,8 @@ */ package org.libresonic.player.security; -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.acegisecurity.Authentication; -import org.acegisecurity.AuthenticationException; -import org.acegisecurity.context.SecurityContextHolder; -import org.acegisecurity.providers.ProviderManager; -import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.StringUtils; - import org.libresonic.player.Logger; import org.libresonic.player.controller.JAXBWriter; import org.libresonic.player.controller.RESTController; @@ -47,6 +30,16 @@ import org.libresonic.player.domain.Version; import org.libresonic.player.service.SecurityService; import org.libresonic.player.service.SettingsService; import org.libresonic.player.util.StringUtil; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; /** * Performs authentication based on credentials being present in the HTTP request parameters. Also checks diff --git a/libresonic-main/src/main/java/org/libresonic/player/service/SecurityService.java b/libresonic-main/src/main/java/org/libresonic/player/service/SecurityService.java index 773e215e..2b79c018 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/service/SecurityService.java +++ b/libresonic-main/src/main/java/org/libresonic/player/service/SecurityService.java @@ -19,20 +19,6 @@ */ package org.libresonic.player.service; -import java.io.File; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -import org.acegisecurity.GrantedAuthority; -import org.acegisecurity.GrantedAuthorityImpl; -import org.acegisecurity.providers.dao.DaoAuthenticationProvider; -import org.acegisecurity.userdetails.UserDetails; -import org.acegisecurity.userdetails.UserDetailsService; -import org.acegisecurity.userdetails.UsernameNotFoundException; -import org.acegisecurity.wrapper.SecurityContextHolderAwareRequestWrapper; -import org.springframework.dao.DataAccessException; - import net.sf.ehcache.Ehcache; import org.libresonic.player.Logger; import org.libresonic.player.dao.UserDao; @@ -40,6 +26,18 @@ import org.libresonic.player.domain.MediaFile; import org.libresonic.player.domain.MusicFolder; import org.libresonic.player.domain.User; import org.libresonic.player.util.FileUtil; +import org.springframework.dao.DataAccessException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.util.ArrayList; +import java.util.List; /** * Provides security-related services for authentication and authorization. @@ -57,7 +55,7 @@ public class SecurityService implements UserDetailsService { /** * Locates the user based on the username. * - * @param username The username presented to the {@link DaoAuthenticationProvider} + * @param username The username * @return A fully populated user record (never null) * @throws UsernameNotFoundException if the user could not be found or the user has no GrantedAuthority. * @throws DataAccessException If user could not be found for a repository-specific reason. @@ -69,16 +67,14 @@ public class SecurityService implements UserDetailsService { } String[] roles = userDao.getRolesForUser(username); - GrantedAuthority[] authorities = new GrantedAuthority[roles.length]; + List authorities = new ArrayList<>(); + authorities.add(new SimpleGrantedAuthority("IS_AUTHENTICATED_ANONYMOUSLY")); + authorities.add(new SimpleGrantedAuthority("ROLE_USER")); for (int i = 0; i < roles.length; i++) { - authorities[i] = new GrantedAuthorityImpl("ROLE_" + roles[i].toUpperCase()); + authorities.add(new SimpleGrantedAuthority("ROLE_" + roles[i].toUpperCase())); } - // If user is LDAP authenticated, disable user. The proper authentication should in that case - // be done by LibresonicLdapBindAuthenticator. - boolean enabled = !user.isLdapAuthenticated(); - - return new org.acegisecurity.userdetails.User(username, user.getPassword(), enabled, true, true, true, authorities); + return new org.springframework.security.core.userdetails.User(username, user.getPassword(), authorities); } /** diff --git a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-security.xml b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-security.xml index b2af9b4b..4a9850e8 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-security.xml +++ b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-security.xml @@ -1,246 +1,65 @@ - - - - - - - - - - - - PATTERN_TYPE_APACHE_ANT - /wap**=httpSessionContextIntegrationFilter,logoutFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,basicExceptionTranslationFilter,filterInvocationInterceptor - /podcastChannel**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor - /podcast**=httpSessionContextIntegrationFilter,logoutFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,basicExceptionTranslationFilter,filterInvocationInterceptor - /rest/**=httpSessionContextIntegrationFilter,logoutFilter,basicProcessingFilter,restRequestParameterProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,basicExceptionTranslationFilter,filterInvocationInterceptor - /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PATTERN_TYPE_APACHE_ANT - - /login.view=IS_AUTHENTICATED_ANONYMOUSLY - /recover.view=IS_AUTHENTICATED_ANONYMOUSLY - /accessDenied.view=IS_AUTHENTICATED_ANONYMOUSLY - /coverArt.view=IS_AUTHENTICATED_ANONYMOUSLY - /hls/**=IS_AUTHENTICATED_ANONYMOUSLY - /stream/**=IS_AUTHENTICATED_ANONYMOUSLY - /ws/**=IS_AUTHENTICATED_ANONYMOUSLY - /share/**=IS_AUTHENTICATED_ANONYMOUSLY - /style/**=IS_AUTHENTICATED_ANONYMOUSLY - /icons/**=IS_AUTHENTICATED_ANONYMOUSLY - /flash/**=IS_AUTHENTICATED_ANONYMOUSLY - /script/**=IS_AUTHENTICATED_ANONYMOUSLY - /sonos/**=IS_AUTHENTICATED_ANONYMOUSLY - /crossdomain.xml=IS_AUTHENTICATED_ANONYMOUSLY - - /personalSettings.view=ROLE_SETTINGS - /passwordSettings.view=ROLE_SETTINGS - /playerSettings.view=ROLE_SETTINGS - /shareSettings.view=ROLE_SETTINGS - - /generalSettings.view=ROLE_ADMIN - /advancedSettings.view=ROLE_ADMIN - /userSettings.view=ROLE_ADMIN - /musicFolderSettings.view=ROLE_ADMIN - /networkSettings.view=ROLE_ADMIN - /dlnaSettings.view=ROLE_ADMIN - /sonosSettings.view=ROLE_ADMIN - /transcodingSettings.view=ROLE_ADMIN - /internetRadioSettings.view=ROLE_ADMIN - /podcastSettings.view=ROLE_ADMIN - /db.view=ROLE_ADMIN - - /deletePlaylist.view=ROLE_PLAYLIST - /savePlaylist.view=ROLE_PLAYLIST - - /download.view=ROLE_DOWNLOAD - - /upload.view=ROLE_UPLOAD - - /createShare.view=ROLE_SHARE - - /changeCoverArt.view=ROLE_COVERART - /editTags.view=ROLE_COVERART - - /setMusicFileInfo.view=ROLE_COMMENT - - /podcastReceiverAdmin.view=ROLE_PODCAST - - /**=IS_AUTHENTICATED_REMEMBERED - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.libresonic.player.ajax.TagService.setTags=ROLE_COVERART - org.libresonic.player.ajax.TransferService.getUploadInfo=ROLE_UPLOAD - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/security + http://www.springframework.org/schema/security/spring-security-3.2.xsd"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libresonic-main/src/main/webapp/WEB-INF/jsp/login.jsp b/libresonic-main/src/main/webapp/WEB-INF/jsp/login.jsp index acc6a193..6209b414 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/jsp/login.jsp +++ b/libresonic-main/src/main/webapp/WEB-INF/jsp/login.jsp @@ -12,7 +12,7 @@ -
" method="POST"> +" method="POST">
@@ -35,10 +35,6 @@ " tabindex="4"> - - - - diff --git a/libresonic-main/src/main/webapp/WEB-INF/jsp/top.jsp b/libresonic-main/src/main/webapp/WEB-INF/jsp/top.jsp index a8e1cbe3..7eeb095d 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/jsp/top.jsp +++ b/libresonic-main/src/main/webapp/WEB-INF/jsp/top.jsp @@ -138,7 +138,7 @@ diff --git a/libresonic-main/src/main/webapp/WEB-INF/web.xml b/libresonic-main/src/main/webapp/WEB-INF/web.xml index 661fffe8..5bd36336 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/web.xml +++ b/libresonic-main/src/main/webapp/WEB-INF/web.xml @@ -208,16 +208,12 @@ - AcegiFilter - org.acegisecurity.util.FilterToBeanProxy - - targetClass - org.acegisecurity.util.FilterChainProxy - + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy - AcegiFilter + springSecurityFilterChain /* diff --git a/pom.xml b/pom.xml index 5a18cf41..4391875c 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,7 @@ iso-8859-1 2.4.2 3.2.17.RELEASE + 3.2.9.RELEASE @@ -109,6 +110,22 @@ spring-web ${spring.version} + + org.springframework.security + spring-security-web + ${spring.security.version} + + + org.springframework.security + spring-security-ldap + ${spring.security.version} + + + org.springframework.security + spring-security-config + ${spring.security.version} + jar + org.springframework spring-jdbc From 92368cca8fb78cb066692bdf3e87a0186a15650a Mon Sep 17 00:00:00 2001 From: Andrew DeMaria Date: Thu, 20 Oct 2016 22:43:54 -0600 Subject: [PATCH 6/8] Fixed display of login error Signed-off-by: Andrew DeMaria --- .../src/main/webapp/WEB-INF/applicationContext-security.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-security.xml b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-security.xml index 4a9850e8..c9dc232d 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-security.xml +++ b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-security.xml @@ -56,7 +56,7 @@ - + From a03aa2805d050ef3cdc9b315adda87148daa7454 Mon Sep 17 00:00:00 2001 From: remi Date: Mon, 21 Nov 2016 23:32:43 +0100 Subject: [PATCH 7/8] New LoginController in place of the login method in MultiController. Slight introduction to Java annotation based configuration (note that has been added to libresonic-servlet.xml). --- .../player/controller/LoginController.java | 72 +++++++++++++++++++ .../player/controller/MultiController.java | 28 -------- .../webapp/WEB-INF/libresonic-servlet.xml | 16 ++++- 3 files changed, 87 insertions(+), 29 deletions(-) create mode 100644 libresonic-main/src/main/java/org/libresonic/player/controller/LoginController.java diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/LoginController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/LoginController.java new file mode 100644 index 00000000..41a9e3ea --- /dev/null +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/LoginController.java @@ -0,0 +1,72 @@ +package org.libresonic.player.controller; + +import org.libresonic.player.Logger; +import org.libresonic.player.domain.User; +import org.libresonic.player.service.PlaylistService; +import org.libresonic.player.service.SecurityService; +import org.libresonic.player.service.SettingsService; +import org.libresonic.player.util.StringUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.stereotype.Controller; +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.view.RedirectView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.HashMap; +import java.util.Map; + +/** + * Spring MVC Controller that serves the login page. + */ +@Controller +@RequestMapping("/login") +public class LoginController { + + + private static final Logger LOG = Logger.getLogger(LoginController.class); + + private final SecurityService securityService; + private final SettingsService settingsService; + private final PlaylistService playlistService; + + @Autowired + public LoginController(SecurityService securityService, SettingsService settingsService, PlaylistService playlistService) { + this.securityService = securityService; + this.settingsService = settingsService; + this.playlistService = playlistService; + } + + @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }) + public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception { + + // Auto-login if "user" and "password" parameters are given. + String username = request.getParameter("user"); + String password = request.getParameter("password"); + if (username != null && password != null) { + username = StringUtil.urlEncode(username); + password = StringUtil.urlEncode(password); + return new ModelAndView(new RedirectView("/j_spring_security_check?"+ + UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY+"=" + username + + "&"+UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_PASSWORD_KEY+"=" + password + )); + } + + Map map = new HashMap(); + map.put("logout", request.getParameter("logout") != null); + map.put("error", request.getParameter("error") != null); + map.put("brand", settingsService.getBrand()); + map.put("loginMessage", settingsService.getLoginMessage()); + + User admin = securityService.getUserByName(User.USERNAME_ADMIN); + if (User.USERNAME_ADMIN.equals(admin.getPassword())) { + map.put("insecure", true); + } + + return new ModelAndView("login", "model", map); + } + +} diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java index e37b736e..fcf98d9b 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java @@ -64,34 +64,6 @@ public class MultiController extends MultiActionController { private SettingsService settingsService; private PlaylistService playlistService; - public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception { - - // Auto-login if "user" and "password" parameters are given. - String username = request.getParameter("user"); - String password = request.getParameter("password"); - if (username != null && password != null) { - username = StringUtil.urlEncode(username); - password = StringUtil.urlEncode(password); - return new ModelAndView(new RedirectView("/j_spring_security_check?"+ - UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY+"=" + username + - "&"+UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_PASSWORD_KEY+"=" + password - )); - } - - Map map = new HashMap(); - map.put("logout", request.getParameter("logout") != null); - map.put("error", request.getParameter("error") != null); - map.put("brand", settingsService.getBrand()); - map.put("loginMessage", settingsService.getLoginMessage()); - - User admin = securityService.getUserByName(User.USERNAME_ADMIN); - if (User.USERNAME_ADMIN.equals(admin.getPassword())) { - map.put("insecure", true); - } - - return new ModelAndView("login", "model", map); - } - public ModelAndView recover(HttpServletRequest request, HttpServletResponse response) throws Exception { Map map = new HashMap(); diff --git a/libresonic-main/src/main/webapp/WEB-INF/libresonic-servlet.xml b/libresonic-main/src/main/webapp/WEB-INF/libresonic-servlet.xml index 52b0f556..5933acd7 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/libresonic-servlet.xml +++ b/libresonic-main/src/main/webapp/WEB-INF/libresonic-servlet.xml @@ -2,7 +2,18 @@ + xmlns:context="http://www.springframework.org/schema/context" + xmlns:mvc="http://www.springframework.org/schema/mvc" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context.xsd + http://www.springframework.org/schema/mvc + http://www.springframework.org/schema/mvc/spring-mvc.xsd"> + + + @@ -434,7 +445,10 @@ topController randomPlayQueueController changeCoverArtController + multiController multiController multiController From 520008bb609abfbde14ce869314b0ed519ec9687 Mon Sep 17 00:00:00 2001 From: remi Date: Tue, 22 Nov 2016 22:09:16 +0100 Subject: [PATCH 8/8] No need for a constructor in the LoginController. Just need to @Autowire each property. --- .../player/controller/LoginController.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/LoginController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/LoginController.java index 41a9e3ea..dfdb5f1d 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/controller/LoginController.java +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/LoginController.java @@ -29,16 +29,10 @@ public class LoginController { private static final Logger LOG = Logger.getLogger(LoginController.class); - private final SecurityService securityService; - private final SettingsService settingsService; - private final PlaylistService playlistService; - @Autowired - public LoginController(SecurityService securityService, SettingsService settingsService, PlaylistService playlistService) { - this.securityService = securityService; - this.settingsService = settingsService; - this.playlistService = playlistService; - } + private final SecurityService securityService = null; + @Autowired + private final SettingsService settingsService = null; @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }) public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception {