Springboot: Unable to access GraphQL server and GraphiQL - java

I am building a multimodule springboot application, I have one module that only does graphql queries and mutations, the challenge am facing is when I try to run the app and query graphql I end up getting 404 not found
{
"timestamp": "2023-01-25T18:25:00.762+00:00",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/graphql"
}
The query am running
query{
retailers{
...allfields
}
}
I am using Netflix graphql. Here Is my configuration
build.gradle.kts file
plugins {
`java-library`
id("app-java-conventions")
id("com.netflix.dgs.codegen")
id("com.google.cloud.tools.jib")
// for jib agent look into https://github.com/GoogleContainerTools/jib/tree/master/examples/java-agent
}
dependencyManagement {
imports {
mavenBom("com.netflix.graphql.dgs:graphql-dgs-platform-dependencies:latest.release")
}
}
dependencies {
implementation(project(":ky-launch-darkly"))
implementation(platform("com.netflix.graphql.dgs:graphql-dgs-platform-dependencies:latest.release"))
implementation("com.netflix.graphql.dgs:graphql-dgs-spring-boot-starter")
implementation("com.netflix.graphql.dgs:graphql-dgs-extended-scalars")
implementation("com.netflix.graphql.dgs:graphql-dgs-subscriptions-websockets-autoconfigure")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.netflix.graphql.dgs:graphql-dgs-spring-boot-starter")
implementation("net.devh:grpc-client-spring-boot-starter:2.13.1.RELEASE")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("net.datafaker:datafaker:1.7.0")
}
my folder structure looks like this for graphql schema
Am using keycloak for authentication but I have permitted access to all graphql endpoints
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/**").permitAll()
.and()
.requestCache()
.requestCache(new NullRequestCache())
.and()
.headers()
.frameOptions().sameOrigin() // needed for H2 web console
.and()
.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.sessionRegistry(sessionRegistry());
}
I have a data resolver for the graphql
#DgsComponent
public class RetailerDataResolver {
#DgsQuery
public List<Retailer> retailers(){
return RetailerDatasource.RETAILER_LIST;
}
}
what could I be doing wrong on my app such that I cant access graphql?

Related

spring boot end point works with browser but not with postman

I am new to spring security, I have written test endpoint with google oauth2, I can authencitace with web browser and my end point works, but not working with postman,
here is my properties
spring.security.oauth2.client.registration.google.client-id={{CLIENT_ID}}
spring.security.oauth2.client.registration.google.client-secret={{SECRET}}
spring.security.oauth2.client.registration.google.scope=openid,profile,email
Here is my controller
#RestController
public class UserController {
#GetMapping()
public String get() {
return "testing java 18";
}
}
Here is my security config
#Configuration
#EnableWebSecurity(debug = true)
public class SecurityConfig {
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
return http.build();
}
}
with above configuration, if I test http://localhost:8080 on browser it redirects to google signing and the text testing java 18 appears.
But when I use postman with below config
Type: `OAuth 2.0`
Add authorization to data to: `Request Header`
Configure New Token:
Token Name: {{SOME_RANDOM_NAME}}
Grant Type: `Authorization Code`
Callback URL: `https://oauth.pstmn.io/v1/callback`
Auth URL: `https://accounts.google.com/o/oauth2/auth`
Access Token URL: `https://oauth2.googleapis.com/token`
Client ID: `{{CLIENT_ID}}` same used in application.properties
Client Secret: `{{CLIENT_SECRET}}` same used in application.properties
Scope: `profile email openid`
State: empty
Client Authentication: `Send as basic auth header`
With above if I hit Get New Access Token, I do get new Access Token and id_token with google signing, after I hit Use Token I and send GET on the endpoint I get 403
Also If I use id_token and change Type to Bearer Token I get the same.
with older version If I use below Securityy config, Endpoint works when I send my id_token as Type to Bearer Token
#Configuration
#EnableWebSecurity(debug = false)
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/**").fullyAuthenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.oauth2ResourceServer().jwt();
}
}
I tried searching in the forum but didn't; got much.

spring boot oauth2 feign allow anonymous requests

I have a client service that distribute a single page application. All the requests from the single page app pass through the client service that uses proxies (Feign) to redirect the calls.
I'd like to allow anonymous calls but I'm not able to do that with my current configuration.
So to make it simpler I have three services : a client, an oauth2 server and an oauth2 resource server.
The oauth2 server is also a resource server.
The client is connected to the oauth2-server with this configuration
security:
oauth2:
client:
clientId: autorisation_code_client
clientSecret: *******
accessTokenUri: https://localhost:****/oauth2-server/oauth/token
userAuthorizationUri: https://localhost:****/oauth2-server/oauth/authorize
#tokenCheckUri: https://localhost:****/oauth2-server/oauth/check_token
resource:
userInfoUri: https://localhost:****/oauth2-server/me
Here is the WebSecurityConfigurerAdapter class of the client, when an user try to access to the login path he's redirected to the oauth2-server to authenticate himself.
#Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers(
"/",
"/index.html",
"/login**",
"/logout**",
//resources
"/assets/**",
"/static/**",
"/*.ico",
"/*.js",
"/*.json").permitAll()
.anyRequest()
.authenticated()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class);
}
The feign proxy used by the client, I'd like to configure the oauth2-server/user/like/*** path to be accessible by anonymous users.
#RestController
#FeignClient(name = "oauth2-server", url = "https://localhost:****")
public interface ProxyOauth2Server {
#GetMapping(value = "oauth2-server/user/like/{name}")
ResponseEntity<?> getUserLikeName(#PathVariable("name") String name);
}
To transmit the token through Feign I have this configuration in the client Main class.
#EnableConfigurationProperties
#SpringBootApplication
#EnableFeignClients("com.tutosharing.client.proxies")
public class ClientUiApplication {
#Autowired
private SecurityPropertiesConfig config;
#Bean
protected OAuth2ProtectedResourceDetails resource() {
AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
resource.setAccessTokenUri(config.getAccessTokenUri());
resource.setUserAuthorizationUri(config.getUserAuthorizationUri());
resource.setClientId(config.getClientId());
resource.setClientSecret(config.getClientSecret());
return resource;
}
#Bean
public RequestInterceptor oauth2FeignRequestInterceptor(OAuth2ClientContext oauth2ClientContext,
OAuth2ProtectedResourceDetails resource) {
return new OAuth2FeignRequestInterceptor(oauth2ClientContext, resource);
}
}
Now the oauth2 server which also serves as a resource server
#SpringBootApplication
#EnableResourceServer
#EnableAuthorizationServer
#EnableConfigurationProperties
public class AuthorizationServerApplication {}
the oauth2 server WebSecurityConfigurerAdapter class
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.antMatchers("/",
"/login",
"/login.do",
"/oauth/authorize**")
.and()
.authorizeRequests()
.antMatchers(
"/",
"/login",
"/login.do")
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login.do")
.usernameParameter("*********")
.passwordParameter("*********")
.and()
.userDetailsService(userDetailsServiceBean())
.requiresChannel()
.anyRequest()
.requiresSecure();
}
}
The Rest controler method I'd like to allow to anonymous users
#RestController
public class UserRControllerRest {
#GetMapping({"/user/like/{name}"})
#JsonView(View.SimpleUser.class)
#PreAuthorize("hasRole('ROLE_USER')")
public ResponseEntity getUserLikeName(#PathVariable String name) {
Set<AuthUser> users = this.userRepository.findByNameLike(name);
return new ResponseEntity(users, HttpStatus.OK);
}
}
If I configure the Rest method with #PreAuthorize("hasRole('ROLE_ANONYMOUS')")
and the WebSecurityConfigurerAdapter like this
http.requestMatchers()
.antMatchers(
...
"/user/like/**",
...)
.and()
.authorizeRequests()
.antMatchers("/user/like/**")
.anonymous()
...
}
} // #formatter:on
I'm able to get an answer if I contact directly the oauth2-server with Postman, but not if I pass through the client service that uses Feign, I'm always redirected to the login page.
So how can I allow anonymous request Through Feign ?
I've found a solution but I'm not sure this is the Best way. So if you have another solution you are welwome.
So far I used this configuration to get the Token from the oauth2-server anytime an user made a request from the client through Feign.
#Bean
protected OAuth2ProtectedResourceDetails resource() {
AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
resource.setAccessTokenUri(config.getAccessTokenUri());
resource.setUserAuthorizationUri(config.getUserAuthorizationUri());
resource.setClientId(config.getClientId());
resource.setClientSecret(config.getClientSecret());
return resource;
}
#Bean
public RequestInterceptor oauth2FeignRequestInterceptor(#Qualifier("oauth2ClientContext") OAuth2ClientContext oauth2ClientContext,
OAuth2ProtectedResourceDetails resource) {
return new OAuth2FeignRequestInterceptor(oauth2ClientContext, resource);
}
The problem with that configuration is that anytime I made a request with Feign a request is sent to the oauth2-client to the /oauth/authorize endpoint. But if the user is not connected it fails, so an unauthenticated user cannot make any request from the client service.
So I used another RequestInterceptor.
#Bean
public RequestInterceptor requestTokenBearerInterceptor() {
return requestTemplate -> {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (!principal.equals("anonymousUser")) {
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)
SecurityContextHolder.getContext().getAuthentication().getDetails();
requestTemplate.header("Authorization", "bearer " + details.getTokenValue());
}
};
}
This way the token that the client service already has, once the user is connected, is added to the request whitout making another request to the /oauth/authorize endpoint. I think the token is sent with every request, I don't think it's a good practice for security matters.
Also in the WebSecurityConfigurerAdapter classes of the client-server I need to add the path so that it is accessible to non-connected users
http.antMatcher("/**")
.authorizeRequests()
.antMatchers(
"/oauth2-server/user/like/**",
...)
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
...;
same for the oauth2-server
http.antMatcher("/**")
.authorizeRequests()
.antMatchers(
"/user/like/**",
...)
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
...;
With that configuration an unauthenticated user can make a request to an unprotected endpoint.

