Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f54ba38
Release/3.2 (#28)
dominicwest Sep 6, 2023
c74f374
Release/3.3 (#39)
dylanwrightCO Sep 28, 2023
b940900
Release/3.6 (#47)
dominicwest Oct 17, 2023
a4c6d94
Merge branch 'main' into release/4.0
GavCookCO Nov 9, 2023
c6a3198
Create DUMMY
GavCookCO Nov 9, 2023
1fb9a9a
Merge pull request #64 from cabinetoffice/release/4.0
GavCookCO Nov 9, 2023
c78a8d7
Merge branch 'main' into release/5.0
jgunnCO Nov 13, 2023
c08f05b
Merge pull request #69 from cabinetoffice/release/5.0
dominicwest Nov 15, 2023
ee6a598
Tmi2 501/revert tmi2 496 changes (#129) (#130)
a-lor-cab Dec 6, 2023
e1bfdc5
Merge pull request #122 from cabinetoffice/release/6.0
dominicwest Dec 6, 2023
3320f82
Release/6.1 (#136)
ConnorTCO Dec 12, 2023
bc90f4a
Merge branch 'main' into release/7.0
iaincooper-tco Jan 12, 2024
3dba5f3
Merge pull request #151 from cabinetoffice/release/7.0
iaincooper-tco Jan 17, 2024
fc3b4a7
Merge pull request #159 from cabinetoffice/release/8.0
dylanwrightCO Feb 7, 2024
fd69ec0
Fix promoteToProd.yml (#179)
dominicwest Feb 7, 2024
b4cc5d7
Merge branch 'main' into release/9.0
dominicwest Feb 23, 2024
4f5b3dd
Adds query to find application with no ownership check to allow lambd…
dylanwrightCO Feb 26, 2024
e297c35
Merge pull request #208 from cabinetoffice/release/9.0
dominicwest Feb 28, 2024
f5edb8b
Fix unpublish application form from lambda (#268) (#269)
dominicwest Mar 27, 2024
aa3b8c8
Merge branch 'main' of github.com:cabinetoffice/gap-find-admin-backen…
dylanwrightCO Mar 27, 2024
b3ef752
Updating release 10.0 with develop changes (#274)
dominicwest Apr 1, 2024
eb512bd
Merge branch 'develop' into release/10.0
jgunnCO Apr 2, 2024
54e1ef9
GAP-2533: Retrospectively fix BST ads in prod (#276) (#278)
dominicwest Apr 2, 2024
9c6405a
Merge pull request #267 from cabinetoffice/release/10.0
dylanwrightCO Apr 2, 2024
535af9a
Improves logs around updating and deleting open search (#280)
dylanwrightCO Apr 9, 2024
7dcfc0b
Merge pull request #281 from cabinetoffice/release/10.1
dylanwrightCO Apr 9, 2024
f72f649
Improving logging (#283)
GavCookCO Apr 10, 2024
24d4b57
Improving logging II
GavCookCO Apr 10, 2024
51b9e44
Merge pull request #284 from cabinetoffice/release/10.2
GavCookCO Apr 10, 2024
f275c32
Merge branch 'main' into release/11.0
jgunnCO Apr 29, 2024
f057aa7
Merge branch 'develop' into release/11.0
jgunnCO Apr 30, 2024
29d600e
Merge branch 'develop' into release/11.0
jgunnCO Apr 30, 2024
16b0599
amend schemeeditorcontroller
jgunnCO May 1, 2024
f1c7f32
Merge branch 'feature/GAP-2619-3' into release/11.0
jgunnCO May 1, 2024
49c2ae2
Merge pull request #299 from cabinetoffice/release/11.0
ConorFayleTCO May 1, 2024
54a13de
Release/12.0 (#308)
arul-fourseals Aug 12, 2024
35616fa
Release/12.3 (#310)
arul-fourseals Jan 9, 2025
e8ec48f
release/12.4 (#313)
BenExile Jun 3, 2025
a4be0bc
Release/test deployments main (#317)
rmohammed-goaco Nov 19, 2025
ff9697d
Implement idempotency check for spotlight submissions in SpotlightBat…
rmohammed-goaco Jan 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/feature.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
--disableRetireJS true

- name: Upload Test results
uses: actions/upload-artifact@master
uses: actions/upload-artifact@v4
with:
name: DependencyCheck report
path: ${{github.workspace}}/reports
6 changes: 3 additions & 3 deletions .github/workflows/pushImage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
--enableRetired
--disableOssIndex true
- name: Upload Test results
uses: actions/upload-artifact@master
uses: actions/upload-artifact@v4
with:
name: DependencyCheck report
path: ${{github.workspace}}/reports
Expand Down Expand Up @@ -110,7 +110,7 @@ jobs:
run: docker save --output ${{ steps.docker-image-name.outputs.name }}.tar $ECR_REGISTRY/gap-apply-admin-backend:${{ env.BUILD_VERSION }}

- name: Upload Docker image
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ steps.docker-image-name.outputs.name }}
path: ${{ steps.docker-image-name.outputs.name }}.tar
Expand Down Expand Up @@ -148,7 +148,7 @@ jobs:
echo BUILD_VERSION is ${{ env.BUILD_VERSION }}

- name: Download Docker image
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: ${{ needs.build.outputs.docker-image-name }}

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
<version>2.19.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ public ResponseEntity<String> getHealthCheck() {
return ResponseEntity.ok("Service up");
}

@GetMapping("/check")
public ResponseEntity<String> getHealthCheck2() {
return ResponseEntity.ok("Admin API Service up");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public ResponseEntity<List<SchemeEditorsDTO>> getSchemeEditors(@PathVariable fin
@PostMapping
public ResponseEntity<String> addEditorToScheme(@PathVariable final Integer schemeId, @RequestBody @Valid final SchemeEditorPostDTO newEditorDto, final HttpServletRequest request) {
final String jwt = HelperUtils.getJwtFromCookies(request, userServiceConfig.getCookieName());
schemeEditorService.addEditorToScheme(schemeId, newEditorDto.getEditorEmailAddress(), jwt);
schemeEditorService.addEditorToScheme(schemeId, newEditorDto.getEditorEmailAddress().toLowerCase(), jwt);
return ResponseEntity.ok("Editor added to scheme successfully");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,42 +31,54 @@ public WebSecurityConfig(final UserService userService, final JwtTokenFilterConf
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

//if you add a path which is hit by the lambda, remember to update also the paths in gov/cabinetoffice/gap/adminbackend/config/LambdasInterceptor.java
// if you add a path which is hit by the lambda, remember to update also the
// paths in gov/cabinetoffice/gap/adminbackend/config/LambdasInterceptor.java
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and()
.authorizeHttpRequests(auth -> auth
.mvcMatchers("/login",
"/health",
"/health/check",
"/emails/sendLambdaConfirmationEmail",
"/users/validateAdminSession",
"/submissions/{submissionId:" + UUID_REGEX_STRING
+ "}/export-batch/{batchExportId:" + UUID_REGEX_STRING + "}/submission",
+ "}/export-batch/{batchExportId:"
+ UUID_REGEX_STRING + "}/submission",
"/submissions/*/export-batch/*/status",
"/submissions/{submissionId:" + UUID_REGEX_STRING + "}/export-batch/{batchExportId:"
"/submissions/{submissionId:" + UUID_REGEX_STRING
+ "}/export-batch/{batchExportId:"
+ UUID_REGEX_STRING + "}/s3-object-key",
"/grant-export/{exportId:" + UUID_REGEX_STRING + "}/outstandingCount",
"/grant-export/{exportId:" + UUID_REGEX_STRING + "}/failedCount",
"/grant-export/{exportId:" + UUID_REGEX_STRING + "}/remainingCount",
"/grant-export/{exportId:" + UUID_REGEX_STRING + "}/completed",
"/grant-export/{exportId:" + UUID_REGEX_STRING + "}/batch/status",
"/grant-export/{exportId:" + UUID_REGEX_STRING + "}/batch/s3-object-key",
"/grant-advert/lambda/{grantAdvertId:" + UUID_REGEX_STRING + "}/publish",
"/grant-advert/lambda/{grantAdvertId:" + UUID_REGEX_STRING + "}/unpublish",
"/grant-export/{exportId:" + UUID_REGEX_STRING
+ "}/outstandingCount",
"/grant-export/{exportId:" + UUID_REGEX_STRING
+ "}/failedCount",
"/grant-export/{exportId:" + UUID_REGEX_STRING
+ "}/remainingCount",
"/grant-export/{exportId:" + UUID_REGEX_STRING
+ "}/completed",
"/grant-export/{exportId:" + UUID_REGEX_STRING
+ "}/batch/status",
"/grant-export/{exportId:" + UUID_REGEX_STRING
+ "}/batch/s3-object-key",
"/grant-advert/lambda/{grantAdvertId:"
+ UUID_REGEX_STRING + "}/publish",
"/grant-advert/lambda/{grantAdvertId:"
+ UUID_REGEX_STRING + "}/unpublish",
"/users/migrate",
"/users/delete",
"/users/tech-support-user/**",
"/users/admin-user/**",
"/users/funding-organisation",
"/application-forms/lambda/**",
"/feedback/add"
)
"/feedback/add")
.permitAll()
.antMatchers("/v3/api-docs/**",
"/swagger-ui/**",
"/swagger-resources/**",
"/swagger-ui.html",
"/webjars/**")
.permitAll()
.antMatchers("/spotlight-submissions/{spotlightSubmissionId:" + UUID_REGEX_STRING + "}")
.antMatchers("/spotlight-submissions/{spotlightSubmissionId:"
+ UUID_REGEX_STRING + "}")
.permitAll()
.antMatchers("/spotlight-batch/status/**",
"/spotlight-batch",
Expand All @@ -77,7 +89,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.anyRequest()
.authenticated())

.formLogin().disable().httpBasic().disable().logout().disable().csrf().disable().exceptionHandling()
.formLogin().disable().httpBasic().disable().logout().disable().csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));

http.addFilterAfter(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,18 @@ public SpotlightBatch addSpotlightSubmissionToSpotlightBatch(SpotlightSubmission
UUID spotlightBatchId) {
final SpotlightBatch spotlightBatch = getSpotlightBatch(spotlightBatchId);
final List<SpotlightSubmission> existingSpotlightSubmissions = spotlightBatch.getSpotlightSubmissions();

// Check if submission is already in the batch (idempotent operation)
boolean alreadyExists = existingSpotlightSubmissions != null
&& existingSpotlightSubmissions.stream()
.anyMatch(s -> s.getId().equals(spotlightSubmission.getId()));

if (alreadyExists) {
log.info("Submission {} is already in batch {}. Returning existing batch (idempotent).",
spotlightSubmission.getId(), spotlightBatchId);
return spotlightBatch;
}

final List<SpotlightBatch> existingSpotlightBatches = spotlightSubmission.getBatches();

existingSpotlightSubmissions.add(spotlightSubmission);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ public Boolean verifyAdminRoles(final String emailAddress, final String roles) {
@PreAuthorize("hasAnyRole('ADMIN', 'SUPER_ADMIN')")
public GrantAdmin getGrantAdminIdFromUserServiceEmail(final String email, final String jwt) {
try {
//UI might send camelcase. change it to lowercase

UserV2DTO response = webClientBuilder.build().get()
.uri(userServiceConfig.getDomain() + "/user/email/" + email)
.uri(userServiceConfig.getDomain() + "/user/email/" + email.toLowerCase())
.cookie(userServiceConfig.getCookieName(), jwt).retrieve().bodyToMono(UserV2DTO.class).block();

return grantAdminRepository.findByGapUserUserSub(response.sub()).orElseThrow(() -> new NotFoundException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ private SimpleEntry<String, String> validateURL(GrantAdvertQuestionResponse ques
// (incl. .com) (repeating) |
// (optional) slash | (optional) additional path | (optional) slash |
// (optional) query params
String urlValidPattern = "^(http://|https://)(www.)?((?!www)[a-zA-Z0-9\\-]{2,}+)(\\.[a-zA-Z0-9\\-]{2,})+(/)?(/[a-z0-9\\-._~%!$&'()*+,;=:@]+)*?(/)?(\\?[a-z0-9\\-._~%!$&'()*+,;=:@/]*)?$";
String urlValidPattern = "^(http://|https://)(www.)?((?!www)[a-zA-Z0-9\\-]{2,}+)(\\.[a-zA-Z0-9\\-]{2,})+(/)?(/[a-z0-9\\-._~%!$&'()*+,;=:@#]+)*?(/)?(\\?[a-z0-9\\-._~%!$&'()*+,;=:@#/]*)?$";
Pattern pattern = Pattern.compile(urlValidPattern, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(question.getResponse());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,8 @@ private static Stream<Arguments> validUrls() {
Arguments.of("https://www.google.co.uk/long/path?query=var&query2=var"),
Arguments.of("http://www.google.co.uk/long/path?query=var&query2=var"),
Arguments.of("https://google.co.uk/long/path?query=var&query2=var"),
Arguments.of("http://google.co.uk/long/path?query=var&query2=var"));
Arguments.of("http://google.co.uk/long/path?query=var&query2=var"),
Arguments.of("https://google.co.uk/competition/1989/overview/63441f1e-850b-4581-986d-cd2f6c6c226d#summary"));
}
// @formatter:on

Expand Down