Skip to content

Commit

Permalink
Merge pull request #40 from razakpm/main
Browse files Browse the repository at this point in the history
feat: disable login requirements in local environment #15
  • Loading branch information
ratheesh-kr authored Jun 18, 2024
2 parents a7d2c6a + 08b6812 commit 6b304da
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 30 deletions.
6 changes: 5 additions & 1 deletion .envrc.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

# If you want use these, remember to start VSCode or your IDE after `direnv allow`

# use `sandbox` (localhost), `devl`, `stage`, `prod`

# use Spring profiles as 'localopen' for testing locally with no authentication, `sandbox` for testing with auth in localhost , `devl`, `stage`, `prod`
export SPRING_PROFILES_ACTIVE=sandbox

# use `localopen', `sandbox` (localhost), `devl`, `stage`, `prod`
export SPRING_PROFILES_ACTIVE=sandbox
export sandbox_TECHBD_UDI_DS_PRIME_JDBC_URL=jdbc:postgresql://aws.neon.tech/persistence-prime
export sandbox_TECHBD_UDI_DS_PRIME_JDBC_USERNAME=persistence-prime
Expand Down
6 changes: 3 additions & 3 deletions hub-prime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</parent>
<groupId>org.techbd</groupId>
<artifactId>hub-prime</artifactId>
<version>0.66.0</version>
<version>0.67.0</version>
<packaging>war</packaging>
<name>TechBD Hub (Prime)</name>
<description>TechBD Hub (Primary)</description>
Expand Down Expand Up @@ -205,11 +205,11 @@
<artifactId>jaxb-impl</artifactId>
<version>4.0.5</version>
</dependency>
<dependency>
<!-- <dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
</dependency> -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.techbd.service.http;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.filter.ForwardedHeaderFilter;

@Configuration
@EnableWebSecurity
@ConfigurationProperties(prefix = "spring.security.oauth2.client.registration.github")
@Profile("localopen")
public class NoAuthSecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests -> authorizeRequests
.anyRequest().permitAll())
.csrf().disable(); // Disable CSRF for simplicity in sandbox

return http.build();
}

