Skip to content
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
4 changes: 4 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ services:
- APPLICATION_UI_BASE_URL=${UI_BASE_URL}
- APPLICATION_INTERNAL_ASSERTION_SERVICE_ID=assertion-service-internal
- APPLICATION_INTERNAL_ASSERTION_SERVICE_CLIENT_SECRET=${ASSERTION_SERVICE_INTERNAL_CLIENT_SECRET}
- APPLICATION_INTERNAL_MEMBER_SERVICE_ID=member-service-internal
- APPLICATION_INTERNAL_MEMBER_SERVICE_CLIENT_SECRET=${MEMBER_SERVICE_INTERNAL_CLIENT_SECRET}
- APPLICATION_SECURITY_ISSUER_URL=${ISSUER_URL}
- UI_REDIRECT_URI=${UI_BASE_URL}/en/auth/callback
- UI_POST_LOGOUT_REDIRECT_URI=${UI_BASE_URL}/en/login
Expand Down Expand Up @@ -146,6 +148,8 @@ services:
- APPLICATION_SALESFORCE_USERNAME=${SALESFORCE_USERNAME}
- APPLICATION_SALESFORCE_PASSWORD=${SALESFORCE_PASSWORD}
- ENABLE_SCHEDULER=${ENABLE_SCHEDULER:-true}
- APPLICATION_INTERNAL_MEMBER_SERVICE_ID=member-service-internal
- APPLICATION_INTERNAL_MEMBER_SERVICE_CLIENT_SECRET=${MEMBER_SERVICE_INTERNAL_CLIENT_SECRET}
volumes:
- ${LOG_VOLUME:-/var/tmp/}:/logs

Expand Down
4 changes: 4 additions & 0 deletions member-service-2/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@
<artifactId>shedlock-spring</artifactId>
<version>5.13.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.orcid.mp.member.client;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;

