/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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 Lesser General Public License for more details.
*
* Copyright 2007 - 2009 Pentaho Corporation. All rights reserved.
*
*/
package org.pentaho.platform.plugin.services.security.userrole.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import javax.sql.DataSource;
import org.pentaho.platform.api.engine.IUserRoleListService;
import org.springframework.context.ApplicationContextException;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
public class JdbcUserRoleListService extends JdbcDaoSupport implements IUserRoleListService {
// ~ Static fields/initializers
// =============================================
public static final String DEF_ALL_AUTHORITIES_QUERY = "SELECT distinct(authority) as authority FROM authorities"; //$NON-NLS-1$
public static final String DEF_ALL_USERNAMES_QUERY = "SELECT distinct(username) as username FROM users"; //$NON-NLS-1$
public static final String DEF_ALL_USERNAMES_IN_ROLE_QUERY = "SELECT distinct(username) as username FROM authorities where authority = ?"; //$NON-NLS-1$
// ~ Instance fields
// ========================================================
protected MappingSqlQuery allAuthoritiesMapping;
protected MappingSqlQuery allUsernamesMapping;
protected MappingSqlQuery allUsernamesInRoleMapping;
private String allAuthoritiesQuery;
private String allUsernamesQuery;
private String allUsernamesInRoleQuery;
private UserDetailsService userDetailsService;
private String rolePrefix;
// ~ Constructors
// ===========================================================
public JdbcUserRoleListService(final UserDetailsService userDetailsService) {
allAuthoritiesQuery = JdbcUserRoleListService.DEF_ALL_AUTHORITIES_QUERY;
allUsernamesQuery = JdbcUserRoleListService.DEF_ALL_USERNAMES_QUERY;
allUsernamesInRoleQuery = JdbcUserRoleListService.DEF_ALL_USERNAMES_IN_ROLE_QUERY;
this.userDetailsService = userDetailsService;
}
// ~ Methods
// ================================================================
/**
* Allows the default query string used to retrieve all authorities to be
* overriden, if default table or column names need to be changed. The
* default query is {@link #DEF_ALL_AUTHORITIES_QUERY}; when modifying this
* query, ensure that all returned columns are mapped back to the same
* column names as in the default query.
*
* @param queryString
* The query string to set
*/
public void setAllAuthoritiesQuery(final String queryString) {
allAuthoritiesQuery = queryString;
}
public String getAllAuthoritiesQuery() {
return allAuthoritiesQuery;
}
/**
* Allows the default query string used to retrieve all user names in a role
* to be overriden, if default table or column names need to be changed. The
* default query is {@link #DEF_ALL_USERS_QUERY}; when modifying this
* query, ensure that all returned columns are mapped back to the same
* column names as in the default query.
*
* @param queryString
* The query string to set
*/
public void setAllUsernamesInRoleQuery(final String queryString) {
allUsernamesInRoleQuery = queryString;
}
public String getAllUsernamesInRoleQuery() {
return allUsernamesInRoleQuery;
}
/**
* Allows the default query string used to retrieve all user names to be
* overriden, if default table or column names need to be changed. The
* default query is {@link #DEF_ALL_USERS_IN_ROLE_QUERY}; when modifying
* this query, ensure that all returned columns are mapped back to the same
* column names as in the default query.
*
* @param queryString
* The query string to set
*/
public void setAllUsernamesQuery(final String queryString) {
allUsernamesQuery = queryString;
}
public String getAllUsernamesQuery() {
return allUsernamesQuery;
}
public GrantedAuthority[] getAllAuthorities() throws DataAccessException {
List allAuths = allAuthoritiesMapping.execute();
if (allAuths.size() == 0) {
GrantedAuthority[] rtn = {};
return rtn;
}
GrantedAuthority[] arrayAuths = {};
return (GrantedAuthority[]) allAuths.toArray(arrayAuths);
}
public String[] getAllUsernames() throws DataAccessException {
List allUserNames = allUsernamesMapping.execute();
if (allUserNames.size() == 0) {
String[] rtn = {};
return rtn;
}
String[] arrayUserNames = {};
return (String[]) allUserNames.toArray(arrayUserNames);
}
public String[] getUsernamesInRole(final GrantedAuthority authority) {
List allUserNames = allUsernamesInRoleMapping.execute(authority.getAuthority());
if (allUserNames.size() == 0) {
String[] rtn = {};
return rtn;
}
String[] arrayUserNames = {};
return (String[]) allUserNames.toArray(arrayUserNames);
}
@Override
protected void initDao() throws ApplicationContextException {
initMappingSqlQueries();
}
/**
* Extension point to allow other MappingSqlQuery objects to be substituted
* in a subclass
*/
protected void initMappingSqlQueries() {
this.allAuthoritiesMapping = new AllAuthoritiesMapping(getDataSource());
this.allUsernamesInRoleMapping = new AllUserNamesInRoleMapping(getDataSource());
this.allUsernamesMapping = new AllUserNamesMapping(getDataSource());
}
// ~ Inner Classes
// ==========================================================
/**
* Query object to look up all users.
*/
protected class AllUserNamesMapping extends MappingSqlQuery {
protected AllUserNamesMapping(final DataSource ds) {
super(ds, allUsernamesQuery);
compile();
}
@Override
protected Object mapRow(final ResultSet rs, final int rownum) throws SQLException {
return rs.getString(1);
}
}
/**
* Query object to look up users in a role.
*/
protected class AllUserNamesInRoleMapping extends MappingSqlQuery {
protected AllUserNamesInRoleMapping(final DataSource ds) {
super(ds, allUsernamesInRoleQuery);
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
@Override
protected Object mapRow(final ResultSet rs, final int rownum) throws SQLException {
return rs.getString(1);
}
}
/**
* Query object to look up all authorities.
*/
protected class AllAuthoritiesMapping extends MappingSqlQuery {
protected AllAuthoritiesMapping(final DataSource ds) {
super(ds, allAuthoritiesQuery);
compile();
}
@Override
protected Object mapRow(final ResultSet rs, final int rownum) throws SQLException {
return new GrantedAuthorityImpl(((null != rolePrefix) ? rolePrefix : "") + rs.getString(1)); //$NON-NLS-1$
}
}
public GrantedAuthority[] getAuthoritiesForUser(final String userName) throws UsernameNotFoundException,
DataAccessException {
UserDetails user = userDetailsService.loadUserByUsername(userName);
return user.getAuthorities();
}
public void setRolePrefix(final String rolePrefix) {
this.rolePrefix = rolePrefix;
}
public void setUserDetailsService(final UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
}