Skip to content

Commit 5314da2

Browse files
committed
Fixes #342
1 parent 39c099d commit 5314da2

14 files changed

Lines changed: 155 additions & 20 deletions

File tree

client/src/styles/vars.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@ $background: #eaebf0;
22
$br: 6px;
33
// Screen
44
$medium: 824px;
5-
$tablet-max: 824px;

client/src/tabs/Tokens.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ div.mod-tokens {
6464
width: 100%;
6565
margin: 40px auto 25px auto;
6666

67-
@media (max-width: $tablet-max) {
67+
@media (max-width: $medium) {
6868
flex-direction: column;
6969
}
7070

@@ -86,7 +86,7 @@ div.mod-tokens {
8686
div.new-token {
8787
width: 60%;
8888

89-
@media (max-width: $tablet-max) {
89+
@media (max-width: $medium) {
9090
padding: 15px;
9191
width: 100%;
9292
}

server/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
<artifactId>spring-boot-configuration-processor</artifactId>
3939
<optional>true</optional>
4040
</dependency>
41+
<dependency>
42+
<groupId>io.micrometer</groupId>
43+
<artifactId>micrometer-registry-prometheus</artifactId>
44+
<version>1.15.1</version>
45+
</dependency>
4146
<dependency>
4247
<groupId>ch.qos.logback.contrib</groupId>
4348
<artifactId>logback-json-classic</artifactId>

server/src/main/java/invite/AccessServerApplication.java renamed to server/src/main/java/invite/InviteServerApplication.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
import org.springframework.boot.autoconfigure.SpringBootApplication;
55

66
@SpringBootApplication
7-
public class AccessServerApplication {
7+
public class InviteServerApplication {
88

99
public static void main(String[] args) {
10-
SpringApplication.run(AccessServerApplication.class, args);
10+
SpringApplication.run(InviteServerApplication.class, args);
1111
}
1212

1313
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package invite.api;
2+
3+
import invite.model.Authority;
4+
import invite.model.Status;
5+
import invite.repository.*;
6+
import io.micrometer.core.instrument.Gauge;
7+
import io.micrometer.core.instrument.MeterRegistry;
8+
import io.swagger.v3.oas.annotations.Hidden;
9+
import org.springframework.web.bind.annotation.RestController;
10+
11+
import java.util.stream.Stream;
12+
13+
@RestController
14+
@Hidden
15+
public class MetricsController {
16+
17+
public MetricsController(UserRepository userRepository,
18+
RoleRepository roleRepository,
19+
InvitationRepository invitationRepository,
20+
UserRoleRepository userRoleRepository,
21+
ApplicationRepository applicationRepository,
22+
MeterRegistry meterRegistry) {
23+
24+
Gauge.builder("total_number_of_users", () ->
25+
userRepository.count())
26+
.description("Total number of Users")
27+
.register(meterRegistry);
28+
29+
Gauge.builder("total_number_of_access_roles", () ->
30+
roleRepository.count())
31+
.description("Total number of Access Roles")
32+
.register(meterRegistry);
33+
34+
Stream.of(Authority.values())
35+
.filter(authority -> !authority.equals(Authority.SUPER_USER) && !authority.equals(Authority.INSTITUTION_ADMIN))
36+
.forEach(authority -> Gauge
37+
.builder("total_number_of_" + authority.name().toLowerCase() + "_users",
38+
() -> userRoleRepository.countByAuthority(authority))
39+
.description("Total number of " + authority.name().toLowerCase() + "-users")
40+
.register(meterRegistry));
41+
42+
Gauge
43+
.builder("total_number_of_institution_admins",
44+
() -> userRepository.countBySuperUserTrue())
45+
.description("Total number of Institution Admins")
46+
.register(meterRegistry);
47+
48+
Gauge
49+
.builder("total_number_of_super_users",
50+
() -> userRepository.countBySuperUserTrue())
51+
.description("Total number of Super users")
52+
.register(meterRegistry);
53+
54+
Gauge.builder("total_number_of_applications",
55+
() -> applicationRepository.count())
56+
.description("Total number of applications")
57+
.register(meterRegistry);
58+
59+
Gauge.builder("total_number_of_pending_invitations",
60+
() -> invitationRepository.countByStatus(Status.OPEN))
61+
.description("Total number of pending invitations")
62+
.register(meterRegistry);
63+
64+
}
65+
66+
}

server/src/main/java/invite/repository/InvitationRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package invite.repository;
22

3+
import invite.model.Authority;
34
import invite.model.Invitation;
45
import invite.model.Role;
56
import invite.model.Status;
@@ -29,6 +30,8 @@ public interface InvitationRepository extends JpaRepository<Invitation, Long>, Q
2930

3031
List<Invitation> findByStatusAndRoles_role(Status status, Role role);
3132

33+
long countByStatus(Status status);
34+
3235
@Query(value = """
3336
SELECT i.id, i.email, i.remote_api_user, i.intended_authority, i.created_at, i.expiry_date,
3437
u.id as user_id, u.name, u.email as inviter_email

server/src/main/java/invite/repository/UserRepository.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ public interface UserRepository extends JpaRepository<User, Long>, QueryRewriter
2323

2424
List<User> findBySuperUserTrue();
2525

26+
long countBySuperUserTrue();
27+
28+
long countByInstitutionAdminTrue();
29+
2630
Optional<User> findByEduPersonPrincipalNameIgnoreCase(String eppn);
2731

2832
Optional<User> findByEmailIgnoreCase(String email);

server/src/main/java/invite/repository/UserRoleRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public interface UserRoleRepository extends JpaRepository<UserRole, Long>, Query
3131

3232
List<UserRole> findByRoleName(String roleName);
3333

34+
long countByAuthority(Authority authority);
35+
3436
@Modifying
3537
@Query(value = "DELETE FROM user_roles WHERE id = ?1", nativeQuery = true)
3638
@Transactional(isolation = Isolation.SERIALIZABLE)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package invite.security;
22

33
public enum Scope {
4-
voot, teams, attribute_aggregation, lifecycle, profile, sp_dashboard, access
4+
voot, teams, attribute_aggregation, lifecycle, profile, sp_dashboard, access, actuator
55
}

server/src/main/java/invite/security/SecurityConfig.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ SecurityFilterChain sessionSecurityFilterChain(HttpSecurity http,
144144
"/api/v1/users/ms-accept-return/**",
145145
"/api/v1/validations/**",
146146
"/ui/**",
147-
"/internal/**")
147+
"/internal/health",
148+
"/internal/info")
148149
.permitAll()
149150
.anyRequest()
150151
.authenticated()
@@ -201,10 +202,12 @@ SecurityFilterChain basicAuthenticationSecurityFilterChain(HttpSecurity http) th
201202
"/api/deprovision/**",
202203
"/api/external/v1/deprovision/**",
203204
"/api/internal/invite/**",
204-
"/api/external/v1/internal/invite/**"
205+
"/api/external/v1/internal/invite/**",
206+
"/internal/prometheus"
205207
).sessionManagement(c -> c
206208
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
207-
)
209+
).authorizeHttpRequests(auth -> auth
210+
.requestMatchers("/internal/prometheus").hasRole("ACTUATOR"))
208211
.authorizeHttpRequests(c -> c
209212
//The API token is secured in the UserHandlerMethodArgumentResolver
210213
.requestMatchers(apiTokenRequestMatcher)

0 commit comments

Comments
 (0)