/*
* SessionContainer.java
*
* Created on June 30, 2007, 4:10 AM
*
* CodaServer and related original technologies are copyright 2008, 18th Street Software, LLC.
*
* Permission to use them is granted under the terms of the GNU GPLv2.
*/
package org.codalang.codaserver;
import org.codalang.codaserver.database.CodaConnection;
import org.codalang.codaserver.database.CodaDatabase;
import org.codalang.codaserver.database.CodaResultSet;
import org.codalang.codaserver.security.SecurityGroup;
import org.codalang.codaserver.security.SecuritySystemUser;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Random;
/**
*
* @author michaelarace
*/
public class SessionContainer {
Hashtable<String,SecuritySystemUser> sessions = new Hashtable();
boolean useCacheFlag = false;
CodaDatabase database;
/** Creates a new instance of SessionContainer */
public SessionContainer(CodaDatabase database, boolean useCacheFlag) {
this.useCacheFlag = useCacheFlag;
this.database = database;
loadSessions();
}
public boolean touchSession(String sessionKey) {
GregorianCalendar cal = new GregorianCalendar();
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select id from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey), null);
if (!rs.getErrorStatus() && rs.next()) {
Hashtable values = new Hashtable();
values.put("session_timestamp", new GregorianCalendar().getTimeInMillis());
connection.updateRow("sessions", "id", rs.getDataLong(0), values);
connection.commit();
return true;
} else {
return false;
}
}
public void put(String sessionKey, SecuritySystemUser user) {
CodaConnection connection = database.getConnection();
Hashtable values = new Hashtable();
values.put("session_key", sessionKey);
values.put("session_timestamp", new GregorianCalendar().getTimeInMillis());
values.put("user_id", user.getUserId());
values.put("user_name", user.getUsername());
connection.insertRow("sessions", values);
connection.commit();
if (useCacheFlag) {
sessions.put(sessionKey, user);
}
}
public void remove(String sessionKey) {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select id from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey), null);
if (!rs.getErrorStatus() && rs.next()) {
connection.deleteRow("sessions", "id", rs.getDataLong(0));
connection.commit();
}
if (useCacheFlag) {
sessions.remove(sessionKey);
}
}
public long getSessionUserId(String sessionKey) {
if (useCacheFlag) {
return ((SecuritySystemUser)sessions.get(sessionKey)).getUserId();
} else {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select id from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey), null);
if (!rs.getErrorStatus() && rs.next()) {
return rs.getDataLong(0);
} else {
return -1;
}
}
}
public boolean setSessionApplication(String sessionKey, long applicationId, String applicationName, int environment) {
CodaConnection connection = database.getConnection();
String environmentString;
switch (environment) {
case 2:
environmentString = "TEST";
break;
case 3:
environmentString = "PROD";
break;
default:
environmentString = "DEV";
}
CodaResultSet rs = connection.runQuery("select id from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey), null);
if (!rs.getErrorStatus() && rs.next()) {
Hashtable values = new Hashtable();
values.put("application_id", applicationId);
values.put("application_name", applicationName.toUpperCase());
values.put("environment_id", environment);
values.put("environment", environmentString);
connection.updateRow("sessions", "id", rs.getDataLong(0), values);
connection.commit();
if (useCacheFlag) {
if (sessions.containsKey(sessionKey)) {
((SecuritySystemUser)sessions.get(sessionKey)).setCurrentEnvironment(environmentString);
((SecuritySystemUser)sessions.get(sessionKey)).setCurrentEnvironmentId(environment);
((SecuritySystemUser)sessions.get(sessionKey)).setCurrentApplication(applicationName.toUpperCase());
((SecuritySystemUser)sessions.get(sessionKey)).setCurrentApplicationId(applicationId);
} else {
loadSession(sessionKey);
}
}
} else {
if (useCacheFlag) {
sessions.remove(sessionKey);
}
}
return false;
}
public String getSessionApplication(String sessionKey) {
if (useCacheFlag && sessions.containsKey(sessionKey)) {
return sessions.get(sessionKey).getCurrentApplication();
} else {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select application_name from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey),null);
if (!rs.getErrorStatus() && rs.next()) {
return rs.getData(0);
}
}
return null;
}
public long getSessionApplicationId(String sessionKey) {
if (useCacheFlag && sessions.containsKey(sessionKey)) {
return sessions.get(sessionKey).getCurrentApplicationId();
} else {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select application_id from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey),null);
if (!rs.getErrorStatus() && rs.next()) {
return rs.getDataLong(0);
}
}
return -1;
}
public String getSessionEnvironment(String sessionKey) {
if (useCacheFlag && sessions.containsKey(sessionKey)) {
return sessions.get(sessionKey).getCurrentEnvironment();
} else {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select environment from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey),null);
if (!rs.getErrorStatus() && rs.next()) {
return rs.getData(0);
}
}
return null;
}
public int getSessionEnvironmentId(String sessionKey) {
if (useCacheFlag && sessions.containsKey(sessionKey)) {
return sessions.get(sessionKey).getCurrentEnvironmentId();
} else {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select environment_id from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey),null);
if (!rs.getErrorStatus() && rs.next()) {
return rs.getDataInt(0);
}
}
return -1;
}
public boolean setSessionGroup(String sessionKey, long groupId, String groupName) {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select id from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey), null);
if (!rs.getErrorStatus() && rs.next()) {
Hashtable values = new Hashtable();
values.put("group_id", groupId);
values.put("group_name", groupName.toUpperCase());
connection.updateRow("sessions", "id", rs.getDataLong(0), values);
connection.commit();
if (useCacheFlag) {
if (sessions.containsKey(sessionKey)) {
((SecuritySystemUser)sessions.get(sessionKey)).setCurrentGroup(groupName.toUpperCase());
} else {
loadSession(sessionKey);
}
}
} else {
if (useCacheFlag) {
sessions.remove(sessionKey);
}
}
return false;
}
public String getSessionGroup(String sessionKey) {
if (useCacheFlag && sessions.containsKey(sessionKey)) {
return sessions.get(sessionKey).getCurrentGroup();
} else {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select group_name from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey),null);
if (!rs.getErrorStatus() && rs.next()) {
return rs.getData(0);
}
}
return null;
}
public long getSessionGroupId(String sessionKey) {
if (useCacheFlag && sessions.containsKey(sessionKey)) {
return sessions.get(sessionKey).getCurrentGroupId();
} else {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select group_id from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey),null);
if (!rs.getErrorStatus() && rs.next()) {
return rs.getDataLong(0);
}
}
return -1;
}
public String getSessionUsername(String sessionKey) {
if (useCacheFlag && sessions.containsKey(sessionKey)) {
return sessions.get(sessionKey).getUsername();
} else {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select user_name from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey),null);
if (!rs.getErrorStatus() && rs.next()) {
return rs.getData(0);
}
}
return "";
}
public void loadSession(String sessionKey) {
this.useCacheFlag = false;
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select user_id, group_name, application_name, environment, group_id, application_id, environment_id, user_name from sessions where session_key = " + connection.formatStringForSQL("sessions", "session_key", sessionKey), null);
if (!rs.getErrorStatus() && rs.next()) {
SecuritySystemUser user = getSecuritySystemUser(rs.getDataLong(0));
user.setUsername(rs.getData(7));
user.setCurrentApplication((rs.getData(2) == null ? null : rs.getData(2).toUpperCase()));
user.setCurrentEnvironment((rs.getData(3) == null ? null : rs.getData(3).toUpperCase()));
user.setCurrentGroup((rs.getData(1) == null ? null : rs.getData(1).toUpperCase()));
user.setCurrentGroupId((rs.getData(4) == null ? -1 : rs.getDataLong(4)));
user.setCurrentApplicationId((rs.getData(5) == null ? -1 : rs.getDataLong(5)));
user.setCurrentEnvironmentId((rs.getData(6) == null ? -1 : rs.getDataInt(6)));
sessions.put(sessionKey, user);
} else {
this.remove(sessionKey);
}
this.useCacheFlag = true;
}
private void loadSessions() {
if (useCacheFlag) {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select user_id, group_name, application_name, environment, group_id, application_id, environment_id, user_name, session_key from sessions", null);
if (!rs.getErrorStatus()) {
while (rs.next()) {
SecuritySystemUser user = getSecuritySystemUser(rs.getDataLong(0));
user.setUsername(rs.getData(7));
user.setCurrentApplication((rs.getData(2) == null ? null : rs.getData(2).toUpperCase()));
user.setCurrentEnvironment((rs.getData(3) == null ? null : rs.getData(3).toUpperCase()));
user.setCurrentGroup((rs.getData(1) == null ? null : rs.getData(1).toUpperCase()));
user.setCurrentGroupId((rs.getData(4) == null ? -1 : rs.getDataLong(4)));
user.setCurrentApplicationId((rs.getData(5) == null ? -1 : rs.getDataLong(5)));
user.setCurrentEnvironmentId((rs.getData(6) == null ? -1 : rs.getDataInt(6)));
sessions.put(rs.getData(8), user);
}
}
}
}
private SecuritySystemUser getSecuritySystemUser(long userId) {
CodaConnection connection = database.getConnection();
CodaResultSet rs = connection.runQuery("select u.server_permission_name from user_server_permissions u where u.user_id = " + connection.formatStringForSQL("user_server_permissions", "user_id", Long.toString(userId)), null);
HashSet serverPermissions = new HashSet();
while (rs.next()) {
serverPermissions.add(rs.getData(0));
}
rs = connection.runQuery("select g.id, g.group_name, g.display_name from user_groups u inner join groups g on g.id = u.group_id where u.user_id = " + connection.formatStringForSQL("user_server_permissions", "user_id", Long.toString(userId)), null);
Hashtable groups = new Hashtable();
while (rs.next()) {
groups.put(rs.getData(1), new SecurityGroup(rs.getDataLong(0), rs.getData(1), rs.getData(2)));
}
rs = connection.runQuery("select user_name from users where id = " + connection.formatStringForSQL("users", "id", Long.toString(userId)), null);
String username = "";
while (rs.next()) {
username = rs.getData(0);
}
return new SecuritySystemUser(userId, username, serverPermissions, groups);
}
public String createSession (long userId) {
CodaConnection connection = database.getConnection();
boolean uniqueKey = false;
String sessionKey = "";
while (!uniqueKey) {
sessionKey = this.getRandomString(32);
CodaResultSet rs1 = connection.runQuery("select id from sessions where session_key = "+ connection.formatStringForSQL("sessions", "session_key", sessionKey), null);
uniqueKey = (rs1.getRowsReturned() == 0);
}
this.put(sessionKey, getSecuritySystemUser(userId));
return sessionKey;
}
public boolean isUserInGroup(String sessionKey, String groupName) {
if (useCacheFlag) {
if (sessions.containsKey(sessionKey)) {
return ((SecuritySystemUser)sessions.get(sessionKey)).isInGroup(groupName);
}
} else {
CodaConnection connection = database.getConnection();
long userId = this.getSessionUserId(sessionKey);
if (userId > 0) {
CodaResultSet rs = connection.runQuery("select count(ug.*) from user_groups ug inner join groups g on g.id = ug.group_id where g.id = " + connection.formatStringForSQL("groups", "group_name", groupName.toUpperCase()) + " and ug.user_id = " + connection.formatStringForSQL("user_groups", "user_id", Long.toString(userId)), null);
if (!rs.getErrorStatus() && rs.next()) {
if (rs.getDataLong(0) > 0) {
return true;
}
}
}
}
return false;
}
public boolean hasServerPermission(String sessionKey, String permissionName) {
if (useCacheFlag) {
if (sessions.containsKey(sessionKey)) {
return ((SecuritySystemUser)sessions.get(sessionKey)).hasServerPermission(permissionName);
}
} else {
CodaConnection connection = database.getConnection();
long userId = this.getSessionUserId(sessionKey);
if (userId > 0) {
CodaResultSet rs = connection.runQuery("select count(*) from user_server_permissions where user_id = " + connection.formatStringForSQL("user_server_permissions", "user_id", Long.toString(userId)) + " and server_permission_name = " + connection.formatStringForSQL("user_server_permissions", "server_permission_name", permissionName.toUpperCase()), null);
if (!rs.getErrorStatus() && rs.next()) {
return rs.getDataInt(0) == 1;
}
}
}
return false;
}
public static String getRandomString(int chars) {
String charSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random r = new Random();
String retval = "";
for (int i = 0; i < chars; i++) {
int rand = r.nextInt(62);
retval += charSet.substring(rand, rand +1);
}
return retval;
}
}