JPA Repository and Spring-data-rest baseURi is /profile - spring-data-jpa

Just learning springboot (and newish to java: from .NET world)
Too PS course on spring-data and spring-data-rest. All went well
Made a test project connection to MS SQlServer. Created a few JPA Repos and unit tests pass for FindAll
I don't have a base-uri set in app properties and when explore the rest interface (with Postman) everything appears under /profile.
{
"_links": {
"self": {
"href": "http://localhost:8080/profile"
},
"users": {
"href": "http://localhost:8080/profile/users"
},
"tasks": {
"href": "http://localhost:8080/profile/tasks"
}
}
}
first question is, where does /profile come from?

It's not a base path (url). It's a normal work of SDR:
A profile link, as defined in RFC 6906, is a place to include application-level details. The ALPS draft spec is meant to define a particular profile format, which we explore later in this section.
If you navigate into the profile link at localhost:8080/profile, you see content resembling the following:
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/profile"
},
"persons" : {
"href" : "http://localhost:8080/profile/persons"
},
"addresses" : {
"href" : "http://localhost:8080/profile/addresses"
}
}
}
To work with your entities you have to use these links:
http://localhost:8080/users
http://localhost:8080/tasks
By the way you can set 'base path' in three ways:
In 'application.properties`
spring.data.rest.basePath=/api
Registering a bean
#Bean
public RepositoryRestConfigurer repositoryRestConfigurer() {
return new RepositoryRestConfigurerAdapter() {
#Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setBasePath("/api");
}
};
}
With a custom implementation of RepositoryRestConfigurer
#Component
public class CustomizedRestMvcConfiguration extends RepositoryRestConfigurerAdapter {
#Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setBasePath("/api");
}
}

Related

dslContract generated from spring restdocs not working with queryParameters

When i create dslcontracts in my restdoc test with query parameters, it creates the groovy contract file as well as stub file. But when i deploy the contract using #EnableStubRunnerServer, i can never get the query parameters to match.
I realized that the stub file is generated with request looking like:
"request" : {
"url" : "/search",
"method" : "GET",
"queryParameters" : {
"query" : {
"equalTo" : "friday"
}
}
}
However if i change the stub file to :
"request" : {
"urlPathPattern" : "/search",
"method" : "GET",
"queryParameters" : {
"query" : {
"equalTo" : "friday"
}
}
}
it seems to work. Is there a way to make this work?
Here is how i'm writing the test:
#Test
public void searchWithQuery() throws Exception {
Map<String, Object> param = new HashMap<>();
param.put("query", "equalTo(\"friday\")");
mockMvc.perform(get(SEARCH_PATH + "?query=friday"))
.andExpect(status().isOk())
.andDo(document("search-query",
dslContract(param)
));
}

I can't perform a REST request with Sencha

I want to perform a rest request with sencha ext js. Threfore I created a model and a store with a proxy. Then I invoked the load function of the store. The problem is that after the invocation the store is still empty. I know this because I debugged it. This is the code:
var myModel = Ext.create('Ext.data.Model', {
fields: [
{ name: 'name' },
{ name: 'age' }
]
});
var myStore = Ext.create('Ext.data.Store', {
model: myModel,
proxy: {
type: 'rest',
url: 'http://localhost:8080/blablabla',
}
});
myStore.load();
The url 'http://localhost:8080/blablabla' is correct because when I type it in the browser I get the json list of users with the "name" and "age" fields. So the server works.
Here is an example of json that I should get:
[ {
"id" : 1,
"name" : "john",
"age": 40
}, {
"id" : 2,
"name" : "jack",
"age": 30
} ]
My Sencha code was correct. The problem was CORS not enabled. So I resolved by adding #CrossOrigin above my server method.
#CrossOrigin
#RequestMapping
public List<Thing> getThings() {
...
return myListOfThings;
}
#CrossOrigin did the trick.

Spring Boot, Spring Security - Prevent direct URL query of MongoDB

