Skip to content
This repository has been archived by the owner on Jan 15, 2021. It is now read-only.

Commit

Permalink
Merge pull request #18 from FAIRDataTeam/release/0.3.0
Browse files Browse the repository at this point in the history
Release 0.3.0
  • Loading branch information
MarekSuchanek authored Jan 15, 2021
2 parents 0714148 + 6c3fa13 commit 7c9245c
Show file tree
Hide file tree
Showing 35 changed files with 1,397 additions and 36 deletions.
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.3.0]

The final release as the Index has been moved to [FAIR Data Point](https://github.com/FAIRDataTeam/FAIRDataPoint) (in [38a5fbd](https://github.com/FAIRDataTeam/FAIRDataPoint/commit/38a5fbdf3bc988447beda2c5daaa1938f15e5408)).

### Added

- Simple webhooks (from database) with possibility to select specific event(s) and/or
specific entries
- Ability to trigger metadata retrieval using secured API endpoints (admin-only)

## [0.2.0]

### Added
Expand All @@ -30,7 +40,7 @@ Initial version for simple list of FAIR Data Points.
- REST API to retrieve entries list (both all and paged) documented using Swagger/OpenAPI
- Simple webpage with table to browse entries including sorting and pagination

[Unreleased]: /../../compare/v0.2.0...develop
[0.1.0]: /../../tree/v0.1.0
[0.1.1]: /../../tree/v0.1.1
[0.2.0]: /../../tree/v0.2.0
[0.3.0]: /../../tree/v0.3.0
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# FAIRDataPoint-index

Index of FAIR Data Points
*Index of FAIR Data Points*

[![FAIRDataPoint-index CI](https://github.com/FAIRDataTeam/FAIRDataPoint-index/workflows/FAIRDataPoint-index%20CI/badge.svg?branch=master)](https://github.com/FAIRDataTeam/FAIRDataPoint-index/actions)
[![License](https://img.shields.io/github/license/FAIRDataTeam/FAIRDataPoint-index)](LICENSE)

:exclamation: The project has been moved directly to [FAIR Data Point](https://github.com/FAIRDataTeam/FAIRDataPoint) (in [38a5fbd](https://github.com/FAIRDataTeam/FAIRDataPoint/commit/38a5fbdf3bc988447beda2c5daaa1938f15e5408)) and is discontinued in this repository.

# Introduction

The index serves as a registry for [FAIR Data Point](https://github.com/FAIRDataTeam/FAIRDataPoint) deployments.
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

<groupId>solutions.fairdata</groupId>
<artifactId>fairdatapoint-index</artifactId>
<version>0.2.0</version>
<version>0.3.0</version>

<inceptionYear>2020</inceptionYear>

Expand All @@ -56,6 +56,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* The MIT License
* Copyright © 2020 https://fairdata.solutions
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package solutions.fairdata.fdp.index.api.controller;

import io.swagger.v3.oas.annotations.Operation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import solutions.fairdata.fdp.index.entity.events.Event;
import solutions.fairdata.fdp.index.service.EventService;
import solutions.fairdata.fdp.index.service.WebhookService;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

@RestController
@RequestMapping("/admin")
public class AdminController {
private static final Logger logger = LoggerFactory.getLogger(PingController.class);

@Autowired
private EventService eventService;

@Autowired
private WebhookService webhookService;

@Operation(hidden = true)
@PostMapping("/trigger")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void triggerMetadataRetrieve(@RequestParam(required = false) String clientUrl, HttpServletRequest request) {
logger.info("Received ping from {}", request.getRemoteAddr());
final Event event = eventService.acceptAdminTrigger(request, clientUrl);
webhookService.triggerWebhooks(event);
eventService.triggerMetadataRetrieval(event);
}

@Operation(hidden = true)
@PostMapping("/ping-webhook")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void webhookPing(@RequestParam(required = true) UUID webhook, HttpServletRequest request) {
logger.info("Received webhook {} ping trigger from {}", webhook, request.getRemoteAddr());
final Event event = webhookService.handleWebhookPing(request, webhook);
webhookService.triggerWebhooks(event);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import solutions.fairdata.fdp.index.api.dto.PingDTO;
import solutions.fairdata.fdp.index.entity.events.Event;
import solutions.fairdata.fdp.index.service.EventService;
import solutions.fairdata.fdp.index.service.WebhookService;

import javax.servlet.http.HttpServletRequest;

Expand All @@ -53,6 +54,9 @@ public class PingController {
@Autowired
private EventService eventService;

@Autowired
private WebhookService webhookService;

@Operation(
description = "Inform about running FAIR Data Point. It is expected to send pings regularly (at least weekly). There is a rate limit set both per single IP within a period of time and per URL in message.",
requestBody = @RequestBody(
Expand Down Expand Up @@ -80,8 +84,9 @@ public class PingController {
@ResponseStatus(HttpStatus.NO_CONTENT)
public void receivePing(HttpEntity<String> httpEntity, HttpServletRequest request) {
logger.info("Received ping from {}", request.getRemoteAddr());
final Event incomingPingEvent = eventService.acceptIncomingPing(httpEntity, request);
logger.info("Triggering metadata retrieval for {}", incomingPingEvent.getRelatedTo().getClientUrl());
eventService.triggerMetadataRetrieval(incomingPingEvent);
final Event event = eventService.acceptIncomingPing(httpEntity, request);
logger.info("Triggering metadata retrieval for {}", event.getRelatedTo().getClientUrl());
eventService.triggerMetadataRetrieval(event);
webhookService.triggerWebhooks(event);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* The MIT License
* Copyright © 2020 https://fairdata.solutions
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package solutions.fairdata.fdp.index.api.dto;

import lombok.Data;
import lombok.NoArgsConstructor;
import solutions.fairdata.fdp.index.entity.webhooks.WebhookEvent;

@Data
@NoArgsConstructor
public class WebhookPayloadDTO {
private WebhookEvent event;
private String uuid;
private String clientUrl;
private String timestamp;
private String secret;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* The MIT License
* Copyright © 2020 https://fairdata.solutions
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package solutions.fairdata.fdp.index.api.filters;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import solutions.fairdata.fdp.index.service.TokenService;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;

import static java.util.Optional.of;
import static java.util.Optional.ofNullable;

@Component
public class TokenFilter extends OncePerRequestFilter {

private static final String PREFIX = "Bearer ";

@Autowired
private TokenService tokenService;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
String token = getToken(request);
if (token != null) {
Optional<Authentication> auth = tokenService.getAuthentication(token);
auth.ifPresent(a -> SecurityContextHolder.getContext().setAuthentication(a));
}
filterChain.doFilter(request, response);
}

private String getToken(HttpServletRequest request) {
return ofNullable(request.getHeader(HttpHeaders.AUTHORIZATION))
.filter(h -> h.startsWith(PREFIX))
.flatMap(h -> of(h.substring(PREFIX.length())))
.orElse(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* The MIT License
* Copyright © 2020 https://fairdata.solutions
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

@javax.annotation.ParametersAreNonnullByDefault
package solutions.fairdata.fdp.index.api.filters;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* The MIT License
* Copyright © 2020 https://fairdata.solutions
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package solutions.fairdata.fdp.index.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import solutions.fairdata.fdp.index.api.filters.TokenFilter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
TokenFilter tokenFilter;

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/admin**").authenticated()
.anyRequest().permitAll()
.and()
.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,16 @@
import org.springframework.data.mongodb.repository.MongoRepository;
import solutions.fairdata.fdp.index.entity.IndexEntry;
import solutions.fairdata.fdp.index.entity.events.Event;
import solutions.fairdata.fdp.index.entity.events.EventType;

import java.time.Instant;
import java.util.List;

public interface EventRepository extends MongoRepository<Event, String> {

Iterable<Event> getAllByFinishedIsNull();
List<Event> getAllByType(EventType type);

List<Event> getAllByFinishedIsNull();

Page<Event> getAllByRelatedTo(IndexEntry indexEntry, Pageable pageable);

Expand Down
Loading

0 comments on commit 7c9245c

Please sign in to comment.