• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FIWARE / credentials-config-service / #37

16 May 2025 12:06PM UTC coverage: 86.4% (+5.2%) from 81.223%
#37

push

web-flow
add presentation definition (#9)

* add presentation definition

* add format

* store format

* fix

* logging

* more logging

* try update

* try

fix the schema

* remove deleted

* fix get all

* format

* support filter

* Extend for presetnation definition

* extend doc

* cleanup

* Update README.md

Co-authored-by: Tim Smyth <33017641+pulledtim@users.noreply.github.com>

* Update api/credentials-config-service.yaml

Co-authored-by: Tim Smyth <33017641+pulledtim@users.noreply.github.com>

* Update api/credentials-config-service.yaml

Co-authored-by: Tim Smyth <33017641+pulledtim@users.noreply.github.com>

---------

Co-authored-by: Tim Smyth <33017641+pulledtim@users.noreply.github.com>

152 of 166 new or added lines in 8 files covered. (91.57%)

13 existing lines in 2 files now uncovered.

324 of 375 relevant lines covered (86.4%)

0.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.18
/src/main/java/org/fiware/iam/rest/ServiceApiController.java
1
package org.fiware.iam.rest;
2

3
import io.micronaut.core.annotation.NonNull;
4
import io.micronaut.core.annotation.Nullable;
5
import io.micronaut.data.model.Page;
6
import io.micronaut.data.model.Pageable;
7
import io.micronaut.data.model.Sort;
8
import io.micronaut.http.HttpResponse;
9
import io.micronaut.http.annotation.Controller;
10
import io.micronaut.transaction.annotation.Transactional;
11
import lombok.RequiredArgsConstructor;
12
import lombok.extern.slf4j.Slf4j;
13
import org.fiware.iam.ServiceMapper;
14
import org.fiware.iam.ccs.api.ServiceApi;
15
import org.fiware.iam.ccs.model.*;
16
import org.fiware.iam.exception.ConflictException;
17
import org.fiware.iam.repository.Service;
18
import org.fiware.iam.repository.ServiceRepository;
19

20
import java.net.URI;
21
import java.util.Optional;
22

23
/**
24
 * Implementation of the service api to configure services and there credentials
25
 */
26
@Slf4j
1✔
27
@Controller("${general.basepath:/}")
28
@RequiredArgsConstructor
29
public class ServiceApiController implements ServiceApi {
30

31
        private final ServiceRepository serviceRepository;
32
        private final ServiceMapper serviceMapper;
33

34
        @Override
35
        public HttpResponse<Object> createService(@NonNull ServiceVO serviceVO) {
36
                if (serviceVO.getId() != null && serviceRepository.existsById(serviceVO.getId())) {
1✔
37
                        throw new ConflictException(String.format("The service with id %s already exists.", serviceVO.getId()),
1✔
38
                                        serviceVO.getId());
1✔
39
                }
40
                validateServiceVO(serviceVO);
1✔
41

42
                Service mappedService = serviceMapper.map(serviceVO);
1✔
43

44
                Service savedService = serviceRepository.save(mappedService);
1✔
45

46
                return HttpResponse.created(
1✔
47
                                URI.create(
1✔
48
                                                ServiceApi.PATH_GET_SERVICE.replace(
1✔
49
                                                                "{id}", savedService.getId())));
1✔
50
        }
51

52
        @Override
53
        public HttpResponse<Object> deleteServiceById(@NonNull String id) {
54
                if (!serviceRepository.existsById(id)) {
1✔
55
                        return HttpResponse.notFound();
1✔
56
                }
57
                serviceRepository.deleteById(id);
1✔
58
                return HttpResponse.noContent();
1✔
59
        }
60

61
        @Override
62
        public HttpResponse<ScopeVO> getScopeForService(@NonNull String id, @Nullable String oidcScope) {
63
                Optional<Service> service = serviceRepository.findById(id);
1✔
64
                if (service.isEmpty()) {
1✔
65
                        return HttpResponse.notFound();
1✔
66
                }
67
                String selectedOidcScope =
68
                                oidcScope == null ?
1✔
69
                                                serviceMapper.map(service.get()).getDefaultOidcScope() :
1✔
70
                                                oidcScope;
1✔
71
                ServiceScopesEntryVO serviceScopesEntryVO = serviceMapper.map(service.get())
1✔
72
                                .getOidcScopes()
1✔
73
                                .get(selectedOidcScope);
1✔
74
                ScopeVO scopeVO = new ScopeVO();
1✔
75
                scopeVO.addAll(serviceScopesEntryVO.getCredentials().stream().map(CredentialVO::getType).toList());
1✔
76
                return HttpResponse.ok(scopeVO);
1✔
77
        }
78

79
        @Override
80
        public HttpResponse<ServiceVO> getService(@NonNull String id) {
81
                Optional<ServiceVO> serviceVO = serviceRepository.findById(id)
1✔
82
                                .map(serviceMapper::map);
1✔
83
                return serviceVO
1✔
84
                                .map(HttpResponse::ok)
1✔
85
                                .orElse(HttpResponse.notFound());
1✔
86
        }
87

88
        @Override
89
        public HttpResponse<ServicesVO> getServices(@Nullable Integer nullablePageSize,
90
                                                                                                @Nullable Integer nullablePage) {
91
                var pageSize = Optional.ofNullable(nullablePageSize).orElse(100);
1✔
92
                var page = Optional.ofNullable(nullablePage).orElse(0);
1✔
93
                if (pageSize < 1) {
1✔
94
                        throw new IllegalArgumentException("PageSize has to be at least 1.");
1✔
95
                }
96
                if (page < 0) {
1✔
97
                        throw new IllegalArgumentException("Offsets below 0 are not supported.");
1✔
98
                }
99

100
                Page<Service> requestedPage = serviceRepository.findAll(
1✔
101
                                Pageable.from(page, pageSize, Sort.of(Sort.Order.asc("id"))));
1✔
102
                return HttpResponse.ok(
1✔
103
                                new ServicesVO()
104
                                                .total((int) requestedPage.getTotalSize())
1✔
105
                                                .pageNumber(page)
1✔
106
                                                .pageSize(requestedPage.getContent().size())
1✔
107
                                                .services(requestedPage.getContent().stream().map(serviceMapper::map).toList()));
1✔
108
        }
109

110
        @Transactional
111
        @Override
112
        public HttpResponse<ServiceVO> updateService(@NonNull String id, @NonNull ServiceVO serviceVO) {
113
                if (serviceVO.getId() != null && !id.equals(serviceVO.getId())) {
1✔
NEW
114
                        throw new IllegalArgumentException("The id of a service cannot be updated.");
×
115
                }
116
                validateServiceVO(serviceVO);
1✔
117
                if (!serviceRepository.existsById(id)) {
1✔
118
                        return HttpResponse.notFound();
1✔
119
                }
120
                // just in case none is set in the object
121
                serviceVO.setId(id);
1✔
122
                serviceRepository.deleteById(id);
1✔
123
                return HttpResponse.ok(serviceMapper.map(serviceRepository.save(serviceMapper.map(serviceVO))));
1✔
124
        }
125

126
        // validate a service vo, e.g. check forbidden null values
127
        private void validateServiceVO(ServiceVO serviceVO) {
128
                if (serviceVO.getDefaultOidcScope() == null) {
1✔
129
                        throw new IllegalArgumentException("Default OIDC scope cannot be null.");
1✔
130
                }
131
                if (serviceVO.getOidcScopes() == null) {
1✔
132
                        throw new IllegalArgumentException("OIDC scopes cannot be null.");
1✔
133
                }
134

135
                String defaultOidcScope = serviceVO.getDefaultOidcScope();
1✔
136
                ServiceScopesEntryVO serviceScopesEntryVO = serviceVO
1✔
137
                                .getOidcScopes()
1✔
138
                                .get(defaultOidcScope);
1✔
139
                if (serviceScopesEntryVO == null) {
1✔
NEW
140
                        throw new IllegalArgumentException("Default OIDC scope must exist in OIDC scopes array.");
×
141
                }
142

143
                Optional<CredentialVO> nullType = serviceScopesEntryVO
1✔
144
                                .getCredentials()
1✔
145
                                .stream()
1✔
146
                                .filter(cvo -> cvo.getType() == null)
1✔
147
                                .findFirst();
1✔
148
                if (nullType.isPresent()) {
1✔
149
                        throw new IllegalArgumentException("Type of a credential cannot be null.");
1✔
150
                }
151
        }
1✔
152

153
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc