Skip to content
Commits on Source (5)
import os
base_cmd = "java -jar ~/code/ia2-gms/gms-client/gms-cli/target/gms-cli.jar --token-file ~/Downloads/token.txt --config-file ~/code/ia2-gms/gms-client/gms-cli/gms.properties "
def exec(cmd):
result = os.popen(base_cmd + cmd).read()
print(result)
return result
assert exec("create-group test false") == "Group created\n"
assert exec("create-group test.test2 true") == "Group created\n"
assert exec("list-groups test") == "test2\n"
assert exec("add-member test.test2 2386") == "Member added\n"
assert exec("add-permission test.test2 2386 VIEW_MEMBERS") == "Permission added\n"
exec("get-user-permissions 2386")
assert exec("get-group-permissions test.test2") == "2386 VIEW_MEMBERS\n"
exec("get-member-email-addresses test.test2 VIEW_MEMBERS")
exec("get-user-groups 2386")
assert exec("set-permission test.test2 2386 ADMIN") == "Permission changed\n"
assert exec("get-group-permissions test.test2") == "2386 ADMIN\n"
assert exec("delete-permission test.test2 2386") == "Permission removed\n"
assert exec("get-group-permissions test.test2") == ""
exec("remove-member test.test2 2386")
exec("get-member-email-addresses test.test2 VIEW_MEMBERS") == ""
exec("delete-group test.test2")
assert exec("list-groups test") == ""
gms_url=http://localhost:8082/gms/ws/jwt gms_url=http://localhost:8082/gms
client_id=gms_cli client_id=gms_cli
client_secret=gms client_secret=gms
rap_url=http://localhost/rap-ia2 rap_url=http://localhost/rap-ia2
...@@ -20,6 +20,11 @@ ...@@ -20,6 +20,11 @@
<artifactId>gms-client</artifactId> <artifactId>gms-client</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<finalName>gms-cli</finalName> <finalName>gms-cli</finalName>
......
...@@ -2,7 +2,9 @@ package it.inaf.ia2.gms.cli; ...@@ -2,7 +2,9 @@ package it.inaf.ia2.gms.cli;
import it.inaf.ia2.client.ClientException; import it.inaf.ia2.client.ClientException;
import it.inaf.ia2.gms.client.GmsClient; import it.inaf.ia2.gms.client.GmsClient;
import it.inaf.ia2.gms.client.model.GroupPermission;
import it.inaf.ia2.gms.client.model.Permission; import it.inaf.ia2.gms.client.model.Permission;
import it.inaf.ia2.gms.client.model.UserPermission;
import it.inaf.ia2.rap.client.ClientCredentialsRapClient; import it.inaf.ia2.rap.client.ClientCredentialsRapClient;
import it.inaf.ia2.rap.client.RapClient; import it.inaf.ia2.rap.client.RapClient;
import it.inaf.ia2.rap.data.AccessTokenResponse; import it.inaf.ia2.rap.data.AccessTokenResponse;
...@@ -74,6 +76,10 @@ public class CLI { ...@@ -74,6 +76,10 @@ public class CLI {
} }
argIndex++; argIndex++;
} }
if (!commandParsed) {
displayUsage();
}
} }
private String getNextArg() { private String getNextArg() {
...@@ -159,6 +165,16 @@ public class CLI { ...@@ -159,6 +165,16 @@ public class CLI {
private void parseCommand() { private void parseCommand() {
switch (args[argIndex]) { switch (args[argIndex]) {
case "list-groups": {
String parent = "";
if (args.length == argIndex + 2) {
parent = args[argIndex + 1];
}
for (String group : client.listGroups(parent, false)) {
System.out.println(group);
}
break;
}
case "create-group": case "create-group":
boolean leaf = false; boolean leaf = false;
if (argIndex + 2 < args.length) { if (argIndex + 2 < args.length) {
...@@ -167,10 +183,31 @@ public class CLI { ...@@ -167,10 +183,31 @@ public class CLI {
client.createGroup(args[argIndex + 1], leaf); client.createGroup(args[argIndex + 1], leaf);
System.out.println("Group created"); System.out.println("Group created");
break; break;
case "get-group-permissions": {
String parent = "";
if (args.length == argIndex + 2) {
parent = args[argIndex + 1];
}
for (GroupPermission gp : client.getGroupPermissions(parent)) {
System.out.println(gp.getUserId() + " " + gp.getPermission());
}
break;
}
case "delete-group": case "delete-group":
client.deleteGroup(args[argIndex + 1]); client.deleteGroup(getNextArg());
System.out.println("Group deleted"); System.out.println("Group deleted");
break; break;
case "get-user-groups": {
String userId = getNextArg();
String parent = "";
if (args.length == argIndex + 2) {
parent = args[argIndex + 1];
}
for (String group : client.getUserGroups(userId, parent)) {
System.out.println(group);
}
break;
}
case "add-member": case "add-member":
if (argIndex + 2 >= args.length) { if (argIndex + 2 >= args.length) {
displayUsage(); displayUsage();
...@@ -185,6 +222,11 @@ public class CLI { ...@@ -185,6 +222,11 @@ public class CLI {
client.removeMember(args[argIndex + 1], args[argIndex + 2]); client.removeMember(args[argIndex + 1], args[argIndex + 2]);
System.out.println("Member removed"); System.out.println("Member removed");
break; break;
case "get-user-permissions":
for (UserPermission up : client.getUserPermissions(getNextArg())) {
System.out.println(up.getGroup() + " " + up.getPermission());
}
break;
case "set-permission": case "set-permission":
if (argIndex + 3 >= args.length) { if (argIndex + 3 >= args.length) {
displayUsage(); displayUsage();
...@@ -230,8 +272,12 @@ public class CLI { ...@@ -230,8 +272,12 @@ public class CLI {
+ " [--rap-url <url>]\n" + " [--rap-url <url>]\n"
+ " [--client-id <id>]\n" + " [--client-id <id>]\n"
+ " [--client-secret <secret>]\n" + " [--client-secret <secret>]\n"
+ " list-groups [<name1.name2.name3>]\n"
+ " create-group <name1.name2.name3> [<leaf>]\n" + " create-group <name1.name2.name3> [<leaf>]\n"
+ " delete-group <name1.name2.name3>\n" + " delete-group <name1.name2.name3>\n"
+ " get-user-groups <user_id> [<name1.name2.name3>]\n"
+ " get-group-permissions [<name1.name2.name3>]\n"
+ " get-user-permissions <user_id>\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"
+ " set-permission <name1.name2.name3> <user_id> <permission>\n" + " set-permission <name1.name2.name3> <user_id> <permission>\n"
......
...@@ -9,6 +9,12 @@ ...@@ -9,6 +9,12 @@
<b-spinner variant="primary" style="width: 3rem; height: 3rem;" label="Loading"></b-spinner> <b-spinner variant="primary" style="width: 3rem; height: 3rem;" label="Loading"></b-spinner>
</div> </div>
</div> </div>
<div class="mt-4">
<p class="text-center">&mdash;&nbsp; Powered by
<img src="@/assets/logo-ia2-small.jpg" alt="logo IA2" /> &nbsp;
<a href="https://www.ia2.inaf.it/" target="_blank">IA2</a> &nbsp;&mdash;
</p>
</div>
</div> </div>
</template> </template>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<!-- Right aligned nav items --> <!-- Right aligned nav items -->
<b-navbar-nav class="ml-auto"> <b-navbar-nav class="ml-auto">
<b-nav-item href="help/index.html" target="blank_" class="mr-4">Help</b-nav-item> <b-nav-item href="help/index.html" target="_blank" class="mr-4">Help</b-nav-item>
<b-nav-form> <b-nav-form>
<b-form-input size="sm" class="mr-sm-2" placeholder="Search" v-model.trim="input.genericSearch.filter" @keydown.native.enter.prevent="genericSearch"></b-form-input> <b-form-input size="sm" class="mr-sm-2" placeholder="Search" v-model.trim="input.genericSearch.filter" @keydown.native.enter.prevent="genericSearch"></b-form-input>
<b-button size="sm" type="button" v-on:click="genericSearch()">Search</b-button> <b-button size="sm" type="button" v-on:click="genericSearch()">Search</b-button>
......
...@@ -3,6 +3,7 @@ package it.inaf.ia2.gms.authn; ...@@ -3,6 +3,7 @@ package it.inaf.ia2.gms.authn;
import it.inaf.ia2.aa.UserManager; import it.inaf.ia2.aa.UserManager;
import it.inaf.ia2.aa.data.User; import it.inaf.ia2.aa.data.User;
import it.inaf.ia2.gms.persistence.LoggingDAO; import it.inaf.ia2.gms.persistence.LoggingDAO;
import it.inaf.ia2.gms.persistence.model.ActionType;
import java.io.IOException; import java.io.IOException;
import java.security.Principal; import java.security.Principal;
import java.util.Map; import java.util.Map;
...@@ -55,13 +56,13 @@ public class JWTFilter implements Filter { ...@@ -55,13 +56,13 @@ public class JWTFilter implements Filter {
Map<String, Object> claims = userManager.parseIdTokenClaims(token); Map<String, Object> claims = userManager.parseIdTokenClaims(token);
if (claims.get("sub") == null) { if (claims.get("sub") == null) {
loggingDAO.logAction("Attempt to access WS with invalid token", request); loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Attempt to access API with invalid token", request);
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid access token: missing sub claim"); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid access token: missing sub claim");
return; return;
} }
ServletRequestWithJWTPrincipal wrappedRequest = new ServletRequestWithJWTPrincipal(request, token, claims); ServletRequestWithJWTPrincipal wrappedRequest = new ServletRequestWithJWTPrincipal(request, token, claims);
loggingDAO.logAction("WS access from " + wrappedRequest.getUserPrincipal().getName(), request); loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "API access from " + wrappedRequest.getUserPrincipal().getName(), request);
fc.doFilter(wrappedRequest, res); fc.doFilter(wrappedRequest, res);
} }
......
...@@ -11,9 +11,12 @@ import it.inaf.ia2.gms.persistence.model.GroupEntity; ...@@ -11,9 +11,12 @@ import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.service.GroupNameService; import it.inaf.ia2.gms.service.GroupNameService;
import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.gms.service.GroupsService;
import it.inaf.ia2.rap.data.RapUser; import it.inaf.ia2.rap.data.RapUser;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
...@@ -84,6 +87,20 @@ public class MembersController { ...@@ -84,6 +87,20 @@ public class MembersController {
return new PaginatedData<>(members, request.getPaginatorPage(), request.getPaginatorPageSize()); return new PaginatedData<>(members, request.getPaginatorPage(), request.getPaginatorPageSize());
} }
@GetMapping(value = "/membership", produces = MediaType.TEXT_PLAIN_VALUE)
public void getMembership(@RequestParam("group") Optional<String> groupNames, @RequestParam("user_id") String userId, HttpServletResponse response) throws IOException {
GroupEntity parent = groupNameService.getGroupFromNames(groupNames);
List<GroupEntity> groups = membershipManager.getUserGroups(parent, userId);
try ( PrintWriter pw = new PrintWriter(response.getOutputStream())) {
for (String groupName : groupNameService.getGroupsNames(groups)) {
pw.println(groupNameService.getShortGroupName(groupName, groupNames));
}
}
}
@PostMapping(value = "/membership", produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) @PostMapping(value = "/membership", produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void addMember(@RequestParam("group") Optional<String> groupNames, public void addMember(@RequestParam("group") Optional<String> groupNames,
@RequestParam("user_id") String targetUserId) { @RequestParam("user_id") String targetUserId) {
......
...@@ -4,6 +4,7 @@ import it.inaf.ia2.gms.exception.BadRequestException; ...@@ -4,6 +4,7 @@ import it.inaf.ia2.gms.exception.BadRequestException;
import it.inaf.ia2.gms.exception.UnauthorizedException; import it.inaf.ia2.gms.exception.UnauthorizedException;
import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.persistence.LoggingDAO; import it.inaf.ia2.gms.persistence.LoggingDAO;
import it.inaf.ia2.gms.persistence.model.ActionType;
import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.PermissionEntity; import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.gms.service.GroupsService;
...@@ -84,14 +85,14 @@ public class GroupsManager extends UserAwareComponent { ...@@ -84,14 +85,14 @@ public class GroupsManager extends UserAwareComponent {
public void verifyUserCanReadGroup(GroupEntity group) { public void verifyUserCanReadGroup(GroupEntity group) {
if (permissionsManager.getCurrentUserPermission(group) == null) { if (permissionsManager.getCurrentUserPermission(group) == null) {
loggingDAO.logAction("Unauthorized group management request, group_id=" + group.getId()); loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Unauthorized group management request, group_id=" + group.getId());
throw new UnauthorizedException("Missing permission to see this group"); throw new UnauthorizedException("Missing permission to see this group");
} }
} }
private void verifyUserCanManageGroup(GroupEntity group) { private void verifyUserCanManageGroup(GroupEntity group) {
if (permissionsManager.getCurrentUserPermission(group) != Permission.ADMIN) { if (permissionsManager.getCurrentUserPermission(group) != Permission.ADMIN) {
loggingDAO.logAction("Unauthorized group management request, group_id=" + group.getId()); loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Unauthorized group management request, group_id=" + group.getId());
throw new UnauthorizedException("Missing admin permission"); throw new UnauthorizedException("Missing admin permission");
} }
} }
......
...@@ -14,6 +14,7 @@ import it.inaf.ia2.gms.persistence.model.InvitedRegistration; ...@@ -14,6 +14,7 @@ import it.inaf.ia2.gms.persistence.model.InvitedRegistration;
import it.inaf.ia2.gms.persistence.model.MembershipEntity; import it.inaf.ia2.gms.persistence.model.MembershipEntity;
import it.inaf.ia2.gms.service.PermissionsService; import it.inaf.ia2.gms.service.PermissionsService;
import it.inaf.ia2.gms.authn.RapClient; import it.inaf.ia2.gms.authn.RapClient;
import static it.inaf.ia2.gms.persistence.model.ActionType.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
...@@ -68,6 +69,7 @@ public class InvitedRegistrationManager extends UserAwareComponent { ...@@ -68,6 +69,7 @@ public class InvitedRegistrationManager extends UserAwareComponent {
for (Map.Entry<GroupEntity, Permission> entry : groupsPermissions.entrySet()) { for (Map.Entry<GroupEntity, Permission> entry : groupsPermissions.entrySet()) {
GroupEntity group = entry.getKey(); GroupEntity group = entry.getKey();
if (permissionsManager.getCurrentUserPermission(group) != Permission.ADMIN) { if (permissionsManager.getCurrentUserPermission(group) != Permission.ADMIN) {
loggingDAO.logAction(UNAUTHORIZED_ACCESS_ATTEMPT, "Attempt to add invited registration for group " + group.getId());
throw new UnauthorizedException("You don't have the permission to perform invited registrations"); throw new UnauthorizedException("You don't have the permission to perform invited registrations");
} }
groupIdsPermissions.put(group.getId(), entry.getValue()); groupIdsPermissions.put(group.getId(), entry.getValue());
...@@ -80,6 +82,8 @@ public class InvitedRegistrationManager extends UserAwareComponent { ...@@ -80,6 +82,8 @@ public class InvitedRegistrationManager extends UserAwareComponent {
.setGroupsPermissions(groupIdsPermissions); .setGroupsPermissions(groupIdsPermissions);
invitedRegistrationDAO.addInvitedRegistration(invitedRegistration); invitedRegistrationDAO.addInvitedRegistration(invitedRegistration);
loggingDAO.logAction(INVITED_REGISTRATION_ADDED, "Email=" + email);
} }
public InvitedRegistration getInvitedRegistrationFromToken(String token) { public InvitedRegistration getInvitedRegistrationFromToken(String token) {
...@@ -94,7 +98,7 @@ public class InvitedRegistrationManager extends UserAwareComponent { ...@@ -94,7 +98,7 @@ public class InvitedRegistrationManager extends UserAwareComponent {
httpSession.setAttribute(INVITED_REGISTRATION, invitedRegistration); httpSession.setAttribute(INVITED_REGISTRATION, invitedRegistration);
loggingDAO.logAction("Started invited registration for email " + invitedRegistration.getEmail()); loggingDAO.logAction(INVITED_REGISTRATION_OPENED, "Started invited registration for email " + invitedRegistration.getEmail());
return invitedRegistration; return invitedRegistration;
} catch (NoSuchAlgorithmException ex) { } catch (NoSuchAlgorithmException ex) {
...@@ -144,9 +148,11 @@ public class InvitedRegistrationManager extends UserAwareComponent { ...@@ -144,9 +148,11 @@ public class InvitedRegistrationManager extends UserAwareComponent {
} }
private void completeInvitedRegistration(InvitedRegistration invitedRegistration) { private void completeInvitedRegistration(InvitedRegistration invitedRegistration) {
String userId = getCurrentUserId();
for (Map.Entry<String, Permission> entry : invitedRegistration.getGroupsPermissions().entrySet()) { for (Map.Entry<String, Permission> entry : invitedRegistration.getGroupsPermissions().entrySet()) {
String groupId = entry.getKey(); String groupId = entry.getKey();
String userId = getCurrentUserId();
GroupEntity groupEntity = groupsDAO.findGroupById(groupId).get(); GroupEntity groupEntity = groupsDAO.findGroupById(groupId).get();
...@@ -156,11 +162,14 @@ public class InvitedRegistrationManager extends UserAwareComponent { ...@@ -156,11 +162,14 @@ public class InvitedRegistrationManager extends UserAwareComponent {
membershipEntity.setCreatedBy(getCurrentUserId()); membershipEntity.setCreatedBy(getCurrentUserId());
membershipsDAO.addMember(membershipEntity); membershipsDAO.addMember(membershipEntity);
permissionsService.addPermission(groupEntity, userId, entry.getValue(), getCurrentUserId()); permissionsService.addPermission(groupEntity, userId, entry.getValue(), userId);
} }
invitedRegistration.setUserId(getCurrentUserId()); invitedRegistration.setUserId(userId);
invitedRegistrationDAO.setRegistrationDone(invitedRegistration); invitedRegistrationDAO.setRegistrationDone(invitedRegistration);
loggingDAO.logAction(INVITED_REGISTRATION_COMPLETED, "user_id=" + userId + " groups=["
+ String.join(",", invitedRegistration.getGroupsPermissions().keySet()) + "]");
} }
public List<InvitedRegistrationItem> getInvitedRegistrationsForGroup(GroupEntity group) { public List<InvitedRegistrationItem> getInvitedRegistrationsForGroup(GroupEntity group) {
...@@ -201,7 +210,7 @@ public class InvitedRegistrationManager extends UserAwareComponent { ...@@ -201,7 +210,7 @@ public class InvitedRegistrationManager extends UserAwareComponent {
invitedRegistrationDAO.deleteInvitedRegistrationRequest(registrationId, groupId); invitedRegistrationDAO.deleteInvitedRegistrationRequest(registrationId, groupId);
loggingDAO.logAction("Deleted invited registration request. " loggingDAO.logAction(INVITED_REGISTRATION_DELETED, "Deleted invited registration request. "
+ "[request_id=" + registrationId + ", group_id=" + groupId + "[request_id=" + registrationId + ", group_id=" + groupId
+ ", group_name=" + group.getName() + "]"); + ", group_name=" + group.getName() + "]");
} }
......
...@@ -10,6 +10,7 @@ import it.inaf.ia2.gms.persistence.model.MembershipEntity; ...@@ -10,6 +10,7 @@ import it.inaf.ia2.gms.persistence.model.MembershipEntity;
import it.inaf.ia2.gms.persistence.model.PermissionEntity; import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.service.PermissionUtils; import it.inaf.ia2.gms.service.PermissionUtils;
import it.inaf.ia2.gms.authn.RapClient; import it.inaf.ia2.gms.authn.RapClient;
import static it.inaf.ia2.gms.persistence.model.ActionType.*;
import it.inaf.ia2.rap.data.RapUser; import it.inaf.ia2.rap.data.RapUser;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
...@@ -49,6 +50,7 @@ public class MembershipManager extends UserAwareComponent { ...@@ -49,6 +50,7 @@ public class MembershipManager extends UserAwareComponent {
Permission groupPermission = permissionsManager.getCurrentUserPermission(group); Permission groupPermission = permissionsManager.getCurrentUserPermission(group);
if (!Permission.includes(groupPermission, Permission.VIEW_MEMBERS)) { if (!Permission.includes(groupPermission, Permission.VIEW_MEMBERS)) {
loggingDAO.logAction(UNAUTHORIZED_ACCESS_ATTEMPT, "Attempted to view members of group " + group.getId());
throw new UnauthorizedException("You don't have the permission to view members"); throw new UnauthorizedException("You don't have the permission to view members");
} }
...@@ -86,7 +88,7 @@ public class MembershipManager extends UserAwareComponent { ...@@ -86,7 +88,7 @@ public class MembershipManager extends UserAwareComponent {
membership.setCreatedBy(getCurrentUserId()); membership.setCreatedBy(getCurrentUserId());
membership = membershipsDAO.addMember(membership); membership = membershipsDAO.addMember(membership);
loggingDAO.logAction("Added member, group_id=" + group.getId() + ", user_id=" + userId); loggingDAO.logAction(MEMBER_ADDED, "Added member, group_id=" + group.getId() + ", user_id=" + userId);
return membership; return membership;
} }
...@@ -94,12 +96,13 @@ public class MembershipManager extends UserAwareComponent { ...@@ -94,12 +96,13 @@ public class MembershipManager extends UserAwareComponent {
public void removeMember(GroupEntity group, String userId) { public void removeMember(GroupEntity group, String userId) {
verifyUserCanManageMembers(group); verifyUserCanManageMembers(group);
membershipsDAO.removeMembership(group.getId(), userId); membershipsDAO.removeMembership(group.getId(), userId);
loggingDAO.logAction("Member removed, group_id=" + group.getId() + ", user_id=" + userId); loggingDAO.logAction(MEMBER_REMOVED, "Member removed, group_id=" + group.getId() + ", user_id=" + userId);
} }
private Permission verifyUserCanManageMembers(GroupEntity group) { private Permission verifyUserCanManageMembers(GroupEntity group) {
Permission permission = permissionsManager.getCurrentUserPermission(group); Permission permission = permissionsManager.getCurrentUserPermission(group);
if (!Permission.includes(permission, Permission.MANAGE_MEMBERS)) { if (!Permission.includes(permission, Permission.MANAGE_MEMBERS)) {
loggingDAO.logAction(UNAUTHORIZED_ACCESS_ATTEMPT, "Attempted to manage members of group " + group.getId());
throw new UnauthorizedException("Missing manage members permissions"); throw new UnauthorizedException("Missing manage members permissions");
} }
return permission; return permission;
......
...@@ -9,6 +9,7 @@ import it.inaf.ia2.gms.persistence.model.PermissionEntity; ...@@ -9,6 +9,7 @@ import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.service.PermissionUtils; import it.inaf.ia2.gms.service.PermissionUtils;
import it.inaf.ia2.gms.service.PermissionsService; import it.inaf.ia2.gms.service.PermissionsService;
import it.inaf.ia2.gms.authn.RapClient; import it.inaf.ia2.gms.authn.RapClient;
import it.inaf.ia2.gms.persistence.model.ActionType;
import it.inaf.ia2.rap.data.RapUser; import it.inaf.ia2.rap.data.RapUser;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -144,7 +145,7 @@ public class PermissionsManager extends UserAwareComponent { ...@@ -144,7 +145,7 @@ public class PermissionsManager extends UserAwareComponent {
} }
private Supplier<UnauthorizedException> unauthorizedExceptionSupplier(GroupEntity group) { private Supplier<UnauthorizedException> unauthorizedExceptionSupplier(GroupEntity group) {
loggingDAO.logAction("Unauthorized attempt to manage permissions [group_id=" + group.getId() + "]"); loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Unauthorized attempt to manage permissions [group_id=" + group.getId() + "]");
return () -> new UnauthorizedException("You don't have the privileges for managing the requested permission"); return () -> new UnauthorizedException("You don't have the privileges for managing the requested permission");
} }
......
package it.inaf.ia2.gms.persistence; package it.inaf.ia2.gms.persistence;
import it.inaf.ia2.gms.persistence.model.ActionType;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
...@@ -52,19 +53,20 @@ public class LoggingDAO { ...@@ -52,19 +53,20 @@ public class LoggingDAO {
return sw.toString(); return sw.toString();
} }
public void logAction(String action) { public void logAction(ActionType type, String action) {
logAction(action, request); logAction(type, action, request);
} }
public void logAction(String action, HttpServletRequest request) { public void logAction(ActionType type, String description, HttpServletRequest request) {
try { try {
String sql = "INSERT INTO audit_log (\"user\", action, ip_address) VALUES (?, ?, ?)"; String sql = "INSERT INTO audit_log (\"user\", action_type, description, ip_address) VALUES (?, ?, ?, ?)";
jdbcTemplate.update(conn -> { jdbcTemplate.update(conn -> {
PreparedStatement ps = conn.prepareStatement(sql); PreparedStatement ps = conn.prepareStatement(sql);
int i = 0; int i = 0;
ps.setString(++i, getUser(request)); ps.setString(++i, getUser(request));
ps.setString(++i, action); ps.setString(++i, type.toString());
ps.setString(++i, description);
ps.setString(++i, getIPAddress(request)); ps.setString(++i, getIPAddress(request));
return ps; return ps;
}); });
......
package it.inaf.ia2.gms.persistence.model;
public enum ActionType {
GROUP_CREATED,
GROUP_DELETED,
GROUP_UPDATED,
MEMBER_ADDED,
MEMBER_REMOVED,
PERMISSION_ADDED,
PERMISSION_UPDATED,
PERMISSION_REMOVED,
JOIN,
INVITED_REGISTRATION_ADDED,
INVITED_REGISTRATION_OPENED,
INVITED_REGISTRATION_DELETED,
INVITED_REGISTRATION_COMPLETED,
UNAUTHORIZED_ACCESS_ATTEMPT
}
...@@ -85,8 +85,13 @@ public class GroupNameService { ...@@ -85,8 +85,13 @@ public class GroupNameService {
} }
public String getShortGroupName(String completeGroupName, Optional<String> groupPrefix) { public String getShortGroupName(String completeGroupName, Optional<String> groupPrefix) {
if (groupPrefix.isPresent()) { if (groupPrefix.isPresent() && !groupPrefix.get().isBlank()) {
return completeGroupName.substring(groupPrefix.get().length() + 1); if (groupPrefix.get().endsWith(".")) {
// this branch is kept for retro-compatibility with old API, it will be removed in the future
return completeGroupName.substring(groupPrefix.get().length());
} else {
return completeGroupName.substring(groupPrefix.get().length() + 1);
}
} }
return completeGroupName; return completeGroupName;
} }
......
...@@ -10,6 +10,7 @@ import it.inaf.ia2.gms.persistence.InvitedRegistrationDAO; ...@@ -10,6 +10,7 @@ import it.inaf.ia2.gms.persistence.InvitedRegistrationDAO;
import it.inaf.ia2.gms.persistence.LoggingDAO; import it.inaf.ia2.gms.persistence.LoggingDAO;
import it.inaf.ia2.gms.persistence.MembershipsDAO; import it.inaf.ia2.gms.persistence.MembershipsDAO;
import it.inaf.ia2.gms.persistence.PermissionsDAO; import it.inaf.ia2.gms.persistence.PermissionsDAO;
import static it.inaf.ia2.gms.persistence.model.ActionType.*;
import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.GroupEntity;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
...@@ -74,7 +75,7 @@ public class GroupsService { ...@@ -74,7 +75,7 @@ public class GroupsService {
group.setCreationTime(new Date()); group.setCreationTime(new Date());
groupsDAO.createGroup(group); groupsDAO.createGroup(group);
loggingDAO.logAction("Added group: parent_path=" + parent.getPath() + ", group_name=" + groupName); loggingDAO.logAction(GROUP_CREATED, "Added group: parent_path=" + parent.getPath() + ", group_name=" + groupName);
return group; return group;
} }
...@@ -90,7 +91,7 @@ public class GroupsService { ...@@ -90,7 +91,7 @@ public class GroupsService {
group.setLeaf(leaf); group.setLeaf(leaf);
GroupEntity entity = groupsDAO.updateGroup(group); GroupEntity entity = groupsDAO.updateGroup(group);
loggingDAO.logAction("Group updated, group_id=" + group.getId() loggingDAO.logAction(GROUP_UPDATED, "Group updated, group_id=" + group.getId()
+ ", new name: " + newGroupName + ", leaf: " + leaf); + ", new name: " + newGroupName + ", leaf: " + leaf);
return entity; return entity;
...@@ -124,7 +125,7 @@ public class GroupsService { ...@@ -124,7 +125,7 @@ public class GroupsService {
groupsDAO.deleteGroup(g); groupsDAO.deleteGroup(g);
} }
loggingDAO.logAction("Group deleted [group_id=" + group.getId() + ", group_name=" + group.getName() + "]"); loggingDAO.logAction(GROUP_DELETED, "Group deleted [group_id=" + group.getId() + ", group_name=" + group.getName() + "]");
return parent; return parent;
} }
......
...@@ -2,11 +2,14 @@ package it.inaf.ia2.gms.service; ...@@ -2,11 +2,14 @@ package it.inaf.ia2.gms.service;
import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.persistence.JoinDAO; import it.inaf.ia2.gms.persistence.JoinDAO;
import it.inaf.ia2.gms.persistence.LoggingDAO;
import it.inaf.ia2.gms.persistence.MembershipsDAO; import it.inaf.ia2.gms.persistence.MembershipsDAO;
import it.inaf.ia2.gms.persistence.PermissionsDAO; import it.inaf.ia2.gms.persistence.PermissionsDAO;
import it.inaf.ia2.gms.persistence.model.ActionType;
import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.MembershipEntity; import it.inaf.ia2.gms.persistence.model.MembershipEntity;
import it.inaf.ia2.gms.persistence.model.PermissionEntity; import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -25,6 +28,9 @@ public class JoinService { ...@@ -25,6 +28,9 @@ public class JoinService {
@Autowired @Autowired
private JoinDAO joinDAO; private JoinDAO joinDAO;
@Autowired
private LoggingDAO loggingDAO;
public String join(String userId1, String userId2) { public String join(String userId1, String userId2) {
List<GroupEntity> user1Groups = membershipsDAO.getUserMemberships(userId1); List<GroupEntity> user1Groups = membershipsDAO.getUserMemberships(userId1);
...@@ -61,9 +67,22 @@ public class JoinService { ...@@ -61,9 +67,22 @@ public class JoinService {
joinDAO.join(membershipsToAdd, permissionsToAdd, deletingUserId); joinDAO.join(membershipsToAdd, permissionsToAdd, deletingUserId);
loggingDAO.logAction(ActionType.JOIN, "removed_user=" + deletingUserId
+ " added_memberships: " + String.join(", ", getAddedGroups(membershipsToAdd))
+ " added_permissions: " + String.join(", ", getAddedPermissions(permissionsToAdd))
);
return remainingUserId; return remainingUserId;
} }
private List<String> getAddedGroups(Set<MembershipEntity> membershipsToAdd) {
return membershipsToAdd.stream().map(m -> m.getGroupId()).collect(Collectors.toList());
}
private List<String> getAddedPermissions(Set<PermissionEntity> permissionsToAdd) {
return permissionsToAdd.stream().map(m -> "(" + m.getGroupId() + "," + m.getPermission() + ")").collect(Collectors.toList());
}
private MembershipEntity getMembershipEntity(String groupId, String userId) { private MembershipEntity getMembershipEntity(String groupId, String userId) {
MembershipEntity entity = new MembershipEntity(); MembershipEntity entity = new MembershipEntity();
entity.setGroupId(groupId); entity.setGroupId(groupId);
......
...@@ -4,6 +4,7 @@ import it.inaf.ia2.gms.model.Permission; ...@@ -4,6 +4,7 @@ import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.persistence.LoggingDAO; import it.inaf.ia2.gms.persistence.LoggingDAO;
import it.inaf.ia2.gms.persistence.model.PermissionEntity; import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.persistence.PermissionsDAO; import it.inaf.ia2.gms.persistence.PermissionsDAO;
import static it.inaf.ia2.gms.persistence.model.ActionType.*;
import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.GroupEntity;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
...@@ -36,7 +37,7 @@ public class PermissionsService { ...@@ -36,7 +37,7 @@ public class PermissionsService {
public void removePermission(GroupEntity group, String userId) { public void removePermission(GroupEntity group, String userId) {
permissionsDAO.deletePermission(group.getId(), userId); permissionsDAO.deletePermission(group.getId(), userId);
loggingDAO.logAction("Removed permission for " + userId + "in group " + group.getId()); loggingDAO.logAction(PERMISSION_REMOVED, "Removed permission for " + userId + " in group " + group.getId());
} }
public PermissionEntity addPermission(GroupEntity group, String userId, Permission permission, String setBy) { public PermissionEntity addPermission(GroupEntity group, String userId, Permission permission, String setBy) {
...@@ -62,7 +63,7 @@ public class PermissionsService { ...@@ -62,7 +63,7 @@ public class PermissionsService {
} }
permissionEntity = permissionsDAO.createOrUpdatePermission(permissionEntity); permissionEntity = permissionsDAO.createOrUpdatePermission(permissionEntity);
loggingDAO.logAction("Added " + permission + " permission for " + userId + "in group " + group.getId()); loggingDAO.logAction(PERMISSION_ADDED, "Added " + permission + " permission for " + userId + " in group " + group.getId());
return permissionEntity; return permissionEntity;
} }
...@@ -76,7 +77,10 @@ public class PermissionsService { ...@@ -76,7 +77,10 @@ public class PermissionsService {
permissionEntity.setGroupPath(group.getPath()); permissionEntity.setGroupPath(group.getPath());
permissionEntity.setSetBy(setBy); permissionEntity.setSetBy(setBy);
return permissionsDAO.createOrUpdatePermission(permissionEntity); permissionEntity = permissionsDAO.createOrUpdatePermission(permissionEntity);
loggingDAO.logAction(PERMISSION_ADDED, "Added " + permission + " permission for " + userId + " in group " + group.getId());
return permissionEntity;
} }
public PermissionEntity updatePermission(GroupEntity group, String userId, Permission permission, String setBy) { public PermissionEntity updatePermission(GroupEntity group, String userId, Permission permission, String setBy) {
...@@ -87,6 +91,9 @@ public class PermissionsService { ...@@ -87,6 +91,9 @@ public class PermissionsService {
permissionEntity.setSetBy(setBy); permissionEntity.setSetBy(setBy);
permissionEntity.setPermission(permission); permissionEntity.setPermission(permission);
return permissionsDAO.updatePermission(permissionEntity); permissionEntity = permissionsDAO.updatePermission(permissionEntity);
loggingDAO.logAction(PERMISSION_UPDATED, "Updated permission for " + userId + " in group " + group.getId() + " to " + permission);
return permissionEntity;
} }
} }
...@@ -48,7 +48,8 @@ CREATE TABLE audit_log ( ...@@ -48,7 +48,8 @@ CREATE TABLE audit_log (
"date" timestamp DEFAULT NOW(), "date" timestamp DEFAULT NOW(),
"user" varchar, "user" varchar,
"ip_address" varchar, "ip_address" varchar,
"action" TEXT "action_type" varchar,
"description" TEXT
); );
CREATE TABLE invited_registration_request ( CREATE TABLE invited_registration_request (
......