/**
* Client for fetching member data from the MP member service.
*/
@Component
public class InternalUserServiceClient {

@Autowired
@Qualifier("internalUserServiceRestClient")
private RestClient internalUserServiceRestClient;

public String updateUsersMemberNames(String memberId, String newMemberName) {
return internalUserServiceRestClient.put().uri("/internal/users/memberName/" + memberId + "/" + newMemberName).retrieve().toEntity(String.class).getBody();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,4 @@ public String updateUser(User user) {
return restClient.put().uri("/users").body(user).retrieve().toEntity(String.class).getBody();
}

public String updateUsersMemberNames(String memberId, String newMemberName) {
return restClient.put().uri("/users/memberName/" + memberId + "/" + newMemberName).retrieve().toEntity(String.class).getBody();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package org.orcid.mp.member.config;

import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.security.oauth2.client.*;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.web.client.RestClient;

@Configuration
public class InternalClientConfig {

@Value("${application.userService.apiUrl}")
private String userServiceApiUrl;

@Autowired
private CloseableHttpClient httpClient;

@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientService clientService) {

OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();

AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceOAuth2AuthorizedClientManager(
clientRegistrationRepository, clientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

return authorizedClientManager;
}


@Bean
public ClientHttpRequestInterceptor internalSecurityInterceptor(
OAuth2AuthorizedClientManager authorizedClientManager) {
return (request, body, execution) -> {
// "assertion-service-client" MUST match the registration-id in your YAML
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest
.withClientRegistrationId("internal-member-client")
.principal("member-service") // Arbitrary string identifying who is running this
.build();

// This performs the magic: checks cache, or calls URL to get fresh token
OAuth2AuthorizedClient authorizedClient = authorizedClientManager.authorize(authorizeRequest);

if (authorizedClient != null) {
String token = authorizedClient.getAccessToken().getTokenValue();
request.getHeaders().setBearerAuth(token);
}

return execution.execute(request, body);
};
}

/**
* RestClient for making internal requests to the member service with scope 'internal', where no user token is present for authorization.
*
* @param internalSecurityInterceptor
* @return
*/
@Bean("internalUserServiceRestClient")
public RestClient internalUserServiceRestClient(ClientHttpRequestInterceptor internalSecurityInterceptor) {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
return RestClient.builder()
.baseUrl(userServiceApiUrl)
.requestFactory(requestFactory)
.requestInterceptor(internalSecurityInterceptor)
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,19 @@ public class Member implements Serializable {
private String defaultLanguage;

@Field
private String type;
private boolean active;

@Field("last_updated_with_salesforce_data")
private Instant lastUpdatedWithSalesforceData;

@Field("deactivated_date")
private Instant deactivatedDate;

@Field("activated_date")
private Instant activatedDate;

@Field
private String status;
private String type;

public String getId() {
return id;
Expand Down Expand Up @@ -171,14 +180,6 @@ public void setType(String type) {
this.type = type;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public String getDefaultLanguage() {
return defaultLanguage;
}
Expand All @@ -187,6 +188,38 @@ public void setDefaultLanguage(String defaultLanguage) {
this.defaultLanguage = defaultLanguage;
}

public boolean isActive() {
return active;
}

public void setActive(boolean active) {
this.active = active;
}

public Instant getLastUpdatedWithSalesforceData() {
return lastUpdatedWithSalesforceData;
}

public void setLastUpdatedWithSalesforceData(Instant lastUpdatedWithSalesforceData) {
this.lastUpdatedWithSalesforceData = lastUpdatedWithSalesforceData;
}

public Instant getDeactivatedDate() {
return deactivatedDate;
}

public void setDeactivatedDate(Instant deactivatedDate) {
this.deactivatedDate = deactivatedDate;
}

public Instant getActivatedDate() {
return activatedDate;
}

public void setActivatedDate(Instant activatedDate) {
this.activatedDate = activatedDate;
}

@Override
public int hashCode() {
final int prime = 31;
Expand All @@ -204,8 +237,10 @@ public int hashCode() {
result = prime * result + ((parentSalesforceId == null) ? 0 : parentSalesforceId.hashCode());
result = prime * result + ((salesforceId == null) ? 0 : salesforceId.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((status == null) ? 0 : status.hashCode());
result = prime * result + ((defaultLanguage == null) ? 0 : defaultLanguage.hashCode());
result = prime * result + ((deactivatedDate == null) ? 0 : deactivatedDate.hashCode());
result = prime * result + ((activatedDate == null) ? 0 : activatedDate.hashCode());
result = prime * result + ((lastUpdatedWithSalesforceData == null) ? 0 : lastUpdatedWithSalesforceData.hashCode());
return result;
}

Expand Down Expand Up @@ -283,16 +318,32 @@ public boolean equals(Object obj) {
return false;
} else if (!type.equals(other.type))
return false;
if (status == null) {
if (other.status != null)
return false;
} else if (!status.equals(other.status))
return false;
if (defaultLanguage == null) {
if (other.defaultLanguage != null)
return false;
} else if (!defaultLanguage.equals(other.defaultLanguage))
return false;
if (deactivatedDate == null) {
if (other.deactivatedDate != null)
return false;
} else if (!deactivatedDate.equals(other.deactivatedDate)) {
return false;
}
if (activatedDate == null) {
if (other.activatedDate != null)
return false;
} else if (!activatedDate.equals(other.activatedDate)) {
return false;
}
if (lastUpdatedWithSalesforceData == null) {
if (other.lastUpdatedWithSalesforceData != null)
return false;
} else if (!lastUpdatedWithSalesforceData.equals(other.lastUpdatedWithSalesforceData)) {
return false;
}
if (active != other.active) {
return false;
}
return true;
}

Expand All @@ -301,6 +352,7 @@ public String toString() {
return "Member [id=" + id + ", clientId=" + clientId + ", salesforceId=" + salesforceId + ", parentSalesforceId=" + parentSalesforceId + ", clientName="
+ clientName + ", isConsortiumLead=" + isConsortiumLead + ", assertionServiceEnabled=" + assertionServiceEnabled + ", superadminEnabled="
+ superadminEnabled + ", createdBy=" + createdBy + ", createdDate=" + createdDate + ", lastModifiedBy=" + lastModifiedBy + ", lastModifiedDate="
+ lastModifiedDate + ", type=" + type + ", status=" + status + ", defaultLanguage=" + defaultLanguage + "]";
+ lastModifiedDate + ", type=" + type + ", defaultLanguage=" + defaultLanguage + ", active=" + active + "]";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.orcid.mp.member.pojo.MemberContactUpdate;
import org.orcid.mp.member.pojo.MemberContactUpdateResponse;
import org.orcid.mp.member.pojo.RemoveConsortiumMember;
import org.orcid.mp.member.security.SecurityUtils;
import org.orcid.mp.member.service.SalesforceService;
import org.orcid.mp.member.service.UserService;
import org.orcid.mp.member.validation.MemberValidation;
Expand Down Expand Up @@ -67,7 +68,7 @@ public class MemberResource {
public ResponseEntity<Member> createMember(@Valid @RequestBody Member member)
throws URISyntaxException, JSONException {
LOG.debug("REST request to save Member : {}", member);
Member created = memberService.createMember(member);
Member created = memberService.createMember(member, SecurityUtils.getCurrentUserLogin().get());
return ResponseEntity.created(new URI("/api/member/" + created.getId())).body(created);
}

Expand Down Expand Up @@ -126,7 +127,7 @@ public ResponseEntity<Member> updateMember(@Valid @RequestBody Member member)
if (!existentMember.isPresent()) {
throw new BadRequestAlertException("Invalid id");
}
member = memberService.updateMember(member);
member = memberService.updateMember(member, SecurityUtils.getCurrentUserLogin().get());
return ResponseEntity.ok().body(member);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.Set;


import org.orcid.mp.member.client.SalesforceClient;
import org.orcid.mp.member.domain.Member;
import org.orcid.mp.member.domain.User;
import org.orcid.mp.member.error.BadRequestAlertException;
import org.orcid.mp.member.repository.MemberRepository;
import org.orcid.mp.member.validation.MemberValidation;
import org.orcid.mp.member.validation.MemberValidator;
import org.orcid.mp.member.salesforce.*;
import org.orcid.mp.member.security.AuthoritiesConstants;
import org.orcid.mp.member.security.SecurityUtils;
import org.orcid.mp.member.upload.MemberCsvReader;
import org.orcid.mp.member.upload.MemberUpload;
Expand Down Expand Up @@ -47,12 +44,6 @@ public class MemberService {
@Autowired
private MemberValidator memberValidator;

@Autowired
private SalesforceClient salesforceClient;

@Autowired
private MailService mailService;

public MemberUpload uploadMemberCSV(InputStream inputStream) {
LOG.info("Reading member CSV upload");
MemberUpload upload = null;
Expand All @@ -76,35 +67,36 @@ public MemberUpload uploadMemberCSV(InputStream inputStream) {
public Member createOrUpdateMember(Member member) {
Optional<Member> optional = memberRepository.findBySalesforceId(member.getSalesforceId());
if (!optional.isPresent()) {
return createMember(member);
return createMember(member, SecurityUtils.getCurrentUserLogin().get());
} else {
member.setId(optional.get().getId());
return updateMember(member);
return updateMember(member, SecurityUtils.getCurrentUserLogin().get());
}
}

public Member createMember(Member member) {
MemberValidation validation = memberValidator.validate(member, userService.getLoggedInUser());
public Member createMember(Member member, String createdBy) {
MemberValidation validation = memberValidator.validate(member, member.getDefaultLanguage() != null ? member.getDefaultLanguage() : "en");
if (!validation.isValid()) {
LOG.warn("Member invalid {}", validation.getErrors().toString());
throw new BadRequestAlertException("Member invalid");
}

Instant now = Instant.now();
member.setCreatedDate(now);
member.setLastModifiedDate(now);
member.setCreatedBy(SecurityUtils.getCurrentUserLogin().get());
member.setLastModifiedBy(SecurityUtils.getCurrentUserLogin().get());
member.setCreatedBy(createdBy);
member.setLastModifiedBy(createdBy);
return memberRepository.save(member);
}

public Member updateMember(Member member) {
public Member updateMember(Member member, String updatedBy) {
Optional<Member> optional = memberRepository.findById(member.getId());
validateMemberUpdate(member, optional);

Member existingMember = optional.get();
existingMember.setClientId(member.getClientId());
existingMember.setParentSalesforceId(member.getParentSalesforceId());
existingMember.setLastModifiedBy(SecurityUtils.getCurrentUserLogin().get());
existingMember.setLastModifiedBy(updatedBy);
existingMember.setLastModifiedDate(Instant.now());
existingMember.setAssertionServiceEnabled(member.getAssertionServiceEnabled());
existingMember.setIsConsortiumLead(member.getIsConsortiumLead());
Expand All @@ -122,7 +114,7 @@ private void propagateUpdatesAndSave(Member member, Member existingMember) {
}

private void validateMemberUpdate(Member member, Optional<Member> existingMember) {
MemberValidation validation = memberValidator.validate(member, userService.getLoggedInUser());
MemberValidation validation = memberValidator.validate(member, member.getDefaultLanguage() != null ? member.getDefaultLanguage() : "en");
if (!validation.isValid()) {
throw new BadRequestAlertException("Member invalid");
}
Expand All @@ -148,7 +140,7 @@ private void validateMemberUpdate(Member member, Optional<Member> existingMember
}

public MemberValidation validateMember(Member member) {
return memberValidator.validate(member, userService.getLoggedInUser());
return memberValidator.validate(member, userService.getLoggedInUser().getLangKey());
}

public Page<Member> getMembers(Pageable pageable) {
Expand Down
Loading
Loading