Azure CLI SSH Config

Update 2023-09-15 Using Control Master This is my preferred approach now, as it is simple to use, and doesn’t come with the added security issues of having authentication keys lying around. It utilises an SSH capability called ControlMaster, which multiplexes multiple SSH sessions over the same connection. Only the initial connection requires authentication, then, all subsequent SSH or SCP calls to the same account+host will use the authenticated connection. Step 1 is to setup you SSH to use ControlMaster. In ~/.ssh/config add ...

October 2, 2021 · Nigel Sim

Spring Security audit events not firing

TL;DR The classes that publish the AuditEvent object are instantiated by AuditAutoConfiguration which is conditional on an AuditEventRepository. If you don’t want to store the events, e.g., in an InMemoryAuditEventRepository, then you need to either: 1) manually instantiate AuthenticationAuditListener and AuthorizationAuditListener, or 2) listen for AbstractAuthorizationEvent and build up from there. The Slightly Longer Version There are a lot of articles on the web about how you can get Spring Security audit events simply by including the spring-boot-starter-actuator artifact, and then creating a listener. ...

February 17, 2021 · Nigel Sim

Extracting TOTP from Authenticator Plus

Authenticator Plus has stated failing in recent version of Android, and appears to be no longer maintained. Specifically, the Google Backup, and the export functions no longer works. This article covers how to extract the TOTP codes from the app and import them into another app. jonasjancarik has provided a Dockerised solution to this. The rest of the post will remain for historical purposes.` TL;DR Backup the database Copy it off the phone to your computer ...

January 15, 2021 · Nigel Sim

Migrating from ModelMapper to Map Struct

TL;DR I’ve built many applications that have used ModelMapper for projecting from one object structure to another, and it has been very good for getting up and running quickly. However, it costs in terms of type safety, and startup performance. So, I’ve switched to a type safe, compile time alternative MapStruct. This article mainly covers the pros and cons of each framework, not how to use them in real projects, or best practises. There are plenty of other articles on the web covering these topics. ...

December 1, 2020 · Nigel Sim

Spring Boot Web Services Client with Jib

When it comes to building a SOAP web services client using Spring, the guide suggests using an Ant based gradle build task to generate the required classes. However, if you are using Jib to produce a Docker container, you may find that the generated classes are not in the container, and there are few guides as to how to get them in there. It looks something like this: ... task genJaxb { ext.sourcesDir = "${buildDir}/generated-sources/jaxb" ext.classesDir = "${buildDir}/classes/jaxb" ext.schema = "http://localhost:8080/ws/countries.wsdl" outputs.dir classesDir doLast() { project.ant { taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask", classpath: configurations.jaxb.asPath mkdir(dir: sourcesDir) mkdir(dir: classesDir) xjc(destdir: sourcesDir, schema: schema, package: "com.example.consumingwebservice.wsdl") { arg(value: "-wsdl") produces(dir: sourcesDir, includes: "**/*.java") } javac(destdir: classesDir, source: 1.8, target: 1.8, debug: true, debugLevel: "lines,vars,source", classpath: configurations.jaxb.asPath) { src(path: sourcesDir) include(name: "**/*.java") include(name: "*.java") } copy(todir: classesDir) { fileset(dir: sourcesDir, erroronmissingdir: false) { exclude(name: "**/*.java") } } } } } ... The crux of the issue is getting the generated classes onto the main source set so that Jib will package them up. I’m not a Gradle expert, so while there may be a way to make this happen with this setup, the neater solution appeared to be to us the XJC Gradle Plugin which takes care of a lot of this automatically. ...

October 18, 2020 · Nigel Sim

UI-Router with ngx-bootstrap tabs

This is a very quick run through of one approach to using a UI-Router with Angular 10 to manage the state of the ngx-bootstrap tabs. The basic approach has two parts: The router config that encodes the state in a known way, and A directive that integrates with the tab directive. The UI-router state is setup to take encode the tab identifier as a parameter in the URL. It is also configured to pass the new router value into the component, as opposed to replacing the component which is the default behaviour. This is done using the dynamic property: ...

August 1, 2020 · Nigel Sim

Spring Security Config - One Minute Overview

The common way to configure Spring Security is by extending WebSecurityConfigurerAdapter and annotating with @Configuration. e.g., from the Java docs: @Configuration class SimpleSecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/**").hasRole("USER").and().formLogin() .and() .logout().deleteCookies("remove").invalidateHttpSession(false) .logoutUrl("/custom-logout").logoutSuccessUrl("/logout-success"); } } If you need to have multiple configurations, for instance, for different paths, then you can either http.antMatchers(...), or you can provide multiple configurations. But these achieve different things, and this distinction needs to be understood. ...

July 15, 2020 · Nigel Sim

Prevent Angular overriding the default form behaviour

In Angular 8/9 the default behaviour is to take control of all <form> elements within the view hierarchy. This can be see by looking at the selector for the form directive. @Directive({ selector: 'form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]', providers: [formDirectiveProvider], host: {'(submit)': 'onSubmit($event)', '(reset)': 'onReset()'}, outputs: ['ngSubmit'], exportAs: 'ngForm' }) When the Angular Form directive is controlling a <form> element it is not possible to do a generic form POST. For instance, if you want to redirect to a third party payment service, which requires you to POST to the server to setup a session, and then redirect the current browser session. ...

May 10, 2020 · Nigel Sim

Static Website Hosting with Docker and Salt

Containerisation of services has numerous advantages in terms of repeatability, security, etc. This is all well and good for an application server and related infrastructure, but how to do this in a light weight fashion, for instance, serving static websites? The ultimate goal is to be able to leverage the benefits of modern devops with low overhead. This blog is hosted on a VPS with 1GB RAM for instance. To do this we utilises: ...

April 7, 2020 · Nigel Sim

Calculating the resulting colour

This is a simple Python application that calculate the resulting hex colour from a foreground colour, background colour, and opacity. This has been useful when writing templates using Flying Saucer which doesn’t support opacity, so we need to calculate final values manually. e.g.: $ python rgba.py a9b421 99e0b2 0.5 #a1ca69 Now, if only this was a handy webpage…

December 18, 2019 · Nigel Sim