Implemented a simple Token Authentication for the /accounts endpoints, so not everyone can just create and delete accounts for fun. Closes #14
parent
333ee23c42
commit
f6e792b4e8
|
@ -50,7 +50,9 @@ public class AccountCrudTest {
|
|||
@Test
|
||||
void newAccountCanBeCreatedAndAccessedAfterwards() throws Exception {
|
||||
AccountForm form = new AccountForm("my-company", List.of("vip@my-company.com"));
|
||||
mockMvc.perform(post("/accounts").contentType(APPLICATION_JSON).content(mapper.writeValueAsString(form)))
|
||||
mockMvc.perform(post("/accounts").header("x-nclazz-auth", "integration-token")
|
||||
.contentType(APPLICATION_JSON).content(mapper.writeValueAsString(form)))
|
||||
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(content().contentType(APPLICATION_JSON))
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
|
@ -64,7 +66,7 @@ public class AccountCrudTest {
|
|||
Account account = Account.of("retrievable-account", List.of("info@account.com"));
|
||||
account = relay.saveAccount(account);
|
||||
|
||||
mockMvc.perform(get("/accounts/{guid}", account.getGuid()))
|
||||
mockMvc.perform(get("/accounts/{guid}", account.getGuid()).header("x-nclazz-auth", "integration-token"))
|
||||
.andExpect(status().is2xxSuccessful())
|
||||
.andExpect(content().contentType(APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$.name").value("retrievable-account"))
|
||||
|
@ -79,7 +81,9 @@ public class AccountCrudTest {
|
|||
|
||||
AccountForm form = new AccountForm("updated-account-renamed", List.of("vip@account.com"));
|
||||
|
||||
mockMvc.perform(put("/accounts/{guid}", account.getGuid()).contentType(APPLICATION_JSON).content(mapper.writeValueAsString(form)))
|
||||
mockMvc.perform(put("/accounts/{guid}", account.getGuid()).header("x-nclazz-auth", "integration-token")
|
||||
.contentType(APPLICATION_JSON).content(mapper.writeValueAsString(form)))
|
||||
|
||||
.andExpect(status().is2xxSuccessful())
|
||||
.andExpect(content().contentType(APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$.name").value("updated-account-renamed"))
|
||||
|
@ -90,7 +94,9 @@ public class AccountCrudTest {
|
|||
@Test
|
||||
void createAccountReturns400OnInvalidName() throws Exception {
|
||||
AccountForm form = new AccountForm("-- totally invalid --", List.of("vip@my-company.com"));
|
||||
mockMvc.perform(post("/accounts").contentType(APPLICATION_JSON).content(mapper.writeValueAsString(form)))
|
||||
mockMvc.perform(post("/accounts").header("x-nclazz-auth", "integration-token")
|
||||
.contentType(APPLICATION_JSON).content(mapper.writeValueAsString(form)))
|
||||
|
||||
.andExpect(status().is4xxClientError())
|
||||
.andExpect(content().contentType(APPLICATION_JSON));
|
||||
}
|
||||
|
@ -98,8 +104,17 @@ public class AccountCrudTest {
|
|||
@Test
|
||||
void createAccountReturns400OnInvalidReceiver() throws Exception {
|
||||
AccountForm form = new AccountForm("valid-name", List.of("valid@my-company.com", "in valid @my-company.com"));
|
||||
mockMvc.perform(post("/accounts").contentType(APPLICATION_JSON).content(mapper.writeValueAsString(form)))
|
||||
mockMvc.perform(post("/accounts").header("x-nclazz-auth", "integration-token")
|
||||
|
||||
.contentType(APPLICATION_JSON).content(mapper.writeValueAsString(form)))
|
||||
.andExpect(status().is4xxClientError())
|
||||
.andExpect(content().contentType(APPLICATION_JSON));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenNoAuthTokenIsProvidedReturns401() throws Exception {
|
||||
AccountForm form = new AccountForm("valid-name", List.of("valid@my-company.com", "in valid @my-company.com"));
|
||||
mockMvc.perform(post("/accounts").contentType(APPLICATION_JSON).content(mapper.writeValueAsString(form)))
|
||||
.andExpect(status().is(401));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,4 +6,6 @@ spring.mail.username=springboot
|
|||
spring.mail.password=integration
|
||||
spring.mail.host=localhost
|
||||
spring.mail.port=25
|
||||
spring.mail.protocol=smtp
|
||||
spring.mail.protocol=smtp
|
||||
|
||||
nclazz.auth.token=integration-token
|
|
@ -1,7 +1,10 @@
|
|||
package de.nclazz.service.mailrelay;
|
||||
|
||||
import de.nclazz.service.mailrelay.adapter.web.SimpleAuthenticationFilter;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.time.Clock;
|
||||
|
@ -18,4 +21,14 @@ public class MailRelayApplication {
|
|||
return Clock.systemDefaultZone();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<SimpleAuthenticationFilter> simpleAuthenticationFilter(@Value("${nclazz.auth.token}") String authenticationToken){
|
||||
FilterRegistrationBean<SimpleAuthenticationFilter> registrationBean = new FilterRegistrationBean<>();
|
||||
|
||||
registrationBean.setFilter(new SimpleAuthenticationFilter(authenticationToken));
|
||||
registrationBean.addUrlPatterns("/accounts/*");
|
||||
|
||||
return registrationBean;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,14 +20,15 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("accounts")
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("accounts")
|
||||
public class AccountRestController {
|
||||
|
||||
private final Relay relay;
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<Account> addAccount(@RequestBody @Valid AccountForm form) {
|
||||
|
||||
Account account = form.toAccount();
|
||||
account = this.relay.saveAccount(account);
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(account);
|
||||
|
@ -51,11 +52,13 @@ public class AccountRestController {
|
|||
}
|
||||
|
||||
@PutMapping("{guid}")
|
||||
public Account updateByGuid(@PathVariable("guid")UUID guid, @RequestBody @Valid AccountForm form) {
|
||||
public Account updateByGuid(@PathVariable("guid")UUID guid,
|
||||
@RequestBody @Valid AccountForm form) {
|
||||
Account account = this.relay.findAccount(guid)
|
||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||
account.setName(form.getName());
|
||||
account.setReceivers(form.getReceivers());
|
||||
return this.relay.saveAccount(account);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package de.nclazz.service.mailrelay.adapter.web;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SimpleAuthenticationFilter implements Filter {
|
||||
|
||||
private final String authenticationToken;
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse res = (HttpServletResponse) servletResponse;
|
||||
|
||||
String token = req.getHeader("x-nclazz-auth");
|
||||
|
||||
if(!this.authenticationToken.equals(token)) {
|
||||
res.setStatus(401);
|
||||
return;
|
||||
}
|
||||
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
# DDL auto schema generation (update, create, create-drop, none, validate)
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.datasource.url=jdbc:h2:file:./test-db
|
||||
|
||||
nclazz.auth.token=
|
|
@ -16,7 +16,6 @@ class AccountRestControllerTest {
|
|||
|
||||
@Test
|
||||
void addAccountCreatesNewAccountAndReturnsIs() {
|
||||
|
||||
Relay relay = TestRelayBuilder.builder().build();
|
||||
|
||||
AccountRestController controller = new AccountRestController(relay);
|
||||
|
@ -86,6 +85,7 @@ class AccountRestControllerTest {
|
|||
|
||||
@Test
|
||||
void accountCanBeUpdated() {
|
||||
String authToken = "auth-token";
|
||||
Relay relay = TestRelayBuilder.builder().build();
|
||||
|
||||
AccountRestController controller = new AccountRestController(relay);
|
||||
|
@ -103,4 +103,5 @@ class AccountRestControllerTest {
|
|||
.extracting("name", "receivers")
|
||||
.containsExactly("my-renamed-account", List.of("vip@my-company.com", "other@my-company.com"));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue