How to exclude Spring Security for Spring Boot Unit Test - unit-testing

Spring Boot version: 2.2.6.RELEASE
#RunWith(SpringRunner::class)
#WebMvcTest(controllers = [IndexController::class])
One thing I would like to do is disable security for the tests.
#WebMvcTest(value = [IndexController::class], secure = false)
and
#AutoConfigureMockMvc(secure = false)
Both of them are do not compile because of secure properties is deprecated.
I do not want mock my security service class in every test
I tried
#WebMvcTest(controllers = [TestController::class], excludeAutoConfiguration = [SecurityConfiguration::class])
and
#WithMockUser
but it doesn't work.
How can I disable security ?

Related

Front end of the notary in cordapp-samples

I want to set up the UI for the notary in cordApp samples. As the notary's Web port is not configured by default,I am trying to change the client's Gradle file to configure the notary.
Is there any other way to configure the notary's UI ?
I checked,It can be seen through the Node Explorer.Is there any other way to check the notary on web front?
You can configure the notary's webport in a similar way as you would configure for any other node.
Your notary must have an RPC address configured.
Once you have an rpc address configured, you can either use the default corda webserver (which is now deprecated) or you must configure your own webserver or use spring-webserver).
Without specifying the web port you can define your spring boot server, and connect to the node via RPC.
Step 1 Define your Spring boot server
#SpringBootApplication
private open class Starter
/**
* Starts our Spring Boot application.
*/
fun main(args: Array<String>) {
val app = SpringApplication(Starter::class.java)
app.setBannerMode(Banner.Mode.OFF)
app.isWebEnvironment = true
app.run(*args)
}
Step 2 Start your server by defining a starter task in your gradle build file
task runPartyAServer(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'net.corda.server.ServerKt'
}
Step 3 Define the rpc configuration used to connect to the node.
server.port=10055
config.rpc.username=user1
config.rpc.password=test
config.rpc.host=localhost
config.rpc.port=10008
Step 4 Connect to the node using the above config defined.
val rpcAddress = NetworkHostAndPort(host, rpcPort)
val rpcClient = CordaRPCClient(rpcAddress)
val rpcConnection = rpcClient.start(username, password)
proxy = rpcConnection.proxy
Step 5 Use the proxy to connect to the notary node.
You can refer to the complete code here.

AWS Java SDK behind a corporate proxy

