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/java 21 Merge Fence Branch #166

Merged
merged 9 commits into from
Jun 21, 2024
Merged
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
31 changes: 31 additions & 0 deletions Jenkinsfile.fence
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
pipeline {
agent any

parameters {
string(name: 'DOCKER_REGISTRY', description: 'Docker registry URL (e.g., ECR URL)', defaultValue: 'hms-dbmi')
string(name: 'REPOSITORY_NAME', description: 'Docker repository name', defaultValue: 'psama')
}

environment {
DOCKER_BUILD_ARGS = "-f ./pic-sure-auth-services/Dockerfile"
GIT_BRANCH_SHORT = sh(script: 'echo ${GIT_BRANCH} | cut -d "/" -f 2', returnStdout: true).trim()
GIT_COMMIT_SHORT = sh(script: 'echo ${GIT_COMMIT} | cut -c1-7', returnStdout: true).trim()
IMAGE_TAG = "${GIT_BRANCH_SHORT}_${GIT_COMMIT_SHORT}"
LATEST_TAG = "latest"
}

stages {
stage('build') {
steps {
sh "docker build ${DOCKER_BUILD_ARGS} -t ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${IMAGE_TAG} ."
sh "docker tag ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${IMAGE_TAG} ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${LATEST_TAG}"
}
}
stage('deploy') {
steps {
sh "docker save ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${LATEST_TAG} | gzip > psama.tar.gz"
sh "aws s3 --sse=AES256 cp psama.tar.gz s3://$S3_BUCKET_NAME/releases/jenkins_pipeline_build_${pipeline_build_id}/psama.tar.gz"
}
}
}
}
32 changes: 32 additions & 0 deletions pic-sure-auth-db/db/sql/V5_MIGRATE_TO_ACCESSRULE_JOINTABLE.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# When merging the FENCE (Also consider the BDC specific) specific pic-sure-auth-micro-app and the more general
# pic-sure-auth-micro-app, we need to remove the circular dependency between the access_rule table and itself.
# We could have supported both, but the same functionality is already supported by the accessRule_subRule join table.
# This script will remove the circular dependency and replace it with a reference to the join table.