@Bean
public CorsFilter corsFilter() {
// primarily setup for Swagger UI and OpenAPI integration
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOriginPattern("*"); // Customize as needed
config.addAllowedMethod("*");
config.addAllowedHeader("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}

@Bean
ForwardedHeaderFilter forwardedHeaderFilter() {
return new ForwardedHeaderFilter();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package org.techbd.service.http;

import org.springframework.context.annotation.Bean;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
Expand All @@ -9,29 +12,39 @@
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.filter.ForwardedHeaderFilter;
import org.springframework.web.filter.OncePerRequestFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.techbd.service.http.filter.GitHubUserAuthorizationFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@ConfigurationProperties(prefix = "spring.security.oauth2.client.registration.github")
@Profile("!localopen")
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws Exception {
// allow authentication for security
// and turn off CSRF to allow POST methods
http.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/login/**", "/oauth2/**", "/", "/Bundle/**", "/metadata",
.requestMatchers("/login/**", "/oauth2/**", "/", "/Bundle", "/Bundle/**", "/metadata",
"/docs/api/interactive/swagger-ui/**", "/docs/api/interactive/**", "/docs/api/openapi/**")
.permitAll()
.anyRequest().authenticated())
.oauth2Login(oauth2Login -> oauth2Login
.defaultSuccessUrl("/home", true))
.csrf(AbstractHttpConfigurer::disable)
.addFilterAfter(new GitHubUserAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
.addFilterAfter(new GitHubUserAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new ExceptionHandlingFilter(), GitHubUserAuthorizationFilter.class);
// allow us to show our own content in IFRAMEs (e.g. Swagger, etc.)
http.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.sameOrigin()));
// System.out.println(http.);
return http.build();
}

Expand All @@ -52,4 +65,36 @@ ForwardedHeaderFilter forwardedHeaderFilter() {
return new ForwardedHeaderFilter();
}

public class ExceptionHandlingFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response,
@NotNull FilterChain filterChain)
throws ServletException, IOException {

if (request.getRequestURI().startsWith("/Bundle")) {

// Check if X-TechBD-Tenant-ID header is missing
if (request.getHeader("X-TechBD-Tenant-ID") == null) {
handleError(response, HttpServletResponse.SC_NOT_FOUND, "X-TechBD-Tenant-ID header is missing");
return;
}

// Check if Content-Type is application/json
if (!"application/json".equals(request.getContentType())) {
handleError(response, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE,
"Content-Type must be application/json");
return;
}

}
filterChain.doFilter(request, response);
}

private void handleError(HttpServletResponse response, int statusCode, String message) throws IOException {
response.setStatus(statusCode);
response.getWriter().write(message);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ public String metadata(final Model model, HttpServletRequest request) {
return "metadata.xml";
}

@PostMapping(value = { "/Bundle/" }, consumes = MediaType.APPLICATION_JSON_VALUE)
@PostMapping(value = { "/Bundle" }, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
@Async
public Object validateBundleAndCreate(final @RequestBody @Nonnull String payload,
Expand Down Expand Up @@ -486,7 +486,7 @@ public List<?> observeRecentSftpInteractions() {
@Operation(summary = "Recent HTTP Request/Response Interactions")
@GetMapping("/admin/observe/interaction/https/recent.json")
@ResponseBody
public Page<Interaction> observeRecentHttpsInteractions(final Model model,
public Page<Interaction> observeRecentHttpsInteractions(final Model model,
final HttpServletRequest request,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Expand Down
59 changes: 37 additions & 22 deletions hub-prime/src/main/resources/templates/layout/prime.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,28 +131,43 @@
id="user-menu-button" aria-expanded="false" aria-haspopup="true">
<span class="absolute -inset-1.5"></span>
<span class="sr-only">Open user menu</span>
<div sec:authentication="principal.attributes['avatar_url']" id="avatar_url"
class="hidden"></div>
<div sec:authentication="principal.attributes['html_url']" id="html_url"
class="hidden"></div>
<div class="relative group">
<a href="#" id="principal_html">
<img class="h-8 w-8 rounded-full" alt="User Profile"
id="principal_image" />
</a>
<div class="hidden group-hover:block absolute z-10 mt-2 w-48 origin-top-right right-2 rounded-md bg-white py-2 shadow-lg ring-1 ring-black ring-opacity-5"
role="menu" aria-orientation="vertical"
aria-labelledby="user-menu-button" tabindex="-1">
<a href="#" class="block px-2 py-2 text-sm text-gray-700 text-left"
role="menuitem" tabindex="-1" id="user-menu-item-0">
<div>
Name:
<span sec:authentication="principal.attributes['name']"></span>
</div>
<div>
ID:
<span sec:authentication="principal.attributes['login']"></span>
</div>
<div sec:authorize="isAuthenticated()">
<div sec:authentication="principal.attributes['avatar_url']" id="avatar_url"
class="hidden"></div>
<div sec:authentication="principal.attributes['html_url']" id="html_url"
class="hidden"></div>
<div class="relative group">
<a href="#" id="principal_html">
<img class="h-8 w-8 rounded-full" alt="User Profile"
id="principal_image" />
</a>
<div class="hidden group-hover:block absolute z-10 mt-2 w-48 origin-top-right right-2 rounded-md bg-white py-2 shadow-lg ring-1 ring-black ring-opacity-5"
role="menu" aria-orientation="vertical"
aria-labelledby="user-menu-button" tabindex="-1">

<a href="#" class="block px-2 py-2 text-sm text-gray-700 text-left"
role="menuitem" tabindex="-1" id="user-menu-item-0">
<div>
Name:
<span sec:authentication="principal.attributes['name']"></span>
</div>
<div>
ID:
<span sec:authentication="principal.attributes['login']"></span>
</div>
</a>

</div>
</div>
</div>
<div sec:authorize="!isAuthenticated()">
<div class="relative group">
<a href="#" id="principal_html">
<img
class="h-8 w-8 rounded-full"
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
alt=""
/>
</a>
</div>
</div>
Expand Down

0 comments on commit 6b304da

Please sign in to comment.