I want to test my AWS code locally so I have to set a proxy to a AWS client.
There is a proxy host (http://user#pass:my-corporate-proxy.com:8080) set in my environment via a variable HTTPS_PROXY.
I didn't find a way how to set the proxy as whole so I came up with this code:
AmazonSNS sns = AmazonSNSClientBuilder.standard()
.withClientConfiguration(clientConfig(System.getenv("HTTPS_PROXY")))
.withRegion(Regions.fromName(System.getenv("AWS_REGION")))
.withCredentials(new DefaultAWSCredentialsProviderChain())
.build();
ClientConfiguration clientConfig(String proxy) {
ClientConfiguration configuration = new ClientConfiguration();
if (proxy != null && !proxy.isEmpty()) {
Matcher matcher = Pattern.compile("(\\w{3,5})://((\\w+):(\\w+)#)?(.+):(\\d{1,5})").matcher(proxy);
if (!matcher.matches()) {
throw new IllegalArgumentException("Proxy not valid: " + proxy);
}
configuration.setProxyHost(matcher.group(5));
configuration.setProxyPort(Integer.parseInt(matcher.group(6)));
configuration.setProxyUsername(matcher.group(3));
configuration.setProxyPassword(matcher.group(4));
}
return configuration;
}
The whole method clientConfig is only boilerplate code.
Is there any elegant way how to achieve this?
As far as I can tell while using AWS SDK V1 (1.11.840), if you have environment variables such as HTTP(S)_PROXY or http(s)_proxy set at runtime, or properties like http(s).proxyHost, proxyPort, proxyUser, and proxyPassword passed to your application, you don't have to set any of that. It gets automatically read into the newly created ClientConfigiration.
As, such you'd only want to set the ProxyAuthenticationMethod, if needed.
ClientConfiguration clientConfig(ProxyAuthenticationMethod authMethod) {
ClientConfiguration conf = new ClientConfiguration();
List<ProxyAuthenticationMethod> proxyAuthentication = new ArrayList<>(1);
proxyAuthentication.add(authMethod);
conf.setProxyAuthenticationMethods(proxyAuthentication);
return conf;
}
ProxyAuthenticationMethod can be ProxyAuthenticationMethod.BASIC or DIGEST or KERBEROS or NTLM or SPNEGO
I can confirm setting the parameters "http(s).proxyHost" (and others) work out of the box, you need however to specify a port, otherwise AWS SDK (1) will not pick it up.
java -Dhttps.proxyHost=proxy.company.com -Dhttps.proxyPort=8080 -Dhttps.proxyUser=myUsername -Dhttps.proxyPassword=myPassword <app>
Username & passsword are optional.
See for more info:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/doc-files/net-properties.html
and
What Java properties to pass to a Java app to authenticate with a http proxy

Unit Test with spring-boot-starter-test and cassandra

My spring boot web application uses Cassandra DB via the Datastax client and the connection occurs as follow:
public CassandraManager(#Autowired CassandraConfig cassandraConfig) {
config = cassandraConfig;
cluster = Cluster.builder()
.addContactPoint(config.getHost())
.build();
session = cluster.connect(config.getKeyspace());
}
When I run my Unit Tests, the spring boot application tries to load the CassandraManager Bean and connect to the Cassandra DB which is not up for the Unit Test as I do not need it. I get the following error: [localhost/127.0.0.1:9042] Cannot connect)
Is there a way to avoid loading this Cassandra Manager Bean to run my UT as they do not need to connect to the DB ? Is it a good practice to do so ?
You can try something like below which worked for me assuming, you are using spring-data-cassandra
First we create another configuration class which will be used for the tests that does not need cassandra connection. It is required as we need to exlude the CassandraDataAutoConfiguration class. Ex:
#SpringBootApplication(exclude = {CassandraDataAutoConfiguration.class})
public class NoCassandraConfig {
}
Then we will use this configuration on our test(s). Ex:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = NoCassandraConfig.class)
public class UtilitiesTest {
/* Lots of tests that does not need DB connection */
}
And there you go.

unittesting with Azure DocumentDB

I'm interested in using azure's DocumentDB, but I can't see how to sensibly develop, run unittests / integration tests, or how to have our continuous integration server run against it.
AFAICS there's no way to run a local version of the docdb server, you only run against a provisioned instance of docdb in azure.
This means that:
each developer must dev against their own provisioned instance of docdb
each time the developer runs integration tests it's against (their own) remote docdb
continuous integration: I have to assume there's a way to programatically provision another docdb instance for the build? Even then the CI server is running against the remote docdb
Any advice on how people are approaching this with docdb would be much appreciated.
You are correct that there is no version of DocumentDB that you run on your own computers. So, I write unit tests for all stored procedures (sprocs) using documentdb-mock (runs client side on node.js). I do test first design (TDD) with this client side testing which has no requirement for connecting to Azure, but it only tests sprocs.
I run a number of other tests on the live Azure platform. In addition to the client-side tests, I test sprocs live with a real documentdb collection. I also test all client-side SDK code (only used for reads as I do all writes in sprocs) on the live system.
I used to have a single collection per developer for live testing but the fact each test can't guarantee the state of the database meant that some tests failed intermittently, so I switched to creating and deleting a database and collection for each test. It's slightly slower but not as slow as you would expect. I use node-unit and below is my setup and tear down code. Some points about this code:
I preload all sprocs every time since I use sprocs for all writes. I only use the client-side SDK for reads. You could skip this if you don't use sprocs.
I am using the documentdb-utils WrappedClient because it provides some added functionality (429 retry, better async API, etc.). It's a drop in replacement for the standard library (although it does not yet support partitioned collections) but you don't need to use it for the example code below to work.
The delay in the tear down was added to fix some intermittent failures that occurred when the collection was removed but some operations were still pending.
Each test file looks like this:
path = require('path')
{DocumentClient} = require('documentdb')
async = require('async')
{WrappedClient, loadSprocs, getLinkArray, getLink} = require('documentdb-utils')
client = null
wrappedClient = null
collectionLinks = null
exports.underscoreTest =
setUp: (setUpCallback) ->
urlConnection = process.env.DOCUMENT_DB_URL
masterKey = process.env.DOCUMENT_DB_KEY
auth = {masterKey}
client = new DocumentClient(urlConnection, auth)
wrappedClient = new WrappedClient(client)
client.deleteDatabase('dbs/dev-test-database', () ->
client.createDatabase({id: 'dev-test-database'}, (err, response, headers) ->
databaseLink = response._self
client.createCollection(databaseLink, {id: '1'}, {offerType: 'S2'}, (err, response, headers) ->
collectionLinks = getLinkArray(['dev-test-database'], [1])
scriptsDirectory = path.join(__dirname, '..', 'sprocs')
spec = {scriptsDirectory, client, collectionLinks}
loadSprocs(spec, (err, result) ->
sprocLink = getLink(collectionLinks[0], 'createVariedDocuments')
console.log("sprocs loaded for test")
setUpCallback(err, result)
)
)
)
)
test1: (test) ->
...
test.done()
test2: (test) ->
...
test.done()
...
tearDown: (callback) ->
f = () ->
client.deleteDatabase('dbs/dev-test-database', () ->
callback()
)
setTimeout(f, 500)
A local version from a DocumentDB is now available : https://learn.microsoft.com/en-us/azure/documentdb/documentdb-nosql-local-emulator

Grails 2.4.4 Testing for permission where spring security code is being used

I am using spock for may application testing and using Grails 2.4.4. I have done domain, controller, and service unit testing. But in controller sections I am stuck with the role wise access. For authentication I am using Spring Security Core Plugin. Below is my sample code.
#Secured(["IS_AUTHENTICATED_FULLY"])
def index(Integer max) {
}
#Secured(["ROLE_A","ROLE_B"])
def create() {
respond new DomainName(params)
}
#Transactional
#Secured(["ROLE_A","ROLE_B"])
def save(DomainName DomainNameInstance) {
}
How do I test that only the user with ROLE_A and ROLE_B can create and save and other cannot? Also I do I check the user is IS_AUTHENTICATED_FULLY to access index action ?
From your question, it sounds like you are trying to test whether the Spring Security code is working. My take on unit testing controllers is that 'if I didn't write I'm not testing it.' Services used by my controllers are mocked, configuration values used by my controller are mocked. Likewise, Spring Security behaviors are mocked (in effect). This means accepting some amount of risk related to the plugins that you use in your application. Do you trust Spring Security to handle roles and authorities correctly? I generally do.
I'm more interested in the behaviors of my code, so I generally just bypass the spring check in my Unit tests. If you want to verify the behaviors of your application if the user is or is not logged in, or does or does not have a certain role, you can do that.
def "test create method without required role"() {
setup:
// tell Spring to behave as if the user does not have the desired role(s)
SpringSecurityUtils.metaClass.static.ifAllGranted = { String role ->
return false
}
when:
controller.index()
then:
// without the required role, what does the controller return?
controller.response.status == ??
cleanup:
SpringSecurityUtils.metaClass = null
}
def "test create method with required role"() {
setup:
// tell Spring to behave as if the user has the required role(s)
SpringSecurityUtils.metaClass.static.ifAllGranted = { String role ->
return true
}
when:
controller.index()
then:
// with the required role(s), what does the controller return?
controller.response.status == 200
controller.response.mimeType.name == "application/json"
controller.response.getText() == "whatever"
cleanup:
SpringSecurityUtils.metaClass = null
}