Skip to content

Commit 659e622

Browse files
authored
Merge pull request #3180 from ControlSystemStudio/CSSTUDIO-2768
Updated login procedure for Olog and save&restore
2 parents f206162 + 05812bd commit 659e622

File tree

7 files changed

+61
-28
lines changed

7 files changed

+61
-28
lines changed

app/logbook/olog/client-es/src/main/java/org/phoebus/olog/es/api/OlogClient.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.phoebus.olog.es.api.model.OlogLog;
3030
import org.phoebus.olog.es.api.model.OlogObjectMappers;
3131
import org.phoebus.olog.es.api.model.OlogSearchResult;
32+
import org.phoebus.olog.es.authentication.LoginCredentials;
3233
import org.phoebus.security.store.SecureStore;
3334
import org.phoebus.security.tokens.AuthenticationScope;
3435
import org.phoebus.security.tokens.ScopedAuthenticationToken;
@@ -519,16 +520,15 @@ public void groupLogEntries(List<Long> logEntryIds) throws LogbookException {
519520
/**
520521
* Logs in to the Olog service.
521522
*
522-
* @param username User name, must not be <code>null</code>.
523+
* @param username Username, must not be <code>null</code>.
523524
* @param password Password, must not be <code>null</code>.
524525
* @throws Exception if the login fails, e.g. bad credentials or service off-line.
525526
*/
526527
public void authenticate(String username, String password) throws Exception {
527528
try {
528529
ClientResponse clientResponse = service.path("login")
529-
.queryParam("username", username)
530-
.queryParam("password", password)
531-
.post(ClientResponse.class);
530+
.type(MediaType.APPLICATION_JSON)
531+
.post(ClientResponse.class, OlogObjectMappers.logEntrySerializer.writeValueAsString(new LoginCredentials(username, password)));
532532
if (clientResponse.getStatus() == Status.UNAUTHORIZED.getStatusCode()) {
533533
throw new Exception("Failed to login: user unauthorized");
534534
} else if (clientResponse.getStatus() != Status.OK.getStatusCode()) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright (C) 2024 European Spallation Source ERIC.
3+
*/
4+
5+
package org.phoebus.olog.es.authentication;
6+
7+
/**
8+
* Wrapper around user's credentials
9+
*
10+
* @param username Self-explanatory
11+
* @param password Self-explanatory
12+
*/
13+
public record LoginCredentials(String username, String password) {
14+
}

app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/client/SaveAndRestoreClientImpl.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.phoebus.applications.saveandrestore.model.CompositeSnapshot;
1616
import org.phoebus.applications.saveandrestore.model.Configuration;
1717
import org.phoebus.applications.saveandrestore.model.ConfigurationData;
18+
import org.phoebus.applications.saveandrestore.model.LoginCredentials;
1819
import org.phoebus.applications.saveandrestore.model.Node;
1920
import org.phoebus.applications.saveandrestore.model.RestoreResult;
2021
import org.phoebus.applications.saveandrestore.model.Snapshot;
@@ -34,11 +35,9 @@
3435
import java.net.CookieManager;
3536
import java.net.CookiePolicy;
3637
import java.net.URI;
37-
import java.net.URLEncoder;
3838
import java.net.http.HttpClient;
3939
import java.net.http.HttpRequest;
4040
import java.net.http.HttpResponse;
41-
import java.nio.charset.StandardCharsets;
4241
import java.time.Duration;
4342
import java.util.Base64;
4443
import java.util.List;
@@ -582,16 +581,14 @@ public List<Node> deleteTag(TagData tagData) {
582581
*/
583582
@Override
584583
public UserData authenticate(String userName, String password) {
585-
String stringBuilder = Preferences.jmasarServiceUrl +
586-
"/login?username=" +
587-
URLEncoder.encode(userName, StandardCharsets.UTF_8) +
588-
"&password=" +
589-
URLEncoder.encode(password, StandardCharsets.UTF_8);
590-
HttpRequest request = HttpRequest.newBuilder()
584+
try {
585+
String stringBuilder = Preferences.jmasarServiceUrl +
586+
"/login";
587+
HttpRequest request = HttpRequest.newBuilder()
591588
.uri(URI.create(stringBuilder))
592-
.POST(HttpRequest.BodyPublishers.noBody())
589+
.header("Content-Type", CONTENT_TYPE_JSON)
590+
.POST(HttpRequest.BodyPublishers.ofString(OBJECT_MAPPER.writeValueAsString(new LoginCredentials(userName, password))))
593591
.build();
594-
try {
595592
HttpResponse<String> response = CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
596593
return OBJECT_MAPPER.readValue(response.body(), UserData.class);
597594
} catch (Exception e) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright (C) 2024 European Spallation Source ERIC.
3+
*/
4+
5+
package org.phoebus.applications.saveandrestore.model;
6+
7+
/**
8+
* Wrapper around user's credentials
9+
*
10+
* @param username Self-explanatory
11+
* @param password Self-explanatory
12+
*/
13+
public record LoginCredentials(String username, String password) {
14+
}

services/save-and-restore/doc/index.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,21 @@ Authorization uses a role-based approach like so:
869869
* Object is a tag
870870
* Save-and-restore role "sar-admin": no restrictions
871871

872+
Authentication endpoint
873+
"""""""""""""""""""""""
874+
875+
A client can may use the /login endpoint to check if user is authenticated:
876+
877+
**.../login**
878+
879+
Method: POST
880+
881+
Body:
882+
883+
.. code-block:: JSON
884+
885+
{"username":"johndoe", "password":"undisclosed"}
886+
872887
873888
Enabled authentication, disabled authorization
874889
----------------------------------------------

services/save-and-restore/pom.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,6 @@
7070
<version>4.7.4-SNAPSHOT</version>
7171
</dependency>
7272

73-
<dependency>
74-
<groupId>org.phoebus</groupId>
75-
<artifactId>core-util</artifactId>
76-
<version>4.7.4-SNAPSHOT</version>
77-
</dependency>
78-
7973
<dependency>
8074
<groupId>org.springframework.boot</groupId>
8175
<artifactId>spring-boot-starter</artifactId>

services/save-and-restore/src/main/java/org/phoebus/service/saveandrestore/web/controllers/AuthenticationController.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.phoebus.service.saveandrestore.web.controllers;
2121

22+
import org.phoebus.applications.saveandrestore.model.LoginCredentials;
2223
import org.phoebus.applications.saveandrestore.model.UserData;
2324
import org.springframework.beans.factory.annotation.Autowired;
2425
import org.springframework.http.HttpStatus;
@@ -29,7 +30,7 @@
2930
import org.springframework.security.core.AuthenticationException;
3031
import org.springframework.security.core.GrantedAuthority;
3132
import org.springframework.web.bind.annotation.PostMapping;
32-
import org.springframework.web.bind.annotation.RequestParam;
33+
import org.springframework.web.bind.annotation.RequestBody;
3334
import org.springframework.web.bind.annotation.RestController;
3435

3536
import java.util.List;
@@ -50,28 +51,26 @@ public class AuthenticationController extends BaseController {
5051
/**
5152
* Authenticates user.
5253
*
53-
* @param userName The user principal name
54-
* @param password User's password
54+
* @param loginCredentials User's credentials
5555
* @return A {@link ResponseEntity} carrying a {@link UserData} object if the login was successful,
5656
* otherwise the body will be <code>null</code>.
5757
*/
5858
@PostMapping(value = "login")
59-
public ResponseEntity<UserData> login(@RequestParam(value = "username") String userName,
60-
@RequestParam(value = "password") String password) {
59+
public ResponseEntity<UserData> login(@RequestBody LoginCredentials loginCredentials) {
6160
Authentication authentication =
62-
new UsernamePasswordAuthenticationToken(userName, password);
61+
new UsernamePasswordAuthenticationToken(loginCredentials.username(), loginCredentials.password());
6362
try {
6463
authentication = authenticationManager.authenticate(authentication);
6564
} catch (AuthenticationException e) {
66-
Logger.getLogger(AuthenticationController.class.getName()).log(Level.WARNING, "Unable to authenticate", e);
65+
Logger.getLogger(AuthenticationController.class.getName()).log(Level.WARNING, "Unable to authenticate user " + loginCredentials.username());
6766
return new ResponseEntity<>(
6867
null,
6968
HttpStatus.UNAUTHORIZED);
7069
}
7170
List<String> roles = authentication.getAuthorities().stream()
7271
.map(GrantedAuthority::getAuthority).collect(Collectors.toList());
7372
return new ResponseEntity<>(
74-
new UserData(userName, roles),
73+
new UserData(loginCredentials.username(), roles),
7574
HttpStatus.OK);
7675
}
7776
}

0 commit comments

Comments
 (0)