Skip to content
Snippets Groups Projects
Commit c67052b0 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Added endpoint for retrieving member email addresses; CLI improvements

parent 909daf60
No related branches found
No related tags found
No related merge requests found
Showing
with 426 additions and 55 deletions
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<finalName>gms-cli</finalName>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
......
package it.inaf.ia2.gms.cli; package it.inaf.ia2.gms.cli;
import it.inaf.ia2.gms.client.GmsClient; import it.inaf.ia2.gms.client.GmsClient;
import it.inaf.ia2.gms.client.GmsClientBuilder;
import it.inaf.ia2.gms.client.model.Permission; import it.inaf.ia2.gms.client.model.Permission;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.List;
import java.util.Properties; import java.util.Properties;
public class CLI { public class CLI {
private final GmsClient client;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
new CLI().run(args); new CLI(args).run();
}
private final String args[];
private int argIndex;
private String gmsBaseUrl;
private String rapBaseUrl;
private String clientId;
private String clientSecret;
private String token;
private GmsClient client;
private CLI(String... args) {
this.args = args;
}
private void run() throws Exception {
if (args.length < 2) {
displayUsage();
}
boolean commandParsed = false;
while (argIndex < args.length && !commandParsed) {
switch (args[argIndex]) {
case "--config-file":
loadConfigFromFile(new File(getNextArg()));
break;
case "--token-file":
loadTokenFromFile(new File(getNextArg()));
break;
case "--gms-url":
gmsBaseUrl = getNextArg();
break;
case "--rap-url":
rapBaseUrl = getNextArg();
break;
case "--client-id":
clientId = getNextArg();
break;
case "--client-secret":
clientSecret = getNextArg();
break;
default:
verifyConfigLoaded();
createClient();
parseCommand();
commandParsed = true;
break;
}
argIndex++;
}
}
private String getNextArg() {
if (argIndex + 1 == args.length) {
System.err.println("Missing value for option " + args[argIndex]);
System.exit(1);
}
return args[++argIndex];
}
private void verifyConfigLoaded() {
if (gmsBaseUrl == null) {
// Attempt reading gms.properties in current directory
loadConfigFromFile(new File("gms.properties"));
}
if (clientId == null && token == null) {
// Attempt loading token.txt in current directory
loadTokenFromFile(new File("token.txt"));
}
if (token != null && (clientSecret == null || rapBaseUrl == null)) {
System.err.println("Client secret and RAP base URL not configured");
System.exit(1);
}
}
private void createClient() {
GmsClientBuilder clientBuilder = new GmsClientBuilder()
.setGmsBaseUrl(gmsBaseUrl);
if (token != null) {
client = clientBuilder.build();
client.setAccessToken(token);
} else {
client = clientBuilder.setClientId(clientId)
.setClientSecret(clientSecret)
.setRapBaseUrl(rapBaseUrl)
.build();
}
} }
private CLI() throws IOException { private void loadConfigFromFile(File config) {
File config = new File("gms.properties");
if (!config.exists()) { if (!config.exists()) {
System.err.println("Unable to find the file gms.properties"); System.err.println("Config file " + config.getAbsolutePath() + " doesn't exist");
System.exit(1); System.exit(1);
} }
Properties properties = new Properties(); Properties properties = new Properties();
try (InputStream in = new FileInputStream(config)) { try (InputStream in = new FileInputStream(config)) {
properties.load(in); properties.load(in);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
} }
String baseUrl = (String) properties.get("base_url"); gmsBaseUrl = properties.getProperty("gms_url");
if (baseUrl == null) { if (gmsBaseUrl == null) {
System.err.println("Missing base_url in gms.properties"); System.err.println("Missing gms_url in gms.properties");
System.exit(1); System.exit(1);
} }
rapBaseUrl = properties.getProperty("rap_url");
clientId = properties.getProperty("client_id");
clientSecret = properties.getProperty("client_secret");
}
private void loadTokenFromFile(File tokenFile) {
String token = (String) properties.get("token"); if (!tokenFile.exists()) {
if (token == null) { System.err.println("Token file " + tokenFile.getAbsolutePath() + " doesn't exist");
System.err.println("Missing token in gms.properties");
System.exit(1); System.exit(1);
} }
client = new GmsClient(baseUrl).setAccessToken(token); try (InputStream in = new FileInputStream(tokenFile)) {
java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\\A");
token = s.next().trim();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
} }
public void run(String... args) throws Exception {
if (args.length < 2) {
displayUsage();
} }
switch (args[0]) { private void parseCommand() {
switch (args[argIndex]) {
case "create-group": case "create-group":
boolean leaf = false; boolean leaf = false;
if (args.length > 1) { if (argIndex + 2 < args.length) {
leaf = Boolean.parseBoolean(args[2]); leaf = Boolean.parseBoolean(args[argIndex + 2]);
} }
client.createGroup(args[1], leaf); client.createGroup(args[argIndex + 1], leaf);
System.out.println("Group created"); System.out.println("Group created");
break; break;
case "delete-group": case "delete-group":
client.deleteGroup(args[1]); client.deleteGroup(args[argIndex + 1]);
System.out.println("Group deleted"); System.out.println("Group deleted");
break; break;
case "add-member": case "add-member":
if (args.length < 3) { if (argIndex + 2 >= args.length) {
displayUsage(); displayUsage();
} }
client.addMember(args[1], args[2]); client.addMember(args[argIndex + 1], args[argIndex + 2]);
System.out.println("Member added"); System.out.println("Member added");
break; break;
case "remove-member": case "remove-member":
if (args.length < 3) { if (argIndex + 2 >= args.length) {
displayUsage(); displayUsage();
} }
client.removeMember(args[1], args[2]); client.removeMember(args[argIndex + 1], args[argIndex + 2]);
System.out.println("Member removed"); System.out.println("Member removed");
break; break;
case "add-permission": case "add-permission":
if (args.length < 4) { if (argIndex + 3 >= args.length) {
displayUsage(); displayUsage();
} }
client.addPermission(args[1], args[2], Permission.valueOf(args[3])); client.addPermission(args[argIndex + 1], args[argIndex + 2], Permission.valueOf(args[argIndex + 3]));
System.out.println("Permission added"); System.out.println("Permission added");
break; break;
case "delete-permission": case "delete-permission":
if (args.length < 4) { if (argIndex + 2 >= args.length) {
displayUsage(); displayUsage();
} }
client.removePermission(args[1], args[2]); client.removePermission(args[argIndex + 1], args[argIndex + 2]);
System.out.println("Permission removed"); System.out.println("Permission removed");
break; break;
case "get-member-email-addresses":
Permission permission = null;
if (argIndex + 2 < args.length) {
permission = Permission.valueOf(args[argIndex + 2]);
}
List<String> addresses = client.getMemberEmailAddresses(args[argIndex + 1], permission);
for (String address : addresses) {
System.out.println(address);
}
break;
default: default:
displayUsage(); displayUsage();
break; break;
...@@ -97,13 +209,20 @@ public class CLI { ...@@ -97,13 +209,20 @@ public class CLI {
} }
private void displayUsage() { private void displayUsage() {
System.out.println("java -jar gms-client.jar\n" System.out.println("gms-client\n"
+ " create-group <name1.name2.name3> <leaf>\n" + " [--config-file <file>]\n"
+ " [--token-file <file>]\n"
+ " [--gms-url <url>]\n"
+ " [--rap-url <url>]\n"
+ " [--client-id <id>]\n"
+ " [--client-secret <secret>]\n"
+ " create-group <name1.name2.name3> [<leaf>]\n"
+ " delete-group <name1.name2.name3>\n" + " delete-group <name1.name2.name3>\n"
+ " add-member <name1.name2.name3> <user_id>\n" + " add-member <name1.name2.name3> <user_id>\n"
+ " remove-member <name1.name2.name3> <user_id>\n" + " remove-member <name1.name2.name3> <user_id>\n"
+ " add-permission <name1.name2.name3> <user_id> <permission>\n" + " add-permission <name1.name2.name3> <user_id> <permission>\n"
+ " delete-permission <name1.name2.name3> <user_id>"); + " delete-permission <name1.name2.name3> <user_id>\n"
+ " get-member-email-addresses <name1.name2.name3> [<permission>]");
System.exit(0); System.exit(0);
} }
} }
...@@ -7,6 +7,7 @@ import it.inaf.ia2.gms.client.call.AddPermissionCall; ...@@ -7,6 +7,7 @@ import it.inaf.ia2.gms.client.call.AddPermissionCall;
import it.inaf.ia2.gms.client.call.CreateGroupCall; import it.inaf.ia2.gms.client.call.CreateGroupCall;
import it.inaf.ia2.gms.client.call.DeleteGroupCall; import it.inaf.ia2.gms.client.call.DeleteGroupCall;
import it.inaf.ia2.gms.client.call.GetGroupPermissionsCall; import it.inaf.ia2.gms.client.call.GetGroupPermissionsCall;
import it.inaf.ia2.gms.client.call.GetMemberEmailAddresses;
import it.inaf.ia2.gms.client.call.GetUserGroupsCall; import it.inaf.ia2.gms.client.call.GetUserGroupsCall;
import it.inaf.ia2.gms.client.call.GetUserPermissionsCall; import it.inaf.ia2.gms.client.call.GetUserPermissionsCall;
import it.inaf.ia2.gms.client.call.ListGroupsCall; import it.inaf.ia2.gms.client.call.ListGroupsCall;
...@@ -20,15 +21,10 @@ import java.util.Map; ...@@ -20,15 +21,10 @@ import java.util.Map;
public class GmsClient { public class GmsClient {
HttpClientWrapper httpClientWrapper; private final HttpClientWrapper httpClientWrapper;
public GmsClient(String baseUrl) { GmsClient(HttpClientWrapper httpClientWrapper) {
this.httpClientWrapper = httpClientWrapper;
if (!baseUrl.endsWith("/")) {
baseUrl += "/";
}
httpClientWrapper = new HttpClientWrapper(baseUrl);
} }
public GmsClient setAccessToken(String accessToken) { public GmsClient setAccessToken(String accessToken) {
...@@ -83,4 +79,8 @@ public class GmsClient { ...@@ -83,4 +79,8 @@ public class GmsClient {
public void addInvitedRegistration(String token, String email, Map<String, Permission> groupsPermissions) { public void addInvitedRegistration(String token, String email, Map<String, Permission> groupsPermissions) {
new AddInvitedRegistrationCall(httpClientWrapper).addInvitedRegistration(token, email, groupsPermissions); new AddInvitedRegistrationCall(httpClientWrapper).addInvitedRegistration(token, email, groupsPermissions);
} }
public List<String> getMemberEmailAddresses(String groupId, Permission permission) {
return new GetMemberEmailAddresses(httpClientWrapper).getMemberEmailAddresses(groupId, permission);
}
} }
package it.inaf.ia2.gms.client;
import it.inaf.ia2.gms.client.call.HttpClientWrapper;
public class GmsClientBuilder {
private String gmsBaseUrl;
private String rapBaseUrl;
private String clientId;
private String clientSecret;
public GmsClientBuilder setGmsBaseUrl(String gmsBaseUrl) {
this.gmsBaseUrl = gmsBaseUrl;
return this;
}
public GmsClientBuilder setRapBaseUrl(String rapBaseUrl) {
this.rapBaseUrl = rapBaseUrl;
return this;
}
public GmsClientBuilder setClientId(String clientId) {
this.clientId = clientId;
return this;
}
public GmsClientBuilder setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
return this;
}
public GmsClient build() {
HttpClientWrapper clientWrapper = new HttpClientWrapper(gmsBaseUrl);
if (rapBaseUrl != null && clientId != null && clientSecret != null) {
clientWrapper.setRapBaseUrl(rapBaseUrl)
.setClientId(clientId).setClientSecret(clientSecret);
}
return new GmsClient(clientWrapper);
}
}
...@@ -27,13 +27,13 @@ public abstract class BaseGmsCall { ...@@ -27,13 +27,13 @@ public abstract class BaseGmsCall {
return clientWrapper.newHttpRequest(endpoint); return clientWrapper.newHttpRequest(endpoint);
} }
protected void logServerError(HttpRequest request, HttpResponse<String> response) { protected static void logServerError(HttpRequest request, HttpResponse<String> response) {
LOGGER.log(Level.SEVERE, () -> "Error while reading " + request.uri() LOGGER.log(Level.SEVERE, () -> "Error while reading " + request.uri()
+ "\nServer response status code is " + response.statusCode() + "\nServer response status code is " + response.statusCode()
+ "\nAServer response text is " + response.body()); + "\nServer response text is " + response.body());
} }
protected void logServerErrorInputStream(HttpRequest request, HttpResponse<InputStream> response) { protected static void logServerErrorInputStream(HttpRequest request, HttpResponse<InputStream> response) {
LOGGER.log(Level.SEVERE, () -> { LOGGER.log(Level.SEVERE, () -> {
Scanner s = new Scanner(response.body()).useDelimiter("\\A"); Scanner s = new Scanner(response.body()).useDelimiter("\\A");
String responseBody = s.hasNext() ? s.next() : ""; String responseBody = s.hasNext() ? s.next() : "";
......
package it.inaf.ia2.gms.client.call;
import it.inaf.ia2.gms.client.model.Permission;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class GetMemberEmailAddresses extends BaseGmsCall {
public GetMemberEmailAddresses(HttpClientWrapper clientWrapper) {
super(clientWrapper);
}
public List<String> getMemberEmailAddresses(String group, Permission permission) {
List<String> emailAddresses = new ArrayList<>();
String endpoint = "email/" + group;
if (permission != null) {
endpoint += "?permission=" + permission;
}
HttpRequest request = newHttpRequest(endpoint)
.header("Accept", "text/plain")
.GET()
.build();
return getClient().sendAsync(request, HttpResponse.BodyHandlers.ofInputStream())
.thenApply(response -> {
if (response.statusCode() == 200) {
return response.body();
}
logServerErrorInputStream(request, response);
throw new IllegalStateException("Unable to retrieve groups");
})
.thenApply(inputStream -> {
try (Scanner scan = new Scanner(inputStream)) {
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (!line.isEmpty()) {
emailAddresses.add(line);
}
}
}
return emailAddresses;
}).join();
}
}
...@@ -4,12 +4,20 @@ import java.net.URI; ...@@ -4,12 +4,20 @@ import java.net.URI;
import java.net.http.HttpClient; import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpRequest.Builder; import java.net.http.HttpRequest.Builder;
import java.net.http.HttpResponse;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HttpClientWrapper { public class HttpClientWrapper {
private final String baseGmsUri; private final String baseGmsUri;
private final HttpClient client; private final HttpClient client;
private String rapBaseUrl;
private String clientId;
private String clientSecret;
private String accessToken; private String accessToken;
public HttpClientWrapper(String baseGmsUri) { public HttpClientWrapper(String baseGmsUri) {
...@@ -29,12 +37,68 @@ public class HttpClientWrapper { ...@@ -29,12 +37,68 @@ public class HttpClientWrapper {
return this; return this;
} }
public HttpClientWrapper setRapBaseUrl(String rapBaseUrl) {
if (!rapBaseUrl.endsWith("/")) {
rapBaseUrl += "/";
}
this.rapBaseUrl = rapBaseUrl;
return this;
}
public HttpClientWrapper setClientId(String clientId) {
this.clientId = clientId;
return this;
}
public HttpClientWrapper setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
return this;
}
Builder newHttpRequest(String endpoint) { Builder newHttpRequest(String endpoint) {
if (accessToken == null) {
accessToken = getAccessTokenFromClientCredentials();
}
return HttpRequest.newBuilder() return HttpRequest.newBuilder()
.uri(URI.create(baseGmsUri + endpoint)) .uri(URI.create(baseGmsUri + endpoint))
.header("Authorization", "Bearer " + accessToken); .header("Authorization", "Bearer " + accessToken);
} }
private String getAccessTokenFromClientCredentials() {
if (rapBaseUrl == null || clientId == null || clientSecret == null) {
throw new IllegalStateException("Access token is null and client credentials are not configured");
}
String basicAuthHeader = clientId + ":" + clientSecret;
HttpRequest tokenRequest = HttpRequest.newBuilder()
.uri(URI.create(rapBaseUrl + "auth/oauth2/token"))
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString(basicAuthHeader.getBytes()))
.header("Accept", "application/json")
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString("grant_type=client_credentials"))
.build();
return client.sendAsync(tokenRequest, HttpResponse.BodyHandlers.ofString())
.thenApply(response -> {
if (response.statusCode() == 200) {
return getAccessTokenFromResponse(response.body());
}
BaseGmsCall.logServerError(tokenRequest, response);
throw new IllegalStateException("Unable to retrieve access token");
}).join();
}
protected String getAccessTokenFromResponse(String body) {
Pattern codePattern = Pattern.compile(".*\"access_token\":\\s*\"([^\"]+).*");
Matcher matcher = codePattern.matcher(body);
if (matcher.find()) {
return matcher.group(1);
}
throw new IllegalStateException("Unable to extract access token from body");
}
HttpClient getClient() { HttpClient getClient() {
return client; return client;
} }
......
...@@ -7,7 +7,6 @@ import java.io.ByteArrayInputStream; ...@@ -7,7 +7,6 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.net.http.HttpClient; import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublisher;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodySubscriber; import java.net.http.HttpResponse.BodySubscriber;
import java.net.http.HttpResponse.BodySubscribers; import java.net.http.HttpResponse.BodySubscribers;
...@@ -18,7 +17,6 @@ import java.util.List; ...@@ -18,7 +17,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Flow; import java.util.concurrent.Flow;
import java.util.concurrent.Flow.Subscriber;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
...@@ -47,9 +45,9 @@ public class GmsClientTest { ...@@ -47,9 +45,9 @@ public class GmsClientTest {
httpClient = mock(HttpClient.class); httpClient = mock(HttpClient.class);
HttpClientWrapper clientWrapper = new MockedHttpClientWrapper(BASE_URL, httpClient); HttpClientWrapper clientWrapper = new MockedHttpClientWrapper(BASE_URL, httpClient);
clientWrapper.setAccessToken("foo");
client = new GmsClient(BASE_URL); client = new GmsClient(clientWrapper);
client.httpClientWrapper = clientWrapper;
} }
@Test @Test
......
package it.inaf.ia2.gms.client.call;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class HttpClientWrapperTest {
@Test
public void testExtractAccessToken() {
String response = "{\"access_token\":\"TEST_TOKEN\",\"token_type\":\"Bearer\",\"expires_in\":3600}";
HttpClientWrapper clientWrapper = new HttpClientWrapper("http://localhost");
assertEquals("TEST_TOKEN", clientWrapper.getAccessTokenFromResponse(response));
}
}
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
</dependencies> </dependencies>
<build> <build>
<finalName>gms</finalName>
<plugins> <plugins>
<plugin> <plugin>
<groupId>com.github.eirslett</groupId> <groupId>com.github.eirslett</groupId>
......
...@@ -7,6 +7,7 @@ import it.inaf.ia2.gms.manager.InvitedRegistrationManager; ...@@ -7,6 +7,7 @@ import it.inaf.ia2.gms.manager.InvitedRegistrationManager;
import it.inaf.ia2.gms.manager.MembershipManager; import it.inaf.ia2.gms.manager.MembershipManager;
import it.inaf.ia2.gms.manager.PermissionsManager; import it.inaf.ia2.gms.manager.PermissionsManager;
import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.model.RapUser;
import it.inaf.ia2.gms.model.response.UserPermission; import it.inaf.ia2.gms.model.response.UserPermission;
import it.inaf.ia2.gms.persistence.GroupsDAO; import it.inaf.ia2.gms.persistence.GroupsDAO;
import it.inaf.ia2.gms.persistence.PermissionsDAO; import it.inaf.ia2.gms.persistence.PermissionsDAO;
...@@ -22,9 +23,11 @@ import java.io.PrintWriter; ...@@ -22,9 +23,11 @@ import java.io.PrintWriter;
import java.security.Principal; import java.security.Principal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -301,6 +304,31 @@ public class JWTWebServiceController { ...@@ -301,6 +304,31 @@ public class JWTWebServiceController {
response.setStatus(HttpServletResponse.SC_CREATED); response.setStatus(HttpServletResponse.SC_CREATED);
} }
@GetMapping(value = "/email/{group:.+}", produces = MediaType.TEXT_PLAIN_VALUE)
public void getEmailOfMembers(@PathVariable("group") String groupNames, @RequestParam("permission") Optional<Permission> permission, HttpServletResponse response) throws IOException {
GroupEntity groupEntity = getGroupFromNames(extractGroupNames(groupNames));
Set<String> selectedUserIds = null;
if (permission.isPresent()) {
Permission desiredPermission = permission.get();
selectedUserIds = new HashSet<>();
for (PermissionEntity groupsPermission : permissionsDAO.getGroupsPermissions(groupEntity.getId())) {
if (Permission.includes(groupsPermission.getPermission(), desiredPermission)) {
selectedUserIds.add(groupsPermission.getUserId());
}
}
}
try (PrintWriter pw = new PrintWriter(response.getOutputStream())) {
for (RapUser member : membershipManager.getMembers(groupEntity)) {
if (selectedUserIds == null || selectedUserIds.contains(member.getId())) {
pw.println(member.getPrimaryEmail());
}
}
}
}
private GroupEntity getGroupFromNames(List<String> groupNames) { private GroupEntity getGroupFromNames(List<String> groupNames) {
if (groupNames.isEmpty()) { if (groupNames.isEmpty()) {
return getRoot(); return getRoot();
......
...@@ -48,7 +48,7 @@ public class MembershipManager extends UserAwareComponent { ...@@ -48,7 +48,7 @@ public class MembershipManager extends UserAwareComponent {
Permission groupPermission = permissionsManager.getCurrentUserPermission(group); Permission groupPermission = permissionsManager.getCurrentUserPermission(group);
if (groupPermission == Permission.TRAVERSE) { if (!Permission.includes(groupPermission, Permission.VIEW_MEMBERS)) {
throw new UnauthorizedException("You don't have the permission to view members"); throw new UnauthorizedException("You don't have the permission to view members");
} }
...@@ -98,8 +98,8 @@ public class MembershipManager extends UserAwareComponent { ...@@ -98,8 +98,8 @@ public class MembershipManager extends UserAwareComponent {
private Permission verifyUserCanManageMembers(GroupEntity group) { private Permission verifyUserCanManageMembers(GroupEntity group) {
Permission permission = permissionsManager.getCurrentUserPermission(group); Permission permission = permissionsManager.getCurrentUserPermission(group);
if (permission != Permission.ADMIN && permission != Permission.MANAGE_MEMBERS) { if (!Permission.includes(permission, Permission.MANAGE_MEMBERS)) {
throw new UnauthorizedException("Missing admin or manage members permissions"); throw new UnauthorizedException("Missing manage members permissions");
} }
return permission; return permission;
} }
......
...@@ -32,4 +32,25 @@ public enum Permission { ...@@ -32,4 +32,25 @@ public enum Permission {
return oldPermission; return oldPermission;
} }
public static boolean includes(Permission permission, Permission permissionToCheck) {
if (permissionToCheck == null) {
throw new IllegalArgumentException("Permission to check cannot be null");
}
if (permission == null) {
return false;
}
switch (permissionToCheck) {
case ADMIN:
return permission == ADMIN;
case MANAGE_MEMBERS:
return permission == MANAGE_MEMBERS || permission == ADMIN;
case VIEW_MEMBERS:
return permission != TRAVERSE;
case TRAVERSE:
return true;
}
return false;
}
} }
...@@ -40,9 +40,7 @@ public class RapUser { ...@@ -40,9 +40,7 @@ public class RapUser {
} }
if (displayName == null) { // No name and surname --> using primary email if (displayName == null) { // No name and surname --> using primary email
Identity primaryIdentity = identities.stream().filter(i -> i.isPrimary()).findFirst() displayName = getPrimaryEmail();
.orElseThrow(() -> new IllegalStateException("No primary identity for user " + id));
displayName = primaryIdentity.getEmail();
} }
// Adding types // Adding types
...@@ -56,4 +54,10 @@ public class RapUser { ...@@ -56,4 +54,10 @@ public class RapUser {
return displayName; return displayName;
} }
public String getPrimaryEmail() {
Identity primaryIdentity = identities.stream().filter(i -> i.isPrimary()).findFirst()
.orElseThrow(() -> new IllegalStateException("No primary identity for user " + id));
return primaryIdentity.getEmail();
}
} }
...@@ -17,7 +17,7 @@ logging.level.org.springframework.security=DEBUG ...@@ -17,7 +17,7 @@ logging.level.org.springframework.security=DEBUG
logging.level.org.springframework.jdbc=TRACE logging.level.org.springframework.jdbc=TRACE
logging.level.org.springframework.web=TRACE logging.level.org.springframework.web=TRACE
spring.datasource.url=jdbc:postgresql://localhost:5433/postgres spring.datasource.url=jdbc:postgresql://localhost:5432/gms2
spring.datasource.username=gms spring.datasource.username=gms
spring.datasource.password=gms spring.datasource.password=gms
......
package it.inaf.ia2.gms.model; package it.inaf.ia2.gms.model;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.JUnit4; import org.junit.runners.JUnit4;
...@@ -37,4 +39,32 @@ public class PermissionTest { ...@@ -37,4 +39,32 @@ public class PermissionTest {
assertEquals(Permission.MANAGE_MEMBERS, Permission.addPermission(Permission.TRAVERSE, Permission.MANAGE_MEMBERS)); assertEquals(Permission.MANAGE_MEMBERS, Permission.addPermission(Permission.TRAVERSE, Permission.MANAGE_MEMBERS));
assertEquals(Permission.VIEW_MEMBERS, Permission.addPermission(Permission.TRAVERSE, Permission.VIEW_MEMBERS)); assertEquals(Permission.VIEW_MEMBERS, Permission.addPermission(Permission.TRAVERSE, Permission.VIEW_MEMBERS));
} }
@Test
public void includesTest() {
assertTrue(Permission.includes(Permission.ADMIN, Permission.ADMIN));
assertFalse(Permission.includes(Permission.MANAGE_MEMBERS, Permission.ADMIN));
assertFalse(Permission.includes(Permission.VIEW_MEMBERS, Permission.ADMIN));
assertFalse(Permission.includes(Permission.TRAVERSE, Permission.ADMIN));
assertFalse(Permission.includes(null, Permission.ADMIN));
assertTrue(Permission.includes(Permission.ADMIN, Permission.MANAGE_MEMBERS));
assertTrue(Permission.includes(Permission.MANAGE_MEMBERS, Permission.MANAGE_MEMBERS));
assertFalse(Permission.includes(Permission.VIEW_MEMBERS, Permission.MANAGE_MEMBERS));
assertFalse(Permission.includes(Permission.TRAVERSE, Permission.MANAGE_MEMBERS));
assertFalse(Permission.includes(null, Permission.MANAGE_MEMBERS));
assertTrue(Permission.includes(Permission.ADMIN, Permission.VIEW_MEMBERS));
assertTrue(Permission.includes(Permission.MANAGE_MEMBERS, Permission.VIEW_MEMBERS));
assertTrue(Permission.includes(Permission.VIEW_MEMBERS, Permission.VIEW_MEMBERS));
assertFalse(Permission.includes(Permission.TRAVERSE, Permission.VIEW_MEMBERS));
assertFalse(Permission.includes(null, Permission.ADMIN));
assertTrue(Permission.includes(Permission.ADMIN, Permission.TRAVERSE));
assertTrue(Permission.includes(Permission.MANAGE_MEMBERS, Permission.TRAVERSE));
assertTrue(Permission.includes(Permission.VIEW_MEMBERS, Permission.TRAVERSE));
assertTrue(Permission.includes(Permission.TRAVERSE, Permission.TRAVERSE));
assertFalse(Permission.includes(null, Permission.TRAVERSE));
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment