Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions solutions.digamma.damas.api/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@
exports solutions.digamma.damas.search;
exports solutions.digamma.damas.common;
exports solutions.digamma.damas.user;
exports solutions.digamma.damas.login;
exports solutions.digamma.damas.session;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package solutions.digamma.damas.session;

import solutions.digamma.damas.common.WorkspaceException;

/**
* A connection is a set of operations that are executed with the same user
* session. A part from login, a valid connection is required for all workspace
* operations.
*
* To create a connection, a valid used token is required, thus a valid login.
* An instance of this class can only be obtained by calling the method {@code
* connect} of a {@link ConnectionManager}.
*
* Once a connection is created, workspace methods called in the same thread
* are done in behalf of the user session that created the connection, until the
* connection is closed or another connection is created.
*
* Connections are closable. The user is encourage to close the connection as
* soon as possible to avoid security breaches. The best way to use connections
* is as a resource in a try-with-resource structure.
*
* A valid token (thus a valid user session) can be used to create as many
* connections as needed, as long as those connections are property closed.
*
* A connection can be committed or rolled back as many times as needed.
*/
public interface Connection extends AutoCloseable {

/**
* Commit connection, persisting all changed in the user session.
*
* @throws WorkspaceException when a workspace exception occurs
*/
void commit() throws WorkspaceException;

/**
* Rollback connection, resetting session data to the persisted state.
*
* @throws WorkspaceException when a workspace exception occurs
*/
void rollback() throws WorkspaceException;

/**
* Close connection.
*
* @throws WorkspaceException when a workspace exception occurs
*/
void close() throws WorkspaceException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package solutions.digamma.damas.session;

import solutions.digamma.damas.common.WorkspaceException;

/**
* Connection manager.
*
* A service class used to create a new connection.
*/
public interface ConnectionManager {

/**
* Initiate a new connection.
*
* This method is the only way to acquire a new valid workspace connection.
*
* To create a new connection a valid (authenticated) token is required.
*
* @param token authentication token
* @return workspace connection
* @throws WorkspaceException when a workspace exception occurs
*/
Connection connect(Token token) throws WorkspaceException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package solutions.digamma.damas.session;

import solutions.digamma.damas.common.WorkspaceException;

/**
* Username/password login manager.
*
* @author Ahmad Shahwan
*/
public interface LoginManager {

/**
* Check user credentials and grant them a user session if credentials are
* valid. If credential are not usable, throw exception.
*
* @param username username
* @param password password
* @return a token representing user session
* @throws WorkspaceException when credential are not valid, or another
* error occurres
*/
UserToken login(String username, String password) throws WorkspaceException;

UserSession identify(Token token) throws WorkspaceException;

/**
* Log out previously logged user, using their token.
*
* @param token user token
* @throws WorkspaceException if an error occurres
*/
void logout(Token token) throws WorkspaceException;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package solutions.digamma.damas.login;
package solutions.digamma.damas.session;

/**
* User session token.
* User token holding session secret.
*
* @author Ahmad Shahwan
*/
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package solutions.digamma.damas.session;

import java.util.Date;

/**
* Information about current used session.
*
* An object of this type is returned when the who-am-I API is queried.
*/
public interface UserSession {

String getUserLogin();

Date getCreationDate();

Date getExpirationDate();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package solutions.digamma.damas.session;

/**
* A used session information along side a session token.
*
* An object of this type is returned upon successful authentication. Both
* session information and token are usually needed for actions following once
* user is logged in.
*/
public interface UserToken extends UserSession, Token {
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package solutions.digamma.damas.auth;

import java.util.HashSet;
import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
Expand All @@ -24,6 +26,7 @@ public abstract class AbstractLoginModule implements LoginModule {
protected String login;
protected char[] password;
protected List<Principal> roles;
protected Set<Object> credentials;
private Subject subject;
private boolean success;

Expand All @@ -44,6 +47,7 @@ public void initialize(
this.sharedState = sharedState;
this.extractCredentials();
this.roles = new ArrayList<>();
this.credentials = new HashSet<>();
}

@Override
Expand All @@ -59,6 +63,7 @@ public boolean commit() throws LoginException {
Principal principal = () -> this.login;
this.subject.getPrincipals().add(principal);
this.subject.getPrincipals().addAll(this.roles);
this.subject.getPublicCredentials().addAll(this.credentials);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<beans xmlns="http://java.sun.com/xml/ns/javaee"></beans>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<beans xmlns="http://java.sun.com/xml/ns/javaee"></beans>
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package solutions.digamma.damas.jcr.login


import solutions.digamma.damas.login.LoginManager
import solutions.digamma.damas.login.Token
import solutions.digamma.damas.common.NotFoundException
import solutions.digamma.damas.session.LoginManager
import solutions.digamma.damas.session.Token
import solutions.digamma.damas.common.WorkspaceException
import solutions.digamma.damas.jcr.common.Exceptions
import solutions.digamma.damas.jcr.session.SecureToken
import solutions.digamma.damas.jcr.session.SessionBookkeeper
import solutions.digamma.damas.jcr.session.TransactionalSession
import solutions.digamma.damas.logging.Logged
import solutions.digamma.damas.session.UserSession
import solutions.digamma.damas.session.UserToken
import java.util.logging.Logger
import javax.inject.Inject
import javax.inject.Singleton
Expand Down Expand Up @@ -41,13 +44,16 @@ internal open class JcrLoginManager : LoginManager {
username, password.toCharArray())
val jcrSession = this.repository.login(credentials)
this.logger.info("Login successful.")
val token = SecureToken()
val session = TransactionalSession(jcrSession)
val token = SecureToken(username)
val session = TransactionalSession(jcrSession, username)
this.bookkeeper.register(token, session)
this.logger.info("Session registered.")
token
}

@Throws(NotFoundException::class)
override fun identify(token: Token) = this.bookkeeper.lookup(token)

@Logged
@Throws(WorkspaceException::class)
override fun logout(token: Token) = this.bookkeeper.unregister(token)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import solutions.digamma.damas.jcr.user.JcrUser
import java.security.Principal
import java.util.Arrays
import javax.jcr.PathNotFoundException
import javax.jcr.SimpleCredentials
import javax.security.auth.login.AccountLockedException
import javax.security.auth.login.AccountNotFoundException
import javax.security.auth.login.CredentialNotFoundException
Expand Down Expand Up @@ -46,6 +47,7 @@ internal open class UserLoginModule : AbstractLoginModule() {
throw FailedLoginException("Invalid password")
this.roles.addAll(user.memberships.map { Principal { it } })
this.roles.add(SystemRole.READWRITE)
this.credentials.add(SimpleCredentials(this.login, CharArray(0)))
return true
} catch (e: WorkspaceException) {
throw LoginException("Authentication error")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package solutions.digamma.damas.jcr.model

import solutions.digamma.damas.common.AuthenticationException
import solutions.digamma.damas.common.NotFoundException
import solutions.digamma.damas.jcr.session.JcrTransaction
import solutions.digamma.damas.jcr.session.JcrConnection
import solutions.digamma.damas.jcr.session.JcrSessionConsumer
import solutions.digamma.damas.logging.Logged
import java.util.logging.Logger
Expand All @@ -23,7 +23,7 @@ internal abstract class JcrManager : JcrSessionConsumer {
@Logged
@Throws(AuthenticationException::class)
get() = try {
JcrTransaction.get().getSession()
JcrConnection.get().getSession()
} catch (e: NotFoundException) {
throw AuthenticationException(e)
}
Expand Down
Loading