How to handle and custom error 401 from Spring boot ldap?

I'm working in an application that uses Spring secutiry LDAP to authenticate its users, the authentication is working fine, my problem is that if someone try to log in with unauthorized credentials, the application sends immediatly a error 401, and I don't want that, I want to custom some friendly message to show this user, but even in debug I can't find where the application executes de authentication, it even seems that my backend isn't called, how can I custom this exception ?
Here's my configuration on my Security configuration class:
#Configuration
#Order(2147483640)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and()
.cors().and()
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers(HttpMethod.GET, "/**").permitAll()
.antMatchers(HttpMethod.POST, "/**").permitAll()
.antMatchers(HttpMethod.PUT, "/**").permitAll()
.antMatchers(HttpMethod.DELETE, "/**").permitAll()
.antMatchers("/**").permitAll();
}
#Configuration
protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
#Autowired
private UsrPessoaService usrPessoaService;
#Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication().userDetailsContextMapper(usrPessoaService)
.userDnPatterns("secret")
.groupSearchBase("secret")
.contextSource()
.root("secret")
.url("secret").port(000);
System.out.println(auth.toString());
}
}
}
Thanks in advance for any help !
Have you considered a WhiteLabel Page?
For example:
https://www.baeldung.com/spring-boot-custom-error-page
#RequestMapping("/error")
public String handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
Integer statusCode = Integer.valueOf(status.toString());
if(statusCode == HttpStatus.NOT_FOUND.value()) {
return "error-404";
}
else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return "error-500";
}
}
return "error";
}
And an example "error.html" template:
<!DOCTYPE html>
<html>
<body>
<h1>Page not found</h1>
<h2>Sorry, we couldn't find the page you were looking for</h2>
Go Home
</body>
</html>
ADDENDUM:
Since the OP has an Angular front end, these links might also be applicable:
Tutorial: Spring Security and Angular.
In this tutorial we show some nice features of Spring Security, Spring
Boot and Angular working together to provide a pleasant and secure
user experience.
It should be accessible to beginners with Spring and Angular, but
there also is plenty of detail that will be of use to experts in
either.
See also:
https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/security/web/AuthenticationEntryPoint.java

