/*
* Created on Jun 25, 2005
*
* Copyright 2005 CafeSip.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.cafesip.jiplet.realms;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import org.cafesip.jiplet.JipletException;
import org.cafesip.jiplet.JipletLogger;
import org.cafesip.jiplet.Pair;
import org.cafesip.jiplet.Realm;
import org.cafesip.jiplet.realms.memory.users.MemoryRealmUsers;
import org.cafesip.jiplet.realms.memory.users.Role;
import org.cafesip.jiplet.realms.memory.users.User;
/**
* @author Amit Chatterjee
*
*/
public class MemoryRealm extends BaseRealm implements Realm
{
private MemoryRealmUsers config;
private String fileName = "jiplet-users.xml";
// user database, key = user name value = Pair(password, roles)
private HashMap users = new HashMap();
private ArrayList allRoles = new ArrayList();
private long lastRead;
private File file;
/**
* A constructor for this class.
*
*
*/
public MemoryRealm()
{
super();
}
/*
* @see org.cafesip.jiplet.Realm#init(java.lang.String, java.io.File,
* java.util.HashMap, boolean)
*/
public void init(String name, File confDir, HashMap params, boolean defaultRealm)
throws JipletException
{
super.init(name, confDir, params, defaultRealm);
try
{
String param = (String)params.get("user-db-file");
if (param != null)
{
fileName = param;
}
file = new File(getConfDir(), fileName);
initUsers();
}
catch (Exception e)
{
throw new JipletException(e);
}
}
private void initUsers() throws JAXBException, IOException
{
users.clear();
allRoles.clear();
FileInputStream istream = new FileInputStream(file);
config = (MemoryRealmUsers) JAXBContext.newInstance(
"org.cafesip.jiplet.realms.memory.users",
this.getClass().getClassLoader()).createUnmarshaller()
.unmarshal(istream);
istream.close();
// next initialize the tables
Iterator iter = config.getRole().iterator();
while (iter.hasNext() == true)
{
Role role = (Role)iter.next();
allRoles.add(role.getRolename());
}
iter = config.getUser().iterator();
next:
while (iter.hasNext() == true)
{
User user = (User)iter.next();
String name = user.getUsername();
String password = user.getPassword();
String roles = user.getRoles().trim();
StringTokenizer tokens = new StringTokenizer(roles, ",");
int num = tokens.countTokens();
String[] r = new String[num];
for (int i = 0; i < num; i++)
{
r[i] = tokens.nextToken().trim();
if (findRole(r[i]) == false)
{
JipletLogger.warn("Role " + r[i] + " configured for user " + name + " is not a valid."
+ " The user will not be added.");
continue next;
}
}
synchronized (users)
{
users.put(name, new Pair(password, r));
}
}
lastRead = System.currentTimeMillis();
}
private boolean findRole(String role)
{
Iterator iter = allRoles.iterator();
while (iter.hasNext() == true)
{
String r = (String)iter.next();
if (r.equals(role) == true)
{
return true;
}
}
return false;
}
/*
* @see org.cafesip.jiplet.Realm#destroy()
*/
public void destroy()
{
}
/*
* @see org.cafesip.jiplet.Realm#addUser(java.lang.String, java.lang.String,
* java.lang.String[])
*/
public boolean addUser(String user, String password, String[] roles)
throws UnsupportedOperationException
{
throw new UnsupportedOperationException("This feature is not yet implemented");
}
/*
* @see org.cafesip.jiplet.Realm#modifyUser(java.lang.String,
* java.lang.String, java.lang.String[])
*/
public boolean modifyUser(String user, String password, String[] roles)
throws UnsupportedOperationException
{
throw new UnsupportedOperationException("This feature is not yet implemented");
}
/*
* @see org.cafesip.jiplet.Realm#deleteUser(java.lang.String)
*/
public boolean deleteUser(String user) throws UnsupportedOperationException
{
throw new UnsupportedOperationException("This feature is not yet implemented");
}
/*
* @see org.cafesip.jiplet.Realm#getRoles(java.lang.String)
*/
public String[] getRoles(String user)
{
Pair p = (Pair)users.get(user);
if (p == null)
{
return null;
}
return (String[])p.getSecond();
}
/*
* @see org.cafesip.jiplet.Realm#supportsProvisioning()
*/
public boolean supportsProvisioning()
{
return false;
}
/*
* @see org.cafesip.jiplet.realms.BaseRealm#getUserInformation(java.lang.String)
*/
public Pair getUserInformation(String user)
{
synchronized(users)
{
long modified = file.lastModified();
if (modified > lastRead)
{
if (JipletLogger.isDebugEnabled() == true)
{
JipletLogger.debug("The memory realm file has been modified. Re-reading it."
+ " The file was last modified on " + new Date(file.lastModified())
+ " and the file was last read on " + new Date(lastRead));
}
try
{
initUsers();
}
catch (Exception e)
{
JipletLogger.error("While reading the memory realm file, an error occured. The realm may be in a hosed up state: "
+ e.getClass().getName() + ":" + e.getMessage());
return null;
}
}
return (Pair)users.get(user);
}
}
}