Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/use authz #143

Closed
wants to merge 6 commits into from
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.MapType;
import edu.harvard.hms.dbmi.avillach.auth.data.entity.Connection;
import edu.harvard.hms.dbmi.avillach.auth.data.entity.Privilege;
import edu.harvard.hms.dbmi.avillach.auth.data.entity.Role;
Expand All @@ -11,7 +10,6 @@
import edu.harvard.hms.dbmi.avillach.auth.data.repository.RoleRepository;
import edu.harvard.hms.dbmi.avillach.auth.rest.TokenService;
import io.swagger.jaxrs.config.BeanConfig;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
Expand All @@ -28,13 +26,10 @@
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.SecurityContext;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import javax.net.ssl.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static edu.harvard.hms.dbmi.avillach.auth.utils.AuthNaming.AuthRoleNaming.ADMIN;
import static edu.harvard.hms.dbmi.avillach.auth.utils.AuthNaming.AuthRoleNaming.SUPER_ADMIN;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,152 +13,194 @@
import javax.persistence.NonUniqueResultException;
import javax.persistence.criteria.*;
import javax.transaction.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;

/**
* <p>Provides operations for the User entity to interact with a database.</p>
*
* @see User
*/
@Transactional
@ApplicationScoped
public class UserRepository extends BaseRepository<User, UUID> {

private Logger logger = LoggerFactory.getLogger(UserRepository.class);

protected UserRepository() {
super(User.class);
}

public User findBySubject(String subject) {
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();
return em.createQuery(query
.where(
eq(cb, queryRoot, "subject", subject)))
.getSingleResult();
}

public User findBySubjectAndConnection(String subject, String connectionId){
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();
try {
private Logger logger = LoggerFactory.getLogger(UserRepository.class);

protected UserRepository() {
super(User.class);
}

public User findBySubject(String subject) {
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();
return em.createQuery(query
.where(
eq(cb, queryRoot, "subject", subject)))
.getSingleResult();
}

public User findBySubjectAndConnection(String subject, String connectionId) {
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();
try {
return em.createQuery(query
.where(
cb.and(
cb.equal(queryRoot.join("connection")
.get("id"), connectionId),
eq(cb, queryRoot, "subject", subject))))
.where(
cb.and(
cb.equal(queryRoot.join("connection")
.get("id"), connectionId),
eq(cb, queryRoot, "subject", subject))))
.getSingleResult();
} catch (NoResultException e){
return null;
} catch (NoResultException e) {
return null;
}
}

public List<User> listUnmatchedByConnectionId(Connection connection) {
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();
return em.createQuery(query
.where(
cb.and(
eq(cb, queryRoot, "connection", connection),
eq(cb, queryRoot, "matched", false))))
.getResultList();
}

/**
* @return
*/
public User findOrCreate(User inputUser) {
User user = null;
String subject = inputUser.getSubject();
try {
user = findBySubject(subject);
logger.info("findOrCreate(), trying to find user: {subject: " + subject +
"}, and found a user with uuid: " + user.getUuid()
+ ", subject: " + user.getSubject());
} catch (NoResultException e) {
logger.debug("findOrCreate() subject " + subject +
" could not be found by `entityManager`, going to create a new user.");
user = createUser(inputUser);
} catch (NonUniqueResultException e) {
logger.error("findOrCreate() " + e.getClass().getSimpleName() + ": " + e.getMessage());
}
return user;
}

private User createUser(User inputUser) {
String subject = inputUser.getSubject();
logger.debug("createUser() creating user, subject: " + subject + " ......");
em().persist(inputUser);

User result = getById(inputUser.getUuid());
if (result != null)
logger.info("createUser() created user, uuid: " + result.getUuid()
+ ", subject: " + subject
+ ", role: " + result.getRoleString()
+ ", privilege: " + result.getPrivilegeString());

return result;
}

public User changeRole(User user, Set<Role> roles) {
logger.info("Starting changing the role of user: " + user.getUuid()
+ ", with subject: " + user.getSubject() + ", to " + roles.stream().map(role -> role.getName()).collect(Collectors.joining(",")));
user.setRoles(roles);
em().merge(user);
User updatedUser = getById(user.getUuid());
logger.info("User: " + updatedUser.getUuid() + ", with subject: " +
updatedUser.getSubject() + ", now has a new role: " + updatedUser.getRoleString());
return updatedUser;
}

@Override
public void persist(User user) {
findOrCreate(user);
}

public User findByEmail(String email) {
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();
return em.createQuery(query
.where(
eq(cb, queryRoot, "email", email)))
.getSingleResult();
}

public boolean checkAgainstTOSDate(String userId) {
CriteriaQuery<User> query = cb().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();

Subquery<Date> subquery = query.subquery(Date.class);
Root<TermsOfService> tosRoot = subquery.from(TermsOfService.class);
subquery.select(cb.greatest(tosRoot.<Date>get("dateUpdated")));

return !em.createQuery(query
.where(
cb.and(
eq(cb, queryRoot, "subject", userId),
cb.greaterThanOrEqualTo(queryRoot.get("acceptedTOS"), subquery))))
.getResultList().isEmpty();
}

/**
* @param uuid the uuid of the user to find
* @return the user with the given uuid, or null if no user is found
*/
public User findByUUID(UUID uuid) {
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();
try {
return em.createQuery(query
.where(
eq(cb, queryRoot, "uuid", uuid)))
.getSingleResult();
} catch (NoResultException e) {
logger.error("findByUUID() " + e.getClass().getSimpleName() + ": " + e.getMessage());
}
}

public List<User> listUnmatchedByConnectionId(Connection connection) {
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();
return em.createQuery(query
.where(
cb.and(
eq(cb, queryRoot, "connection", connection),
eq(cb, queryRoot, "matched", false))))
.getResultList();
}

/**
*
* @return
*/
public User findOrCreate(User inputUser) {
User user = null;
String subject = inputUser.getSubject();
try{
user = findBySubject(subject);
logger.info("findOrCreate(), trying to find user: {subject: " + subject+
"}, and found a user with uuid: " + user.getUuid()
+ ", subject: " + user.getSubject());
} catch (NoResultException e) {
logger.debug("findOrCreate() subject " + subject +
" could not be found by `entityManager`, going to create a new user.");
user = createUser(inputUser);
}catch(NonUniqueResultException e){
logger.error("findOrCreate() " + e.getClass().getSimpleName() + ": " + e.getMessage());
}
return user;
}

private User createUser(User inputUser) {
String subject = inputUser.getSubject();
// if (subject == null && userId == null){
// logger.error("createUser() cannot create user when both subject and userId are null");
// return null;
// }
logger.debug("createUser() creating user, subject: " + subject + " ......");
em().persist(inputUser);

User result = getById(inputUser.getUuid());
if (result != null)
logger.info("createUser() created user, uuid: " + result.getUuid()
+ ", subject: " + subject
+ ", role: " + result.getRoleString()
+ ", privilege: "+ result.getPrivilegeString());

return result;
}

public User changeRole(User user, Set<Role> roles){
logger.info("Starting changing the role of user: " + user.getUuid()
+ ", with subject: " + user.getSubject() + ", to " + roles.stream().map(role -> role.getName()).collect(Collectors.joining(",")));
user.setRoles(roles);
em().merge(user);
User updatedUser = getById(user.getUuid());
logger.info("User: " + updatedUser.getUuid() + ", with subject: " +
updatedUser.getSubject() + ", now has a new role: " + updatedUser.getRoleString());
return updatedUser;
}

@Override
public void persist(User user) {
findOrCreate(user);
}

public User findByEmail(String email) {
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();
return em.createQuery(query
.where(
eq(cb, queryRoot, "email", email)))
.getSingleResult();
}

public boolean checkAgainstTOSDate(String userId){
CriteriaQuery<User> query = cb().createQuery(User.class);
Root<User> queryRoot = query.from(User.class);
query.select(queryRoot);
CriteriaBuilder cb = cb();

Subquery<Date> subquery = query.subquery(Date.class);
Root<TermsOfService> tosRoot = subquery.from(TermsOfService.class);
subquery.select(cb.greatest(tosRoot.<Date>get("dateUpdated")));

return !em.createQuery(query
.where(
cb.and(
eq(cb, queryRoot, "subject", userId),
cb.greaterThanOrEqualTo(queryRoot.get("acceptedTOS"), subquery))))
.getResultList().isEmpty();
}

return null;
}

/**
* Creates a user with a subject of "open_access|{uuid}"
* and an email of "{uuid}@open_access.com"
*
* @return the created user
*/
public User createOpenAccessUser(Role openAccessRole) {
User user = new User();
em().persist(user);

user = getById(user.getUuid());
user.setSubject("open_access|" + user.getUuid().toString());
if (openAccessRole != null) {
user.setRoles(new HashSet<>(List.of(openAccessRole)));
} else {
logger.error("createOpenAccessUser() openAccessRole is null");
user.setRoles(new HashSet<>());
}
user.setEmail(user.getUuid() + "@open_access.com");
em().merge(user);

logger.info("createOpenAccessUser() created user, uuid: " + user.getUuid()
+ ", subject: " + user.getSubject()
+ ", role: " + user.getRoleString()
+ ", privilege: " + user.getPrivilegeString()
+ ", email: " + user.getEmail());
return user;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@
@Produces("application/json")
public class AuthService {

private Logger logger = LoggerFactory.getLogger(this.getClass());

@Inject
AuthorizationService authorizationService;
private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Inject
AuthenticationService authenticationService;
Expand Down
Loading