forked from mkyong/spring-boot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
583 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>spring-rest-security</artifactId> | ||
<packaging>jar</packaging> | ||
<name>Spring Boot REST API Example</name> | ||
<version>1.0</version> | ||
|
||
<parent> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-parent</artifactId> | ||
<version>2.1.2.RELEASE</version> | ||
</parent> | ||
|
||
<!-- Java 8 --> | ||
<properties> | ||
<java.version>1.8</java.version> | ||
<downloadSources>true</downloadSources> | ||
<downloadJavadocs>true</downloadJavadocs> | ||
</properties> | ||
|
||
<dependencies> | ||
|
||
<!-- spring mvc, rest --> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
|
||
<!-- spring security --> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-security</artifactId> | ||
</dependency> | ||
|
||
<!-- spring security test --> | ||
<dependency> | ||
<groupId>org.springframework.security</groupId> | ||
<artifactId>spring-security-test</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
<!-- jpa, crud repository --> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-data-jpa</artifactId> | ||
</dependency> | ||
|
||
<!-- in-memory database --> | ||
<dependency> | ||
<groupId>com.h2database</groupId> | ||
<artifactId>h2</artifactId> | ||
</dependency> | ||
|
||
<!-- unit test rest --> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-test</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
<!-- test patch operation need this --> | ||
<dependency> | ||
<groupId>org.apache.httpcomponents</groupId> | ||
<artifactId>httpclient</artifactId> | ||
<version>4.5.7</version> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
<!-- hot swapping, disable cache for template, enable live reload --> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-devtools</artifactId> | ||
<optional>true</optional> | ||
</dependency> | ||
|
||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
|
||
<plugin> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-maven-plugin</artifactId> | ||
<configuration> | ||
<addResources>true</addResources> | ||
</configuration> | ||
</plugin> | ||
|
||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<version>2.22.0</version> | ||
</plugin> | ||
|
||
</plugins> | ||
|
||
</build> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package com.mkyong; | ||
|
||
import com.mkyong.error.validator.Author; | ||
|
||
import javax.persistence.Entity; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.Id; | ||
import javax.validation.constraints.DecimalMin; | ||
import javax.validation.constraints.NotEmpty; | ||
import javax.validation.constraints.NotNull; | ||
import java.math.BigDecimal; | ||
|
||
@Entity | ||
public class Book { | ||
|
||
@Id | ||
@GeneratedValue | ||
private Long id; | ||
|
||
@NotEmpty(message = "Please provide a name") | ||
private String name; | ||
|
||
@Author | ||
@NotEmpty(message = "Please provide a author") | ||
private String author; | ||
|
||
@NotNull(message = "Please provide a price") | ||
@DecimalMin("1.00") | ||
private BigDecimal price; | ||
|
||
// avoid this "No default constructor for entity" | ||
public Book() { | ||
} | ||
|
||
public Book(String name, String author, BigDecimal price) { | ||
this.name = name; | ||
this.author = author; | ||
this.price = price; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public void setId(Long id) { | ||
this.id = id; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
public String getAuthor() { | ||
return author; | ||
} | ||
|
||
public void setAuthor(String author) { | ||
this.author = author; | ||
} | ||
|
||
public BigDecimal getPrice() { | ||
return price; | ||
} | ||
|
||
public void setPrice(BigDecimal price) { | ||
this.price = price; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Book{" + | ||
"id=" + id + | ||
", name='" + name + '\'' + | ||
", author='" + author + '\'' + | ||
", price=" + price + | ||
'}'; | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
spring-rest-security/src/main/java/com/mkyong/BookController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package com.mkyong; | ||
|
||
import com.mkyong.error.BookNotFoundException; | ||
import com.mkyong.error.BookUnSupportedFieldPatchException; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.util.StringUtils; | ||
import org.springframework.validation.annotation.Validated; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import javax.validation.Valid; | ||
import javax.validation.constraints.Min; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
@RestController | ||
@Validated | ||
public class BookController { | ||
|
||
@Autowired | ||
private BookRepository repository; | ||
|
||
// Find | ||
@GetMapping("/books") | ||
List<Book> findAll() { | ||
return repository.findAll(); | ||
} | ||
|
||
// Save | ||
@PostMapping("/books") | ||
Book newBook(@Valid @RequestBody Book newBook) { | ||
return repository.save(newBook); | ||
} | ||
|
||
// Find | ||
@GetMapping("/books/{id}") | ||
Book findOne(@PathVariable @Min(1) Long id) { | ||
return repository.findById(id) | ||
.orElseThrow(() -> new BookNotFoundException(id)); | ||
} | ||
|
||
// Save or update | ||
@PutMapping("/books/{id}") | ||
Book saveOrUpdate(@RequestBody Book newBook, @PathVariable Long id) { | ||
|
||
return repository.findById(id) | ||
.map(x -> { | ||
x.setName(newBook.getName()); | ||
x.setAuthor(newBook.getAuthor()); | ||
x.setPrice(newBook.getPrice()); | ||
return repository.save(x); | ||
}) | ||
.orElseGet(() -> { | ||
newBook.setId(id); | ||
return repository.save(newBook); | ||
}); | ||
} | ||
|
||
// update author only | ||
@PatchMapping("/books/{id}") | ||
Book patch(@RequestBody Map<String, String> update, @PathVariable Long id) { | ||
|
||
return repository.findById(id) | ||
.map(x -> { | ||
|
||
String author = update.get("author"); | ||
if (!StringUtils.isEmpty(author)) { | ||
x.setAuthor(author); | ||
|
||
// better create a custom method to update a value = :newValue where id = :id | ||
return repository.save(x); | ||
} else { | ||
throw new BookUnSupportedFieldPatchException(update.keySet()); | ||
} | ||
|
||
}) | ||
.orElseGet(() -> { | ||
throw new BookNotFoundException(id); | ||
}); | ||
|
||
} | ||
|
||
@DeleteMapping("/books/{id}") | ||
void deleteBook(@PathVariable Long id) { | ||
repository.deleteById(id); | ||
} | ||
|
||
} |
6 changes: 6 additions & 0 deletions
6
spring-rest-security/src/main/java/com/mkyong/BookRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.mkyong; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface BookRepository extends JpaRepository<Book, Long> { | ||
} |
26 changes: 26 additions & 0 deletions
26
spring-rest-security/src/main/java/com/mkyong/StartBookApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.mkyong; | ||
|
||
import org.springframework.boot.CommandLineRunner; | ||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.context.annotation.Bean; | ||
|
||
import java.math.BigDecimal; | ||
|
||
@SpringBootApplication | ||
public class StartBookApplication { | ||
|
||
// start everything | ||
public static void main(String[] args) { | ||
SpringApplication.run(StartBookApplication.class, args); | ||
} | ||
|
||
@Bean | ||
CommandLineRunner initDatabase(BookRepository repository) { | ||
return args -> { | ||
repository.save(new Book("A Guide to the Bodhisattva Way of Life", "Santideva", new BigDecimal("15.41"))); | ||
repository.save(new Book("The Life-Changing Magic of Tidying Up", "Marie Kondo", new BigDecimal("9.69"))); | ||
repository.save(new Book("Refactoring: Improving the Design of Existing Code", "Martin Fowler", new BigDecimal("47.99"))); | ||
}; | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
spring-rest-security/src/main/java/com/mkyong/config/SpringSecurityConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.mkyong.config; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.http.HttpMethod; | ||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | ||
import org.springframework.security.core.userdetails.User; | ||
import org.springframework.security.core.userdetails.UserDetailsService; | ||
import org.springframework.security.provisioning.InMemoryUserDetailsManager; | ||
|
||
@Configuration | ||
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { | ||
|
||
@Override | ||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { | ||
super.configure(auth); | ||
|
||
/*auth.inMemoryAuthentication() | ||
.withUser("user").password("{noop}password").roles("USER") | ||
.and() | ||
.withUser("admin").password("{noop}password").roles("ADMIN");*/ | ||
|
||
} | ||
|
||
@Override | ||
protected void configure(HttpSecurity http) throws Exception { | ||
|
||
http.httpBasic().and().authorizeRequests(). | ||
antMatchers(HttpMethod.GET, "/books/**").hasRole("USER"). | ||
antMatchers(HttpMethod.POST, "/books").hasRole("ADMIN"). //save | ||
antMatchers(HttpMethod.PUT, "/books/**").hasRole("ADMIN"). //update | ||
antMatchers(HttpMethod.PATCH, "/books/**").hasRole("ADMIN").//update | ||
antMatchers(HttpMethod.DELETE, "/books/**").hasRole("ADMIN"). //delete*/ | ||
and(). | ||
csrf().disable(); | ||
|
||
/*http | ||
.authorizeRequests() | ||
.antMatchers("/books").hasRole("USERS") | ||
.antMatchers("/books/**").hasRole("ADMIN") | ||
.and() | ||
.httpBasic() | ||
.and() | ||
.csrf().disable() | ||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);*/ | ||
|
||
} | ||
|
||
@Bean | ||
public UserDetailsService userDetailsService() { | ||
// for testing only | ||
User.UserBuilder users = User.withDefaultPasswordEncoder(); | ||
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); | ||
manager.createUser(users.username("user").password("password").roles("USER").build()); | ||
manager.createUser(users.username("admin").password("password").roles("USER", "ADMIN").build()); | ||
return manager; | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
spring-rest-security/src/main/java/com/mkyong/error/BookNotFoundException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.mkyong.error; | ||
|
||
public class BookNotFoundException extends RuntimeException { | ||
|
||
public BookNotFoundException(Long id) { | ||
super("Book id not found : " + id); | ||
} | ||
|
||
} |
11 changes: 11 additions & 0 deletions
11
spring-rest-security/src/main/java/com/mkyong/error/BookUnSupportedFieldPatchException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.mkyong.error; | ||
|
||
import java.util.Set; | ||
|
||
public class BookUnSupportedFieldPatchException extends RuntimeException { | ||
|
||
public BookUnSupportedFieldPatchException(Set<String> keys) { | ||
super("Field " + keys.toString() + " update is not allow."); | ||
} | ||
|
||
} |
Oops, something went wrong.