mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-01 18:03:59 +00:00
-Added simple usermanagement service to enable creation of user role specific settings for the raceboard
-Added simple security roles for the AdminConsole.html and LeaderboardEditing.html -> the users and roles are defined in the realm.properties in the jetty config directory
This commit is contained in:
1 parent
abc98e86fd
commit
f7d35ffeff
11 files changed
+222
-14
No files matched your search
@@ -13,6 +13,16 @@
|
||||
<servlet-name>SailingService</servlet-name>
|
||||
<url-pattern>/sailing</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<display-name>User Management Service</display-name>
|
||||
<servlet-name>UserManagementService</servlet-name>
|
||||
<servlet-class>com.sap.sailing.gwt.ui.server.UserManagementServiceImpl</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>UserManagementService</servlet-name>
|
||||
<url-pattern>/usermanagement</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- enabling remote logging -->
|
||||
<servlet>
|
||||
@@ -24,4 +34,66 @@
|
||||
<servlet-name>remoteLoggingServlet</servlet-name>
|
||||
<url-pattern>/com.sap.sailing.gwt.ui.AdminConsole/remote_logging</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Administration pages</web-resource-name>
|
||||
<url-pattern>/AdminConsole.html</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>administrator</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<!-- Preparation of security constraints for the leaderboard and raceboard pages
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Raceboard pages</web-resource-name>
|
||||
<url-pattern>/RaceBoard.html</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>administrator</role-name>
|
||||
<role-name>spectator</role-name>
|
||||
<role-name>moderator</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Leaderboard pages</web-resource-name>
|
||||
<url-pattern>/Leaderboard.html</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>administrator</role-name>
|
||||
<role-name>spectator</role-name>
|
||||
<role-name>moderator</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
-->
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Leaderboard editing pages</web-resource-name>
|
||||
<url-pattern>/LeaderboardEditing.html</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>administrator</role-name>
|
||||
<role-name>moderator</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>user management pages</web-resource-name>
|
||||
<url-pattern>/UserManagement.html</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>administrator</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<login-config>
|
||||
<auth-method>BASIC</auth-method>
|
||||
<realm-name>SailingServerRealm</realm-name>
|
||||
</login-config>
|
||||
</web-app>
|
||||
+5
@@ -30,6 +30,11 @@ public abstract class AbstractEntryPoint implements EntryPoint, ErrorReporter {
|
||||
*/
|
||||
protected final SailingServiceAsync sailingService = GWT.create(SailingService.class);
|
||||
|
||||
/**
|
||||
* Create a remote service proxy to talk to the server-side user management service.
|
||||
*/
|
||||
protected final UserManagementServiceAsync userManagementService = GWT.create(UserManagementService.class);
|
||||
|
||||
/**
|
||||
* The message displayed to the user when the server cannot be reached or
|
||||
* returns an error.
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.sap.sailing.gwt.ui.client;
|
||||
|
||||
import com.google.gwt.user.client.rpc.RemoteService;
|
||||
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
|
||||
import com.sap.sailing.gwt.ui.shared.UserDTO;
|
||||
|
||||
@RemoteServiceRelativePath("usermanagement")
|
||||
public interface UserManagementService extends RemoteService {
|
||||
|
||||
public boolean isUserInRole(String userRole);
|
||||
|
||||
public UserDTO getUser();
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.sap.sailing.gwt.ui.client;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.gwt.ui.shared.UserDTO;
|
||||
|
||||
public interface UserManagementServiceAsync {
|
||||
|
||||
void isUserInRole(String userRole, AsyncCallback<Boolean> callback);
|
||||
|
||||
void getUser(AsyncCallback<UserDTO> callback);
|
||||
|
||||
}
|
||||
+11
-9
@@ -18,6 +18,7 @@ import com.sap.sailing.gwt.ui.shared.LeaderboardDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.UserDTO;
|
||||
|
||||
public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
private RaceDTO selectedRace;
|
||||
@@ -54,13 +55,14 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
final ParallelExecutionCallback<List<String>> getLeaderboardNamesCallback = new ParallelExecutionCallback<List<String>>();
|
||||
final ParallelExecutionCallback<List<EventDTO>> listEventsCallback = new ParallelExecutionCallback<List<EventDTO>>();
|
||||
final ParallelExecutionCallback<LeaderboardGroupDTO> getLeaderboardGroupByNameCallback = new ParallelExecutionCallback<LeaderboardGroupDTO>();
|
||||
final ParallelExecutionCallback<UserDTO> getUserCallback = new ParallelExecutionCallback<UserDTO>();
|
||||
|
||||
if (leaderboardGroupName != null) {
|
||||
new ParallelExecutionHolder(getLeaderboardNamesCallback, getLeaderboardGroupByNameCallback, listEventsCallback) {
|
||||
new ParallelExecutionHolder(getLeaderboardNamesCallback, getLeaderboardGroupByNameCallback, listEventsCallback, getUserCallback) {
|
||||
@Override
|
||||
public void handleSuccess() {
|
||||
checkUrlParameters(getLeaderboardNamesCallback.getData(),
|
||||
getLeaderboardGroupByNameCallback.getData(), listEventsCallback.getData());
|
||||
getLeaderboardGroupByNameCallback.getData(), listEventsCallback.getData(), getUserCallback.getData());
|
||||
}
|
||||
@Override
|
||||
public void handleFailure(Throwable t) {
|
||||
@@ -68,10 +70,10 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
}
|
||||
};
|
||||
} else {
|
||||
new ParallelExecutionHolder(getLeaderboardNamesCallback, listEventsCallback) {
|
||||
new ParallelExecutionHolder(getLeaderboardNamesCallback, listEventsCallback, getUserCallback) {
|
||||
@Override
|
||||
public void handleSuccess() {
|
||||
checkUrlParameters(getLeaderboardNamesCallback.getData(), null, listEventsCallback.getData());
|
||||
checkUrlParameters(getLeaderboardNamesCallback.getData(), null, listEventsCallback.getData(), getUserCallback.getData());
|
||||
}
|
||||
@Override
|
||||
public void handleFailure(Throwable t) {
|
||||
@@ -84,10 +86,10 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
sailingService.getLeaderboardNames(getLeaderboardNamesCallback);
|
||||
if(leaderboardGroupName != null)
|
||||
sailingService.getLeaderboardGroupByName(leaderboardGroupNameParamValue, getLeaderboardGroupByNameCallback);
|
||||
|
||||
userManagementService.getUser(getUserCallback);
|
||||
}
|
||||
|
||||
private void checkUrlParameters(List<String> leaderboardNames, LeaderboardGroupDTO leaderboardGroup, List<EventDTO> events)
|
||||
private void checkUrlParameters(List<String> leaderboardNames, LeaderboardGroupDTO leaderboardGroup, List<EventDTO> events, UserDTO user)
|
||||
{
|
||||
if (!leaderboardNames.contains(leaderboardName)) {
|
||||
createErrorPage(stringMessages.noSuchLeaderboard());
|
||||
@@ -114,7 +116,7 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
return;
|
||||
}
|
||||
|
||||
createRaceBoardPanel(selectedRace, events);
|
||||
createRaceBoardPanel(selectedRace, events, user);
|
||||
}
|
||||
|
||||
private RaceDTO findRace(String eventName, String raceName, List<EventDTO> events) {
|
||||
@@ -132,13 +134,13 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void createRaceBoardPanel(RaceDTO selectedRace, List<EventDTO> events) {
|
||||
private void createRaceBoardPanel(RaceDTO selectedRace, List<EventDTO> events, UserDTO userDTO) {
|
||||
LogoAndTitlePanel logoAndTitlePanel = new LogoAndTitlePanel(stringMessages);
|
||||
logoAndTitlePanel.addStyleName("LogoAndTitlePanel");
|
||||
RaceSelectionModel raceSelectionModel = new RaceSelectionModel();
|
||||
List<RaceIdentifier> singletonList = Collections.singletonList(selectedRace.getRaceIdentifier());
|
||||
raceSelectionModel.setSelection(singletonList);
|
||||
raceBoardPanel = new RaceBoardPanel(sailingService, raceSelectionModel, leaderboardName, leaderboardGroupName,
|
||||
raceBoardPanel = new RaceBoardPanel(sailingService, userDTO, raceSelectionModel, leaderboardName, leaderboardGroupName,
|
||||
RaceBoardEntryPoint.this, stringMessages);
|
||||
raceBoardPanel.fillEvents(events);
|
||||
|
||||
|
||||
+18
-1
@@ -38,8 +38,10 @@ import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LegTimepointDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.UserDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.components.ComponentViewer;
|
||||
import com.sap.sailing.gwt.ui.shared.panels.BreadcrumbPanel;
|
||||
import com.sap.sailing.gwt.ui.usermanagement.UserRoles;
|
||||
|
||||
/**
|
||||
* A panel showing a list of components visualizing a race from the events announced by calls to {@link #fillEvents(List)}.
|
||||
@@ -66,10 +68,12 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
private final TimePanel timePanel;
|
||||
private final Timer timer;
|
||||
private final RaceSelectionProvider raceSelectionProvider;
|
||||
private final UserDTO user;
|
||||
|
||||
public RaceBoardPanel(SailingServiceAsync sailingService, RaceSelectionProvider raceSelectionProvider, String leaderboardName,
|
||||
public RaceBoardPanel(SailingServiceAsync sailingService, UserDTO currentUser, RaceSelectionProvider raceSelectionProvider, String leaderboardName,
|
||||
String leaderboardGroupName, ErrorReporter errorReporter, final StringMessages stringMessages) {
|
||||
this.sailingService = sailingService;
|
||||
this.user = currentUser;
|
||||
this.raceSelectionProvider = raceSelectionProvider;
|
||||
raceSelectionProvider.addRaceSelectionChangeListener(this);
|
||||
racesByIdentifier = new HashMap<RaceIdentifier, RaceDTO>();
|
||||
@@ -88,6 +92,8 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
ArrayList<Pair<String, String>> breadcrumbLinksData = new ArrayList<Pair<String, String>>();
|
||||
String debugParam = Window.Location.getParameter("gwt.codesvr");
|
||||
|
||||
getUserSpecificLeaderBoardSettings(user);
|
||||
|
||||
if(leaderboardGroupName != null) {
|
||||
String link = "/gwt/Spectator.html?leaderboardGroupName=" + leaderboardGroupName;
|
||||
if(debugParam != null && !debugParam.isEmpty())
|
||||
@@ -135,6 +141,17 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
timePanel = new TimePanel(timer, stringMessages);
|
||||
}
|
||||
|
||||
private LeaderboardSettings getUserSpecificLeaderBoardSettings(UserDTO user)
|
||||
{
|
||||
LeaderboardSettings settings = null;
|
||||
if (user != null && user.roles.contains(UserRoles.moderator.name())) {
|
||||
|
||||
} else {
|
||||
// anonymous user
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
private void addComponentViewerMenuEntry(final ComponentViewer c) {
|
||||
Anchor menuEntry = new Anchor(c.getViewerName());
|
||||
menuEntry.addStyleName("raceBoardNavigation-navigationitem");
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.sap.sailing.gwt.ui.server;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
||||
import com.sap.sailing.gwt.ui.client.UserManagementService;
|
||||
import com.sap.sailing.gwt.ui.shared.UserDTO;
|
||||
import com.sap.sailing.gwt.ui.usermanagement.UserRoles;
|
||||
|
||||
/*
|
||||
* This is a extremly simple implementation of a user management service.
|
||||
*/
|
||||
public class UserManagementServiceImpl extends RemoteServiceServlet implements UserManagementService {
|
||||
private static final long serialVersionUID = -6360444730702283475L;
|
||||
// private static final Logger logger = Logger.getLogger(UserManagementServiceImpl.class.getName());
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String userRole) {
|
||||
return getThreadLocalRequest().isUserInRole(userRole);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDTO getUser() {
|
||||
HttpServletRequest threadLocalRequest = getThreadLocalRequest();
|
||||
Principal userPrincipal = threadLocalRequest.getUserPrincipal();
|
||||
List<String> roles = new ArrayList<String>();
|
||||
|
||||
if (userPrincipal != null) {
|
||||
UserDTO userDTO = new UserDTO(userPrincipal.getName());
|
||||
|
||||
for(UserRoles role: UserRoles.values()) {
|
||||
if (threadLocalRequest.isUserInRole(role.name())) {
|
||||
roles.add(role.name());
|
||||
}
|
||||
}
|
||||
userDTO.roles = roles;
|
||||
|
||||
return userDTO;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.sap.sailing.gwt.ui.shared;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
|
||||
public class UserDTO implements IsSerializable {
|
||||
public String principalName;
|
||||
|
||||
public String firstname;
|
||||
|
||||
public String lastname;
|
||||
|
||||
public List<String> roles;
|
||||
|
||||
public UserDTO(String principalName) {
|
||||
super();
|
||||
this.principalName = principalName;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.sap.sailing.gwt.ui.usermanagement;
|
||||
|
||||
public enum UserRoles {
|
||||
administrator,
|
||||
spectator,
|
||||
moderator
|
||||
}
|
||||
@@ -128,6 +128,16 @@
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.security.HashLoginService">
|
||||
<Set name="name">SailingServerRealm</Set>
|
||||
<Set name="config"><Property name="jetty.home" default="."/>/etc/realm.properties</Set>
|
||||
<Set name="refreshInterval">0</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- extra options -->
|
||||
<!-- =========================================================== -->
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
# If DIGEST Authentication is used, the password must be in a recoverable
|
||||
# format, either plain text or OBF:.
|
||||
#
|
||||
admin: OBF:1vv11uvg1y7z1x0z1wu61w8j1w971wu81x1n1y7z1uuq1vu9,user,admin
|
||||
|
||||
# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
|
||||
digest: MD5:6e120743ad67abfbc385bc2bb754e297,user
|
||||
administrator: sailing,spectator,moderator,administrator
|
||||
axel: axel,spectator,moderator,administrator
|
||||
frank: frank,spectator,moderator,administrator
|
||||
lennart: lennart,spectator,moderator,administrator
|
||||
marcus: marcus,spectator,moderator,administrator
|
||||
spectator: spectator,spectator
|
||||
moderator: moderator,moderator
|
||||
Reference in new issue
Block a user