So, I'm working on a Spring Boot Web App that utilizes Spring Security for login authentication. Currently, we have three types of users who get redirected to the appropriate dashboard and when they try to access the other dashboards through a direct URL, they are denied access. Any unauthenticated user is also denied access to the rest of the site. While testing, I had found that once a user had successfully been authenticated, if they were to use a direct URL to "/", or localhost:8080 for testing, instead of being redirected to the login page as they would when not authenticated, a JSON with information of our tables in our MongoDB instance would be returned. Worse, if they appended a table name to the URL, they would receive the entire table in JSON form.
Example: http://localhost:8080/premios (Currently holding dummy values)
{
"_embedded" : {
"premios" : [ {
"title" : "hdlkfjgd",
"description" : "dflgkj",
"points" : 20,
"enabled" : false,
"_links" : {
"self" : {
"href" : "http://localhost:8080/premios/5a013a974833be43fa38dc53"
},
"premio" : {
"href" : "http://localhost:8080/premios/5a013a974833be43fa38dc53"
}
}
}, {
"title" : "dfdggd",
"description" : "dfgd",
"points" : 5,
"enabled" : false,
"_links" : {
"self" : {
"href" : "http://localhost:8080/premios/5a0a11964833be69a480a901"
},
"premio" : {
"href" : "http://localhost:8080/premios/5a0a11964833be69a480a901"
}
}
}, {
"title" : "alksksjlkakjf",
"description" : "sdlkfkjsdlfkj",
"points" : 5,
"enabled" : false,
"_links" : {
"self" : {
"href" : "http://localhost:8080/premios/5a0a12b24833be6a6e47a22a"
},
"premio" : {
"href" : "http://localhost:8080/premios/5a0a12b24833be6a6e47a22a"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/premios{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile/premios"
},
"search" : {
"href" : "http://localhost:8080/premios/search"
}
},
"page" : {
"size" : 20,
"totalElements" : 3,
"totalPages" : 1,
"number" : 0
}
}
How can I prevent this? Is this due to how I have Spring Security set up, or something I need to do on our mLab to only allow controllers on the backend to make queries? The above premios URL is not a defined request method in any of our controllers so I'm not sure why it's working. Here's how it's configured:
WebSecurityConfig.java
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private SimpleAuthenticationSuccessHandler successHandler;
#Autowired
public void configureGlobal(
AuthenticationManagerBuilder auth,
CustomUserDetailsService userDetailsService) throws Exception {
auth
.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http)
throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/images/**", "/script/**").permitAll()
.antMatchers("/signup").permitAll()
.antMatchers("/webapp/admin").hasRole("ADMIN")
.antMatchers("/webapp/sales").hasRole("SALES")
.antMatchers("/webapp/business").hasRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.successHandler(successHandler)
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher(("/logout")))
.logoutSuccessUrl("/login")
.permitAll();
}
}
SimpleAuthenticationSuccessHandler.java
#Component
public class SimpleAuthenticationSuccessHandler implements AuthenticationSuccessHandler{
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
#Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Authentication authentication) throws IOException, ServletException {
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
authorities.forEach(authority -> {
if(authority.getAuthority().equals("ROLE_ADMIN")) {
try {
redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/admin");
} catch (Exception e) {
e.printStackTrace();
}
}
else if(authority.getAuthority().equals("ROLE_SALES")) {
try {
redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/sales");
} catch (Exception e) {
e.printStackTrace();
}
}
else if(authority.getAuthority().equals("ROLE_USER")) {
try {
redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/business");
} catch (Exception e) {
e.printStackTrace();
}
}
else {
throw new IllegalStateException();
}
});
}
}
Maybe, it's something to do with the success handler? I'm new to using Spring Boot and building a Web App so any help is much appreciated!
For anyone with a similar issue, I solved my problem by changing:
.anyRequest().authenticated()
to
.anyRequest().denyAll().
Once a user was authenticated, they were able to make any request of our Web App. By using denyAll, we could prevent all requests that were not specified in our antmatchers. I also modified antmatchers such as this:
.antMatchers("/webapp/business").hasRole("USER")
to
.antMatchers("/webapp/business").access("isFullyAuthenticated() and hasRole('USER')")
And just in case, I made sure to reroute any requests to "/" to our login page "/login".

Camel Rest-DSL (api-doc) - Potential bug

I've been using Rest-DSL (Camel v2.18.1) and trying to set up my own RestOperationResponseMsgDefinition so as to have a useful API doc. By setting a class to the responseModel to tell which object will be returned in case of success, its structure is properly shown in the API doc. However, if I create a class that has that object within, all endpoints which mention it as their outputType/responseModel stop showing the correct structure in the API doc and put "string" instead. Like this:
My outputType/responseModel:
class Address {
private Integer id;
private String descr;
}
API-doc snippet:
"/addresses" : {
"get" : {
"produces" : [ "application/json" ],
"responses" : {
"200" : {
"description" : "Success.",
"schema" : {
"$ref" : "#/definitions/Address"
}
}
...
In Swagger-UI, the response example value is shown as:
{
"id": "string",
"descr": "string"
}
Everything is alright till I create any class having an Address object within! For instance:
class Store {
private Integer id;
private String name;
private Address address;
}
Now, for the same endpoint mentioned before, I get...
"/addresses" : {
"get" : {
"produces" : [ "application/json" ],
"responses" : {
"200" : {
"description" : "Success.",
"schema" : {
"type" : "string",
"format" : "com.mycompany.integration.domain.Address"
}
}
...
And the following in Swagger-UI as example value:
"string"
Has anybody ever passed through and solved this? This seems a bug, though...

mongochef azure document db query issue

I am currently using MongoChef (4.3.0) to access an Azure Document DB (using DocumentDB protocol support for MongoDB).
The data in question is from an Application Insights continuous export has the following type of data within (there is other data there but this is the key part i am interested in...)
{
... other fields ...
"request" : [
{
"name" : "GET /images/loading_man.gif",
"count" : NumberInt(1),
"responseCode" : NumberInt(200),
"success" : NumberInt(1),
"url" : "http://<removed>.cloudapp.azure.com/<something>/images/loading_man.gif"
... other fields ...
}
]
... other fields ...
}
Using MongoChef I can perform some basic query like the following without issue;
{ "request": { $exists: true } }
but anything more complicated seems to return nothing or not run at all
{ "request.0.url": { $exists: true } }
{ "request.0.url": /.*man.*/i }
If I Export this data and Import it to my local MongoDb I am indeed able to perform such searches on the data in question without issue.
Any ideas how I could perform this type of search on the data in question without needing to export it?.
(this is a programming issue, because I want to do the above in a python program!)
Well it looks like all I needed to do was use $elemMatch!
{ "request": { $elemMatch: {url:/.*man.*/i } }}
this is as I understand the recommended way but also 'faster'?