forked from mindsmash/tiny-tasks
-
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.
- User can login - User can register - Only authorized user can access tasks and some user data
- Loading branch information
ymolla
committed
Nov 8, 2019
1 parent
dde7dc0
commit 490e11f
Showing
14 changed files
with
320 additions
and
14 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
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 |
---|---|---|
@@ -1,5 +1,6 @@ | ||
#Fri Nov 08 15:41:57 EAT 2019 | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip | ||
distributionBase=GRADLE_USER_HOME | ||
distributionPath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip | ||
zipStoreBase=GRADLE_USER_HOME | ||
zipStorePath=wrapper/dists | ||
zipStoreBase=GRADLE_USER_HOME |
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 |
---|---|---|
@@ -1,13 +1,14 @@ | ||
package com.coyoapp.tinytask; | ||
|
||
public class ResourceConstants { | ||
public static final String TINY_TASKS_V1 = "/v1/tiny-tasks/"; | ||
|
||
//Everyday at 8:00 AM | ||
public static final String CRON_EVERYDAY_EXPRESSION = "0 0 8 * * *"; | ||
|
||
//used only for testing | ||
public static final String CRON_EVERY_TWO_SECONDS_EXPRESSION = "2 * * * * *"; | ||
|
||
public static final String EMAIL_SUBJECT = "Unfinished Tiny Tasks"; | ||
|
||
public static final String TINY_TASKS_V1_UNSECURED = "/v1/tiny-tasks/"; | ||
public static final String TINY_TASKS_V1_SECURED = "/v1/tiny-tasks/secured/"; | ||
} |
63 changes: 63 additions & 0 deletions
63
src/main/java/com/coyoapp/tinytask/auth/CustomUserDetails.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,63 @@ | ||
package com.coyoapp.tinytask.auth; | ||
|
||
import com.coyoapp.tinytask.domain.User; | ||
import org.springframework.security.core.GrantedAuthority; | ||
import org.springframework.security.core.authority.SimpleGrantedAuthority; | ||
import org.springframework.security.core.userdetails.UserDetails; | ||
|
||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
public class CustomUserDetails implements UserDetails { | ||
|
||
private User user; | ||
|
||
public CustomUserDetails(User user) { | ||
this.user = user; | ||
} | ||
|
||
@Override | ||
public Collection<? extends GrantedAuthority> getAuthorities() { | ||
if(null == user.getRoles()) { | ||
return Collections.emptySet(); | ||
} | ||
Set<SimpleGrantedAuthority> grantedAuthorities = new HashSet<>(); | ||
user.getRoles().forEach(role -> { | ||
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRole().toUpperCase())); | ||
}); | ||
|
||
return grantedAuthorities; | ||
} | ||
|
||
@Override | ||
public String getPassword() { | ||
return this.user.getPassword(); | ||
} | ||
|
||
@Override | ||
public String getUsername() { | ||
return this.user.getUsername(); | ||
} | ||
|
||
@Override | ||
public boolean isAccountNonExpired() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean isAccountNonLocked() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean isCredentialsNonExpired() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean isEnabled() { | ||
return true; | ||
} | ||
} |
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
53 changes: 53 additions & 0 deletions
53
src/main/java/com/coyoapp/tinytask/configuration/AuthServerConfig.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,53 @@ | ||
package com.coyoapp.tinytask.configuration; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; | ||
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; | ||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; | ||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; | ||
import org.springframework.security.oauth2.provider.token.TokenStore; | ||
|
||
@Configuration | ||
@EnableAuthorizationServer | ||
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { | ||
|
||
static final String CLIEN_ID = "tiny-task-client"; | ||
static final String CLIENT_SECRET = "tiny-secret"; | ||
static final String GRANT_TYPE_PASSWORD = "password"; | ||
static final String AUTHORIZATION_CODE = "authorization_code"; | ||
static final String REFRESH_TOKEN = "refresh_token"; | ||
static final String IMPLICIT = "implicit"; | ||
static final String SCOPE_READ = "read"; | ||
static final String SCOPE_WRITE = "write"; | ||
static final String TRUST = "trust"; | ||
static final int ACCESS_TOKEN_VALIDITY_SECONDS = 1 * 60 * 60; | ||
static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 6 * 60 * 60; | ||
|
||
@Autowired | ||
private TokenStore tokenStore; | ||
|
||
@Autowired | ||
private AuthenticationManager authenticationManager; | ||
|
||
@Override | ||
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception { | ||
|
||
configurer | ||
.inMemory() | ||
.withClient(CLIEN_ID) | ||
.secret(new BCryptPasswordEncoder().encode(CLIENT_SECRET)) | ||
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT) | ||
.scopes(SCOPE_READ, SCOPE_WRITE, TRUST) | ||
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS). | ||
refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS); | ||
} | ||
|
||
@Override | ||
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { | ||
endpoints.tokenStore(tokenStore) | ||
.authenticationManager(authenticationManager); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/com/coyoapp/tinytask/configuration/OAuthCoresConfig.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,30 @@ | ||
package com.coyoapp.tinytask.configuration; | ||
|
||
import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.core.Ordered; | ||
import org.springframework.web.cors.CorsConfiguration; | ||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | ||
import org.springframework.web.filter.CorsFilter; | ||
|
||
@Configuration | ||
public class OAuthCoresConfig { | ||
@Bean | ||
public FilterRegistrationBean customCorsFilter() { | ||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); | ||
CorsConfiguration config = new CorsConfiguration(); | ||
config.setAllowCredentials(true); | ||
config.addAllowedOrigin("http://localhost:4200"); | ||
config.addAllowedHeader("*"); | ||
config.addAllowedMethod("*"); | ||
source.registerCorsConfiguration("/oauth/token", config); | ||
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); | ||
|
||
//IMPORTANT #2: I didn't stress enough the importance of this line in my original answer, | ||
//but it's here where we tell Spring to load this filter at the right point in the chain | ||
//(with an order of precedence higher than oauth2's filters) | ||
bean.setOrder(Ordered.HIGHEST_PRECEDENCE); | ||
return bean; | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/com/coyoapp/tinytask/configuration/ResourceServerConfig.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,29 @@ | ||
package com.coyoapp.tinytask.configuration; | ||
|
||
import com.coyoapp.tinytask.ResourceConstants; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; | ||
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; | ||
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; | ||
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; | ||
|
||
@Configuration | ||
@EnableResourceServer | ||
public class ResourceServerConfig extends ResourceServerConfigurerAdapter { | ||
private static final String RESOURCE_ID = "resource_id"; | ||
|
||
@Override | ||
public void configure(ResourceServerSecurityConfigurer resources) { | ||
resources.resourceId(RESOURCE_ID).stateless(false); | ||
} | ||
|
||
@Override | ||
public void configure(HttpSecurity http) throws Exception { | ||
http.cors().and() | ||
.anonymous().disable() | ||
.authorizeRequests() | ||
.antMatchers(ResourceConstants.TINY_TASKS_V1_SECURED + "**").access( "hasRole('ROLE_USER')") | ||
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
src/main/java/com/coyoapp/tinytask/configuration/SecurityConfig.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,58 @@ | ||
package com.coyoapp.tinytask.configuration; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; | ||
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.core.userdetails.UserDetailsService; | ||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
import org.springframework.security.oauth2.provider.token.TokenStore; | ||
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; | ||
|
||
import javax.annotation.Resource; | ||
|
||
@Configuration | ||
@EnableWebSecurity | ||
@EnableGlobalMethodSecurity(prePostEnabled = true) | ||
public class SecurityConfig extends WebSecurityConfigurerAdapter { | ||
|
||
@Resource(name = "userService") | ||
private UserDetailsService userDetailsService; | ||
|
||
@Override | ||
@Bean | ||
public AuthenticationManager authenticationManagerBean() throws Exception { | ||
return super.authenticationManagerBean(); | ||
} | ||
|
||
@Autowired | ||
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { | ||
auth.userDetailsService(userDetailsService) | ||
.passwordEncoder(encoder()); | ||
} | ||
|
||
@Override | ||
protected void configure(HttpSecurity http) throws Exception { | ||
http | ||
.csrf().disable() | ||
.anonymous().disable() | ||
.authorizeRequests() | ||
.antMatchers("/**").permitAll(); | ||
} | ||
|
||
@Bean | ||
public TokenStore tokenStore() { | ||
return new InMemoryTokenStore(); | ||
} | ||
|
||
@Bean | ||
public BCryptPasswordEncoder encoder(){ | ||
return new BCryptPasswordEncoder(); | ||
} | ||
|
||
} |
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
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
49 changes: 49 additions & 0 deletions
49
src/main/java/com/coyoapp/tinytask/web/TinyTaskController.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,49 @@ | ||
package com.coyoapp.tinytask.web; | ||
|
||
import com.coyoapp.tinytask.ResourceConstants; | ||
import com.coyoapp.tinytask.domain.User; | ||
import com.coyoapp.tinytask.dto.TaskResponse; | ||
import com.coyoapp.tinytask.repository.UserRepository; | ||
import com.coyoapp.tinytask.service.TinyTaskService; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.security.core.userdetails.UserDetails; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import java.util.List; | ||
|
||
@Slf4j | ||
@RestController | ||
@RequestMapping(ResourceConstants.TINY_TASKS_V1_SECURED) | ||
@RequiredArgsConstructor | ||
public class TinyTaskController { | ||
|
||
@Autowired | ||
private UserRepository userRepository; | ||
|
||
private final TinyTaskService tinyTaskService; | ||
|
||
@GetMapping(path = "user/{userId}/tasks",produces = MediaType.APPLICATION_JSON_UTF8_VALUE) | ||
public ResponseEntity<List<TaskResponse>> getAllUserTasks(@PathVariable String userId) { | ||
return new ResponseEntity<>(tinyTaskService.getAllUserTasks(userId), HttpStatus.OK); | ||
} | ||
|
||
@GetMapping(path = "current-user",produces = MediaType.APPLICATION_JSON_UTF8_VALUE) | ||
public ResponseEntity<User> getLoggedInUser() { | ||
UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); | ||
|
||
String username = principal.getUsername(); | ||
|
||
User user = userRepository.findByUsername(username); | ||
|
||
return new ResponseEntity<>(user, HttpStatus.OK); | ||
} | ||
} |
Oops, something went wrong.