diff --git a/pom.xml b/pom.xml index 52899f3..d1cf437 100644 --- a/pom.xml +++ b/pom.xml @@ -54,6 +54,11 @@ swag-organizations 1.8-1de59d5-epic-server + + com.rbkmoney + org-management-proto + 1.2-06c5c84 + diff --git a/src/main/java/com/rbkmoney/orgmanager/config/AppConfig.java b/src/main/java/com/rbkmoney/orgmanager/config/AppConfig.java new file mode 100644 index 0000000..882d76f --- /dev/null +++ b/src/main/java/com/rbkmoney/orgmanager/config/AppConfig.java @@ -0,0 +1,8 @@ +package com.rbkmoney.orgmanager.config; + +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AppConfig { + +} diff --git a/src/main/java/com/rbkmoney/orgmanager/converter/MemberConverter.java b/src/main/java/com/rbkmoney/orgmanager/converter/MemberConverter.java index 5223683..993d25a 100644 --- a/src/main/java/com/rbkmoney/orgmanager/converter/MemberConverter.java +++ b/src/main/java/com/rbkmoney/orgmanager/converter/MemberConverter.java @@ -1,10 +1,14 @@ package com.rbkmoney.orgmanager.converter; +import com.rbkmoney.bouncer.context.v1.*; import com.rbkmoney.orgmanager.entity.MemberEntity; +import com.rbkmoney.orgmanager.entity.OrganizationEntity; import com.rbkmoney.swag.organizations.model.Member; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.stream.Collectors; + import static java.util.stream.Collectors.toSet; @Service @@ -12,6 +16,7 @@ import static java.util.stream.Collectors.toSet; public class MemberConverter { private final MemberRoleConverter memberRoleConverter; + private final OrganizationConverter organizationConverter; public Member toDomain(MemberEntity entity) { return new Member() @@ -21,4 +26,16 @@ public class MemberConverter { .map(memberRoleConverter::toDomain) .collect(toSet())); } + + public User toThrift(MemberEntity member) { + return new User() + .setId(member.getId()) + .setRealm(new Entity()) + .setEmail(member.getEmail()) + .setOrgs(member.getOrganizations() == null ? null : + member.getOrganizations() + .stream() + .map(organizationConverter::toThrift) + .collect(Collectors.toSet())); + } } diff --git a/src/main/java/com/rbkmoney/orgmanager/converter/OrganizationConverter.java b/src/main/java/com/rbkmoney/orgmanager/converter/OrganizationConverter.java index 4e72b1c..a6fbc4b 100644 --- a/src/main/java/com/rbkmoney/orgmanager/converter/OrganizationConverter.java +++ b/src/main/java/com/rbkmoney/orgmanager/converter/OrganizationConverter.java @@ -1,5 +1,8 @@ package com.rbkmoney.orgmanager.converter; +import com.rbkmoney.bouncer.context.v1.Entity; +import com.rbkmoney.bouncer.context.v1.OrgRole; +import com.rbkmoney.bouncer.context.v1.OrgRoleScope; import com.rbkmoney.orgmanager.entity.OrganizationEntity; import com.rbkmoney.orgmanager.util.JsonMapper; import com.rbkmoney.swag.organizations.model.Organization; @@ -10,6 +13,7 @@ import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.util.UUID; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -35,4 +39,17 @@ public class OrganizationConverter { .owner(entity.getOwner()) .metadata(jsonMapper.toMap(entity.getMetadata())); } + + public com.rbkmoney.bouncer.context.v1.Organization toThrift(OrganizationEntity e) { + return new com.rbkmoney.bouncer.context.v1.Organization() + .setId(e.getId()) + .setOwner(new Entity()) + .setRoles(e.getRoles() == null ? null : + e.getRoles().stream() + .map(r -> new OrgRole() + .setId(r.getId()) + .setScope(new OrgRoleScope() + .setShop(new Entity()))) + .collect(Collectors.toSet())); + } } diff --git a/src/main/java/com/rbkmoney/orgmanager/entity/MemberEntity.java b/src/main/java/com/rbkmoney/orgmanager/entity/MemberEntity.java index 8a8c6ed..fcb9916 100644 --- a/src/main/java/com/rbkmoney/orgmanager/entity/MemberEntity.java +++ b/src/main/java/com/rbkmoney/orgmanager/entity/MemberEntity.java @@ -26,5 +26,14 @@ public class MemberEntity implements Serializable { inverseJoinColumns = @JoinColumn(name = "member_role_id")) private Set roles; + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) + @JoinTable( + name = "member_to_organization", + joinColumns = @JoinColumn(name = "member_id"), + inverseJoinColumns = @JoinColumn(name = "organization_id")) + private Set organizations; + private String email; } diff --git a/src/main/java/com/rbkmoney/orgmanager/service/AuthContextService.java b/src/main/java/com/rbkmoney/orgmanager/service/AuthContextService.java new file mode 100644 index 0000000..2bf0135 --- /dev/null +++ b/src/main/java/com/rbkmoney/orgmanager/service/AuthContextService.java @@ -0,0 +1,37 @@ +package com.rbkmoney.orgmanager.service; + +import com.rbkmoney.bouncer.ctx.ContextFragment; +import com.rbkmoney.bouncer.ctx.ContextFragmentType; +import com.rbkmoney.orgmanagement.AuthContextProviderSrv; +import com.rbkmoney.orgmanagement.UserNotFound; +import com.rbkmoney.orgmanager.converter.MemberConverter; +import com.rbkmoney.orgmanager.entity.MemberEntity; +import com.rbkmoney.orgmanager.repository.MemberRepository; +import lombok.RequiredArgsConstructor; +import org.apache.thrift.TException; +import org.apache.thrift.TSerializer; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class AuthContextService implements AuthContextProviderSrv.Iface { + + private final MemberRepository memberRepository; + private final MemberConverter memberConverter; + + @Override + public ContextFragment getUserContext(String id) throws UserNotFound, TException { + + Optional entity = memberRepository.findById(id); + if (entity.isEmpty()) { + throw new UserNotFound(); + } + MemberEntity member = entity.get(); + TSerializer tSerializer = new TSerializer(); + return new ContextFragment() + .setType(ContextFragmentType.v1_thrift_binary) + .setContent(tSerializer.serialize(memberConverter.toThrift(member))); + } +} diff --git a/src/main/java/com/rbkmoney/orgmanager/servlet/AuthContextProviderServlet.java b/src/main/java/com/rbkmoney/orgmanager/servlet/AuthContextProviderServlet.java new file mode 100644 index 0000000..9e1f01e --- /dev/null +++ b/src/main/java/com/rbkmoney/orgmanager/servlet/AuthContextProviderServlet.java @@ -0,0 +1,32 @@ +package com.rbkmoney.orgmanager.servlet; + +import com.rbkmoney.orgmanagement.AuthContextProviderSrv; +import com.rbkmoney.woody.thrift.impl.http.THServiceBuilder; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import javax.servlet.*; +import javax.servlet.annotation.WebServlet; +import java.io.IOException; + +@WebServlet("/auth-context") +@Slf4j +@RequiredArgsConstructor +public class AuthContextProviderServlet extends GenericServlet { + + private Servlet thriftServlet; + + private final AuthContextProviderSrv.Iface authContextProvider; + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + thriftServlet = new THServiceBuilder() + .build(AuthContextProviderSrv.Iface.class, authContextProvider); + } + + @Override + public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { + thriftServlet.service(req, res); + } +} diff --git a/src/test/java/com/rbkmoney/orgmanager/converter/MemberConverterTest.java b/src/test/java/com/rbkmoney/orgmanager/converter/MemberConverterTest.java index 688d8ff..74c109e 100644 --- a/src/test/java/com/rbkmoney/orgmanager/converter/MemberConverterTest.java +++ b/src/test/java/com/rbkmoney/orgmanager/converter/MemberConverterTest.java @@ -1,8 +1,11 @@ package com.rbkmoney.orgmanager.converter; +import com.rbkmoney.bouncer.context.v1.User; import com.rbkmoney.orgmanager.entity.MemberEntity; import com.rbkmoney.orgmanager.entity.MemberRoleEntity; +import com.rbkmoney.orgmanager.entity.OrganizationEntity; import com.rbkmoney.swag.organizations.model.*; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -26,17 +29,17 @@ public class MemberConverterTest { when(memberRoleConverter.toEntity(any(MemberRole.class), anyString())) .thenReturn(new MemberRoleEntity()); - converter = new MemberConverter(memberRoleConverter); + OrganizationConverter organizationConverter = mock(OrganizationConverter.class); + when(organizationConverter.toThrift(any(OrganizationEntity.class))) + .thenReturn(new com.rbkmoney.bouncer.context.v1.Organization()); + + converter = new MemberConverter(memberRoleConverter, organizationConverter); } @Test public void shouldConvertToDomain() { // Given - MemberEntity entity = MemberEntity.builder() - .id("id") - .email("email") - .roles(Set.of(new MemberRoleEntity())) - .build(); + MemberEntity entity = buildMemberEntity(); // When Member member = converter.toDomain(entity); @@ -49,4 +52,23 @@ public class MemberConverterTest { assertThat(member).isEqualToComparingFieldByField(expected); } + + @Test + public void shouldConvertToThrift() { + MemberEntity entity = buildMemberEntity(); + User user = converter.toThrift(entity); + Assert.assertEquals(entity.getId(), user.getId()); + Assert.assertEquals(entity.getEmail(), user.getEmail()); + Assert.assertEquals(entity.getOrganizations().size(), user.getOrgs().size()); + } + + private MemberEntity buildMemberEntity() { + return MemberEntity.builder() + .id("id") + .email("email") + .roles(Set.of(new MemberRoleEntity())) + .organizations(Set.of(new OrganizationEntity())) + .build(); + } + } \ No newline at end of file diff --git a/src/test/java/com/rbkmoney/orgmanager/converter/OrganizationConverterTest.java b/src/test/java/com/rbkmoney/orgmanager/converter/OrganizationConverterTest.java index 1bd5ea2..4a5dfa8 100644 --- a/src/test/java/com/rbkmoney/orgmanager/converter/OrganizationConverterTest.java +++ b/src/test/java/com/rbkmoney/orgmanager/converter/OrganizationConverterTest.java @@ -2,6 +2,7 @@ package com.rbkmoney.orgmanager.converter; import com.fasterxml.jackson.databind.ObjectMapper; import com.rbkmoney.orgmanager.entity.OrganizationEntity; +import com.rbkmoney.orgmanager.entity.OrganizationRoleEntity; import com.rbkmoney.orgmanager.util.JsonMapper; import com.rbkmoney.swag.organizations.model.Organization; import org.junit.Before; @@ -10,8 +11,10 @@ import org.junit.Test; import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.util.Map; +import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; public class OrganizationConverterTest { @@ -50,13 +53,7 @@ public class OrganizationConverterTest { @Test public void shouldConvertToDomain() { // Given - OrganizationEntity entity = OrganizationEntity.builder() - .id("id") - .createdAt(LocalDateTime.parse("2019-08-24T14:15:22")) - .name("org") - .owner("own") - .metadata("{\"a\":\"b\"}") - .build(); + OrganizationEntity entity = buildOrganizationEntity(); // When Organization organization = converter.toDomain(entity); @@ -71,4 +68,23 @@ public class OrganizationConverterTest { assertThat(organization).isEqualToComparingFieldByField(expected); } + + @Test + public void shouldConvertToThrift(){ + OrganizationEntity organizationEntity = buildOrganizationEntity(); + var organization = converter.toThrift(organizationEntity); + assertEquals(organizationEntity.getId(), organization.getId()); + assertEquals(organizationEntity.getRoles().size(), organization.getRoles().size()); + } + + private OrganizationEntity buildOrganizationEntity() { + return OrganizationEntity.builder() + .id("id") + .createdAt(LocalDateTime.parse("2019-08-24T14:15:22")) + .name("org") + .owner("own") + .metadata("{\"a\":\"b\"}") + .roles(Set.of(new OrganizationRoleEntity())) + .build(); + } } \ No newline at end of file diff --git a/src/test/java/com/rbkmoney/orgmanager/service/AuthContextServiceTest.java b/src/test/java/com/rbkmoney/orgmanager/service/AuthContextServiceTest.java new file mode 100644 index 0000000..5ed6c2f --- /dev/null +++ b/src/test/java/com/rbkmoney/orgmanager/service/AuthContextServiceTest.java @@ -0,0 +1,53 @@ +package com.rbkmoney.orgmanager.service; + +import com.rbkmoney.bouncer.context.v1.User; +import com.rbkmoney.bouncer.ctx.ContextFragment; +import com.rbkmoney.bouncer.ctx.ContextFragmentType; +import com.rbkmoney.orgmanagement.UserNotFound; +import com.rbkmoney.orgmanager.converter.MemberConverter; +import com.rbkmoney.orgmanager.entity.MemberEntity; +import com.rbkmoney.orgmanager.repository.MemberRepository; +import org.apache.thrift.TException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.Optional; + + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +@RunWith(MockitoJUnitRunner.class) +public class AuthContextServiceTest { + + @Mock + private MemberRepository memberRepository; + @Mock + private MemberConverter memberConverter; + + @InjectMocks + private AuthContextService service; + + @Test + public void testUserContext() throws TException { + String id = "1"; + when(memberRepository.findById(id)).thenReturn(Optional.of(new MemberEntity())); + when(memberConverter.toThrift(any())).thenReturn(new User()); + + ContextFragment userContext = service.getUserContext(id); + + verify(memberRepository, times(1)).findById(id); + verify(memberConverter, times(1)).toThrift(any()); + assertEquals(ContextFragmentType.v1_thrift_binary, userContext.getType()); + } + + @Test(expected = UserNotFound.class) + public void testUserNotFound() throws TException { + String id = "1"; + when(memberRepository.findById(id)).thenReturn(Optional.empty() ); + service.getUserContext(id); + } +}