diff --git a/src/main/java/com/alkemy/ong/config/SecurityConfig.java b/src/main/java/com/alkemy/ong/config/SecurityConfig.java index dc835365..5d14a5e8 100644 --- a/src/main/java/com/alkemy/ong/config/SecurityConfig.java +++ b/src/main/java/com/alkemy/ong/config/SecurityConfig.java @@ -31,6 +31,7 @@ protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeHttpRequests() .antMatchers("/api/docs/**", "/api/swagger-ui/**", "/v3/api-docs/**", "/auth/login", "/auth/register").permitAll() + .antMatchers(HttpMethod.GET, "/v1/organizations/public").permitAll() .antMatchers(HttpMethod.GET).authenticated() .antMatchers(HttpMethod.POST).hasRole("ADMIN") .antMatchers(HttpMethod.PATCH).hasRole("ADMIN") diff --git a/src/main/java/com/alkemy/ong/core/model/Organization.java b/src/main/java/com/alkemy/ong/core/model/Organization.java index 41e437a8..8df0828e 100644 --- a/src/main/java/com/alkemy/ong/core/model/Organization.java +++ b/src/main/java/com/alkemy/ong/core/model/Organization.java @@ -9,18 +9,16 @@ import lombok.ToString; import org.hibernate.annotations.SQLDelete; import org.hibernate.annotations.Where; - -import javax.persistence.Column; -import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.EntityListeners; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Column; +import javax.persistence.Embedded; import java.util.Objects; - @Getter @Setter @ToString @@ -28,13 +26,13 @@ @Entity @Table(name = "organization") @Where(clause = "is_active=true") -@SQLDelete(sql ="UPDATE organization SET is_active=false WHERE organization_id=? ") +@SQLDelete(sql = "UPDATE organization SET is_active=false WHERE organization_id=? ") @EntityListeners(AuditListener.class) public class Organization implements Auditable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name="organization_id") + @Column(name = "organization_id") private Long id; @Column(nullable = false) @@ -52,19 +50,19 @@ public class Organization implements Auditable { @Column(nullable = false) private String email; - @Column(nullable = false, name="welcome_text", columnDefinition = "text") + @Column(nullable = false, name = "welcome_text", columnDefinition = "text") private String welcomeText; @Column(name = "about_us_text", columnDefinition = "text") private String aboutUsText; - @Column(name="facebook") + @Column(name = "facebook") private String facebookUrl; - @Column(name="linkedin") + @Column(name = "linkedin") private String linkedinUrl; - @Column(name="instagram") + @Column(name = "instagram") private String instagramUrl; @Embedded @@ -82,5 +80,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(id); } - } diff --git a/src/main/java/com/alkemy/ong/core/usecase/OrganizationService.java b/src/main/java/com/alkemy/ong/core/usecase/OrganizationService.java new file mode 100644 index 00000000..52a9318d --- /dev/null +++ b/src/main/java/com/alkemy/ong/core/usecase/OrganizationService.java @@ -0,0 +1,8 @@ +package com.alkemy.ong.core.usecase; + +import com.alkemy.ong.core.model.Organization; + +public interface OrganizationService { + + Organization getOrganizationEntity(Long id); +} diff --git a/src/main/java/com/alkemy/ong/core/usecase/impl/OrganizationServiceImpl.java b/src/main/java/com/alkemy/ong/core/usecase/impl/OrganizationServiceImpl.java new file mode 100644 index 00000000..9d919fe1 --- /dev/null +++ b/src/main/java/com/alkemy/ong/core/usecase/impl/OrganizationServiceImpl.java @@ -0,0 +1,22 @@ +package com.alkemy.ong.core.usecase.impl; + +import com.alkemy.ong.config.exception.NotFoundException; +import com.alkemy.ong.core.model.Organization; +import com.alkemy.ong.core.repository.OrganizationRepository; +import com.alkemy.ong.core.usecase.OrganizationService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class OrganizationServiceImpl implements OrganizationService { + + private final OrganizationRepository organizationRepository; + + @Override + @Transactional(readOnly = true) + public Organization getOrganizationEntity(Long id) { + return organizationRepository.findById(id).orElseThrow(() -> new NotFoundException(id)); + } +} diff --git a/src/main/java/com/alkemy/ong/ports/input/rs/api/OrganizationApi.java b/src/main/java/com/alkemy/ong/ports/input/rs/api/OrganizationApi.java new file mode 100644 index 00000000..6da63f94 --- /dev/null +++ b/src/main/java/com/alkemy/ong/ports/input/rs/api/OrganizationApi.java @@ -0,0 +1,18 @@ +package com.alkemy.ong.ports.input.rs.api; + +import com.alkemy.ong.ports.input.rs.response.OrganizationResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; + +@Validated +public interface OrganizationApi { + + @Operation(summary = "get Organization", description = "get Organization", responses = { + @ApiResponse(responseCode = "200", description = "Ok") + }) + ResponseEntity getOrganization(Long id); + +} diff --git a/src/main/java/com/alkemy/ong/ports/input/rs/controller/OrganizationController.java b/src/main/java/com/alkemy/ong/ports/input/rs/controller/OrganizationController.java new file mode 100644 index 00000000..f69726ec --- /dev/null +++ b/src/main/java/com/alkemy/ong/ports/input/rs/controller/OrganizationController.java @@ -0,0 +1,31 @@ +package com.alkemy.ong.ports.input.rs.controller; + +import com.alkemy.ong.core.model.Organization; +import com.alkemy.ong.core.usecase.OrganizationService; +import com.alkemy.ong.ports.input.rs.api.OrganizationApi; +import com.alkemy.ong.ports.input.rs.mapper.OrganizationControllerMapper; +import com.alkemy.ong.ports.input.rs.response.OrganizationResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import static com.alkemy.ong.ports.input.rs.api.ApiConstants.ORGANIZATIONS_URI; + +@RestController +@RequestMapping(ORGANIZATIONS_URI) +@RequiredArgsConstructor +public class OrganizationController implements OrganizationApi { + + private final OrganizationService organizationService; + + private final OrganizationControllerMapper mapper; + + @Override + @GetMapping("/{id}") + public ResponseEntity getOrganization(@PathVariable("id") Long id) { + Organization organization = organizationService.getOrganizationEntity(id); + OrganizationResponse organizationResponse = mapper.organizationToOrganizationResponse(organization); + return ResponseEntity.ok(organizationResponse); + } + +} diff --git a/src/main/java/com/alkemy/ong/ports/input/rs/mapper/OrganizationControllerMapper.java b/src/main/java/com/alkemy/ong/ports/input/rs/mapper/OrganizationControllerMapper.java new file mode 100644 index 00000000..5ed4c007 --- /dev/null +++ b/src/main/java/com/alkemy/ong/ports/input/rs/mapper/OrganizationControllerMapper.java @@ -0,0 +1,14 @@ +package com.alkemy.ong.ports.input.rs.mapper; + +import com.alkemy.ong.core.model.Organization; +import com.alkemy.ong.ports.input.rs.response.OrganizationResponse; +import org.mapstruct.Mapper; +import org.mapstruct.Named; + +@Mapper +public interface OrganizationControllerMapper extends CommonMapper { + + @Named("organizationToOrganizationResponse") + OrganizationResponse organizationToOrganizationResponse(Organization organization); + +} diff --git a/src/main/java/com/alkemy/ong/ports/input/rs/response/OrganizationResponse.java b/src/main/java/com/alkemy/ong/ports/input/rs/response/OrganizationResponse.java new file mode 100644 index 00000000..28906807 --- /dev/null +++ b/src/main/java/com/alkemy/ong/ports/input/rs/response/OrganizationResponse.java @@ -0,0 +1,19 @@ +package com.alkemy.ong.ports.input.rs.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class OrganizationResponse { + + private String name; + private String image; + private int phone; + private String address; + +}