Postman 403 Forbidden message

I made some api with REST Spring. GET request works fine in Postman but when I try to do POST request I receive this error :
{
"timestamp": "2018-09-25T06:39:27.226+0000",
"status": 403,
"error": "Forbidden",
"message": "Forbidden",
"path": "/cidashboard/projects"
}
This is my controller :
#RestController
#RequestMapping(ProjectController.PROJECT_URL)
public class ProjectController {
public static final String PROJECT_URL = "/cidashboard/projects";
private final ProjectService projectService;
public ProjectController(ProjectService projectService) {
this.projectService = projectService;
}
#GetMapping
List<Project> getAllProjects(){
return projectService.findAllProjects();
}
#GetMapping("/{id}")
Project getProjectById(#PathVariable int id) {
return projectService.findProjectById(id);
}
#PostMapping
void addProject(#RequestBody Project newProject) {
projectService.saveProject(newProject);
}
}
Security configuration
initial I wanted to work with ldap, but in my application properties i left only the conection at database....................................................................................................................................................
#EnableGlobalMethodSecurity
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**").permitAll();
// .anyRequest().fullyAuthenticated();
// .and()
// .formLogin().loginPage("/login").permitAll()
// .failureUrl("/login-error");
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource(contextSource())
.passwordCompare()
//.passwordEncoder(new LdapShaPasswordEncoder())
.passwordAttribute("userPassword");
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/static/**"); // #3
}
#Bean
public DefaultSpringSecurityContextSource contextSource() {
return new DefaultSpringSecurityContextSource(Arrays.asList("ldap://localhost:8389/"), "dc=springframework,dc=org");
}
}
Enable spring security with #EnableWebSecurity usage.By default enables csrf support, you have to disable it to prevent Forbidden errors.
#Override
protected void configure(HttpSecurity http) throws Exception {
http //other configure params.
.csrf().disable();
}
PS: 415 unsupported type --> add to your mapping like this annotation for which type of data is sending from Postman.
#PostMapping(consumes = "application/json")
void addProject(#RequestBody Project newProject) {
projectService.saveProject(newProject);
}
In case you want to solve this issue without compromising security, you can send the xsrf-token with your request in postman.
Create a new environment in Postman (e.g. "local").
Create a new variable in this environment (e.g. "xsrf-token")
Go back to your request and make sure the right environment is selected on the top right corner ("local" in this case)
In your POST request, add a header with key "X-XSRF-TOKEN" and value "{{csrf-token}}"
In the "tests" tab, add following code:
var xsrfCookie = pm.cookies.get('XSRF-TOKEN')
pm.environment.set("xsrf-token", xsrfCookie)
The first time you make this request, you will still get a 403, but you'll also receive a cookie with the xsrf-token. The script will copy this token in the environment variable and the next requests you'll make use the appropriate token.
Check the "User-Agent" included in Headers section, If not add the "User-Agent" field
I I was also getting the same error. I found the solution using a different application, not postman {Insomnia REST Client}.
When I went back to postman after wondering, I realized that it is related to permissions in spring security. So after setting the permissions it will work.

How to protect AngularJS partials pages with Spring Security

I'm working on a Spring MVC web app and I'm using AngularJS, I want to protect my views based on roles, example if I login with and admin role I can watch the delete users partial page, and if I login with user role I can't watch the delete user partial page.
I knew how to do this with spring security but with a normal web app not with a restful Single page app with angularJS, since with angular you are not really requesting a view from the server instead you just load a partial html page in a ng-view tag.
I'm also using ngRoute to route my partials.
Here is my ngRoute.jS file
angular.module('MyApp')
.config(['$routeProvider', 'USER_ROLES' ,function ($routeProvider, USER_ROLES) {
$routeProvider.
when('/', {
templateUrl: '/SpringMVCTemplateAnn/resources/angular/templates/dashboardTemplates/dashboardTemplate.html',
controller: 'DashBoardCtrl',
access: {
loginRequired: true,
authorizedRoles: [USER_ROLES.all]
}
}).
when('/login', {
templateUrl: '/SpringMVCTemplateAnn/resources/angular/templates/loginTemplate/login.html',
controller: 'LoginController',
access: {
loginRequired: false,
authorizedRoles: [USER_ROLES.all]
}
}).
when('/createUser', {
templateUrl: '/SpringMVCTemplateAnn/views/partials/userTemplates/createUser.html',
controller: 'UserCtrl'
}).
when('/deleteUser', {
templateUrl: '/SpringMVCTemplateAnn/views/partials/userTemplates/deleteUser.html',
controller: 'UserCtrl'
}).
}]);
here is my spring security configuration I'm using java annotation configuration, I have adapted the configuration to convert it so it could fit a rest application
this is my Security class that extends WebSecuirtyConfigureAdapter
public class SegurityConfig extends WebSecurityConfigurerAdapter {
public SegurityConfig() {
super();
}
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private RestUnauthorizedEntryPoint restAuthenticationEntryPoint;
#Autowired
private AccessDeniedHandler restAccessDeniedHandler;
#Autowired
private AuthenticationSuccessHandler restAuthenticationSuccessHandler;
#Autowired
private AuthenticationFailureHandler restAuthenticationFailureHandler;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**", "/index.jsp", "/login.jsp",
"/template/**", "/", "/error/**");
}
//
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers("/failure").permitAll()
.antMatchers("/v2/api-docs").hasAnyAuthority("admin")
.antMatchers("/users/**").hasAnyAuthority("admin")
.antMatchers("/views/partials/userTemplates/createUser.html").access("hasRole('create users')")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.accessDeniedHandler(restAccessDeniedHandler)
.and()
.formLogin()
.loginProcessingUrl("/login")
.successHandler(restAuthenticationSuccessHandler)
.failureHandler(restAuthenticationFailureHandler)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
.deleteCookies("JSESSIONID")
.permitAll()
.and();
}
}
I'm also using the http-auth-interceptor plugin for angularjs
here is MyApp module
angular.module('MyApp', ['ngRoute', 'ui.bootstrap', 'smart-table', 'http-auth-interceptor']);
and here is my js file that prevents users for navigating the site without being authenticated
angular.module('MyApp')
.run(function ($rootScope, $location, $http, AuthSharedService, Session,
USER_ROLES, $q, $timeout) {
$rootScope.$on('$routeChangeStart', function (event, next) {
if (next.originalPath === "/login" && $rootScope.authenticated) {
event.preventDefault();
console.log('registrese');
} else if (next.access && next.access.loginRequired && !$rootScope.authenticated) {
event.preventDefault();
$rootScope.$broadcast("event:auth-loginRequired", {});
} else if (next.access && !AuthSharedService.isAuthorized(next.access.authorizedRoles)) {
event.preventDefault();
$rootScope.$broadcast("event:auth-forbidden", {});
}
});
// Call when the the client is confirmed
$rootScope.$on('event:auth-loginConfirmed', function (event, data) {
console.log('login confirmed start ' + data);
$rootScope.loadingAccount = false;
var nextLocation = ($rootScope.requestedUrl ? $rootScope.requestedUrl : "/home");
var delay = ($location.path() === "/loading" ? 1500 : 0);
$timeout(function () {
Session.create(data);
$rootScope.account = Session;
$rootScope.authenticated = true;
$location.path(nextLocation).replace();
}, delay);
});
// Call when the 401 response is returned by the server
$rootScope.$on('event:auth-loginRequired', function (event, data) {
if ($rootScope.loadingAccount && data.status !== 401) {
$rootScope.requestedUrl = $location.path()
$location.path('/loading');
} else {
Session.invalidate();
$rootScope.authenticated = false;
$rootScope.loadingAccount = false;
$location.path('/login');
}
});
// Call when the 403 response is returned by the server
$rootScope.$on('event:auth-forbidden', function (rejection) {
$rootScope.$evalAsync(function () {
$location.path('/error/403').replace();
});
});
});
and here is my USER_ROLES constant js file
angular.module('MyApp')
.constant('USER_ROLES', {
all: '*',
admin: 'admin',
user: 'user'
});
I want to protect my partials pages if I login with a user that have the normal user role I want to be able to not watch the delete or create users partial page,
I tried moving my partials outside of the resources folder and putting this in my secuirty class .antMatchers("/views/partials/userTemplates/createUser.html").access("hasRole('create users')") but what this does if that it blocks the partial even if I login with a user that have that role I still get the 403 error, I would like to this to happen but if I login with a user that doesn't have that role but why this happens when I login with a user that have the role is like it doesn't recognize that I have that role.
Is there a way to protect those partials based on roles like in a normal web app because that config worked in a normal web app that I worked but it looks like it doesn't work in a Single page rest app.
If it possible to protect those partials from the server side, I know that I can protect my Rest methods in the server-side using #PreAuthorize("hasRole('create users')") but is there a way to put like an .antMatchers("/my partials/**").hasAnyAuthority("admin") or something similar in the security config class to protect the partials?
My folder structure
SpringMVCProject
--Web-Pages
--WEB-INF
--resources
--angular
--controllers
userController.js
--services
userService.js
--partials
--userPartials
deleteuser.html
app.js
permissionConstants.js
routes.js
--css
--views
--partials (I experimented putting this the folder but I 403 error)
--userpartials
deleteuser.html
index.html
--Source Packages
--controllers
--userControllers
UserController.java
--secuirty
SecuirtyConfig.java

Categories