-- Step 1: Create the join table
--
-- Table structure for table `accessRule_subRule`
--
CREATE TABLE `accessRule_subRule`
(
`accessRule_id` binary(16) NOT NULL,
`subRule_id` binary(16) NOT NULL,
PRIMARY KEY (`accessRule_id`, `subRule_id`),
KEY (`subRule_id`),
CONSTRAINT FOREIGN KEY (`subRule_id`) REFERENCES `access_rule` (`uuid`),
CONSTRAINT FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- Step 2: Insert data from the circular dependency into the join table
INSERT INTO accessRule_subRule (accessRule_id, subRule_id)
SELECT ar.uuid, ar.subAccessRuleParent_uuid
FROM access_rule ar
WHERE ar.subAccessRuleParent_uuid IS NOT NULL;

-- Step 3: Update references in the original table to point to the join table
UPDATE access_rule ar
JOIN accessRule_subRule ars ON ars.accessRule_id = ar.uuid
SET ar.subAccessRuleParent_uuid = NULL; -- Remove circular dependency reference so it can be dropped

-- Step 4: Drop the column from the original table
ALTER TABLE access_rule DROP COLUMN subAccessRuleParent_uuid;
4 changes: 0 additions & 4 deletions pic-sure-auth-services/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
FROM maven:3.9.6-amazoncorretto-21 as build

COPY ./pom.xml /app/pom.xml

RUN mvn -f /app/pom.xml dependency:go-offline

# Copy the source code into the container
COPY ./ /app

Expand Down
15 changes: 6 additions & 9 deletions pic-sure-auth-services/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,8 @@
<xml.bind.version>2.3.0</xml.bind.version>
</properties>
<dependencies>
<!-- Spring dependencies -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>3.2.4</version>
<scope>compile</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<!-- Web version has been explicitly set to fix security finding in spring-boot-starter-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
Expand Down Expand Up @@ -80,6 +72,11 @@
<artifactId>mysql-connector-j</artifactId>
<version>8.2.0</version>
</dependency>
<dependency>
<groupId>com.amazonaws.secretsmanager</groupId>
<artifactId>aws-secretsmanager-jdbc</artifactId>
<version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.sessionManagement((session) -> session.sessionCreationPolicy(STATELESS))
.authenticationProvider(authenticationProvider)
.authorizeHttpRequests((authorizeRequests) ->
authorizeRequests.requestMatchers("/actuator/health", "/actuator/info", "/authentication/**", "/swagger.yaml", "/swagger.json","/authentication").permitAll()
authorizeRequests.requestMatchers("/actuator/health", "/actuator/info", "/authentication/**", "/swagger.yaml", "/swagger.json","/authentication", "/okta/authentication", "/open/authentication").permitAll()
.anyRequest().authenticated()
)
.httpBasic(AbstractHttpConfigurer::disable)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ public static class TypeNaming {
public static final int ANY_REG_MATCH = 12;
public static final int IS_EMPTY = 13;
public static final int IS_NOT_EMPTY = 14;
public static final int ALL_CONTAINS_OR_EMPTY = 15;
public static final int ALL_CONTAINS_OR_EMPTY_IGNORE_CASE = 16;

public static Map<String, Integer> getTypeNameMap(){
Map<String, Integer> map = new LinkedHashMap<>();
Expand Down Expand Up @@ -111,7 +113,6 @@ public static Map<String, Integer> getTypeNameMap(){
* This field should neither be saved to database
* nor seen by a user
*/
@JsonIgnore
@Transient
private Set<String> mergedValues = new HashSet<>();

Expand All @@ -120,7 +121,6 @@ public static Map<String, Integer> getTypeNameMap(){
* It is a intermediate product that generated on the fly for supporting
* auto-merging functionality of accessRules when doing authorization.
*/
@JsonIgnore
@Transient
private String mergedName = "";

Expand Down Expand Up @@ -159,13 +159,13 @@ public static Map<String, Integer> getTypeNameMap(){
@Column(name = "isEvaluateOnlyByGates")
private Boolean evaluateOnlyByGates;

@ManyToOne
private AccessRule subAccessRuleParent;

/**
* introduce sub-accessRule to enable the ability of more complex problem
* introduce sub-accessRule to enable the ability of more complex problem, essentially it is an AND relationship.
*/
@OneToMany(mappedBy = "subAccessRuleParent")
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "accessRule_subRule",
joinColumns = {@JoinColumn(name = "accessRule_id", nullable = false)},
inverseJoinColumns = {@JoinColumn(name = "subRule_id", nullable = false)})
private Set<AccessRule> subAccessRule;

/**
Expand Down Expand Up @@ -222,16 +222,6 @@ public void setDescription(String description) {
this.description = description;
}

@JsonIgnore
public AccessRule getSubAccessRuleParent() {
return subAccessRuleParent;
}

@JsonProperty("subAccessRuleParent")
public void setSubAccessRuleParent(AccessRule subAccessRuleParent) {
this.subAccessRuleParent = subAccessRuleParent;
}

public Set<AccessRule> getGates() {
return gates;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ public User setRoles(Set<Role> roles) {
}

/**
* return all privileges in the roles as a set
* @return
* @return set of privileges
*/
@JsonIgnore
public Set<Privilege> getTotalPrivilege(){
Expand All @@ -113,7 +112,7 @@ public Set<Privilege> getTotalPrivilege(){

/**
* return all privileges in the roles as a set
* @return
* @return set of privileges
*/
@JsonIgnore
public Set<AccessRule> getTotalAccessRule(){
Expand All @@ -128,7 +127,7 @@ public Set<AccessRule> getTotalAccessRule(){
/**
* return all privilege name in each role as a set.
*
* @return
* @return set of privilege names
*/
@JsonIgnore
public Set<String> getPrivilegeNameSet(){
Expand All @@ -138,14 +137,14 @@ public Set<String> getPrivilegeNameSet(){
return null;

Set<String> nameSet = new HashSet<>();
totalPrivilegeSet.stream().forEach(p -> nameSet.add(p.getName()));
totalPrivilegeSet.forEach(p -> nameSet.add(p.getName()));
return nameSet;
}

/**
* return privilege names in each role as a set based on Application given.
*
* @return
* @return set of privilege names
*/
@JsonIgnore
public Set<String> getPrivilegeNameSetByApplication(Application application){
Expand All @@ -170,7 +169,7 @@ public Set<String> getPrivilegeNameSetByApplication(Application application){
/**
* return privileges in each role as a set based on Application given.
*
* @return
* @return set of privileges
*/
@JsonIgnore
public Set<Privilege> getPrivilegesByApplication(Application application){
Expand All @@ -182,8 +181,7 @@ public Set<Privilege> getPrivilegesByApplication(Application application){
return null;

Set<Privilege> privileges = new HashSet<>();
roles.stream().
forEach(r -> privileges.addAll(r.getPrivileges()
roles.forEach(r -> privileges.addAll(r.getPrivileges()
.stream()
.filter(p -> application.getUuid()
.equals((p.getApplication()==null)?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edu.harvard.hms.dbmi.avillach.auth.filter;

import edu.harvard.hms.dbmi.avillach.auth.entity.Application;
import edu.harvard.hms.dbmi.avillach.auth.entity.Privilege;
import edu.harvard.hms.dbmi.avillach.auth.entity.Role;
import edu.harvard.hms.dbmi.avillach.auth.exceptions.NotAuthorizedException;
import edu.harvard.hms.dbmi.avillach.auth.model.CustomApplicationDetails;
Expand Down Expand Up @@ -215,12 +216,10 @@ private void setSecurityContextForUser(HttpServletRequest request, HttpServletRe
}
}

logger.info("User with email {} has roles {}.", authenticatedUser.getUser().getEmail(), userRoles != null ? userRoles.stream().map(Role::getName).collect(Collectors.joining(",")) : null);
logger.info("User with email {} has privileges {}.", authenticatedUser.getUser().getEmail(), userRoles != null ? userRoles.stream().map(Role::getPrivileges).collect(Collectors.toSet()) : null);
logger.info("User with email {} has privileges {}.", authenticatedUser.getUser().getEmail(), authenticatedUser.getUser().getTotalPrivilege().stream().map(Privilege::getName).collect(Collectors.joining(",")));
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(authenticatedUser, null, authenticatedUser.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public class CustomUserDetails implements UserDetails {
public CustomUserDetails(User user) {
this.user = user;
if (user != null && user.getRoles() != null) {
this.authorities = user.getRoles().stream()
.map(role -> (GrantedAuthority) role::getName)
this.authorities = user.getTotalPrivilege().stream()
.map(privilege -> (GrantedAuthority) privilege::getName)
.toList();
} else {
this.authorities = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package edu.harvard.hms.dbmi.avillach.auth.model.fenceMapping;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

public class BioDataCatalyst {

@JsonProperty("bio_data_catalyst")
private List<StudyMetaData> studyMetaData;

public List<StudyMetaData> getStudyMetaData() {
return studyMetaData;
}

public void setStudyMetaData(List<StudyMetaData> studyMetaData) {
this.studyMetaData = studyMetaData;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package edu.harvard.hms.dbmi.avillach.auth.model.fenceMapping;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;

public class IsHarmonizedDeserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
String text = jsonParser.getText();
return "Y".equalsIgnoreCase(text);
}
}
Loading