* BAEL-1973

* Modified CSS Background

* removed unnecessary comment
This commit is contained in:
Adam InTae Gerard 2018-09-04 19:39:00 -07:00 committed by KevinGilmore
parent 8b805cad04
commit a42dfbcf12
27 changed files with 496 additions and 245 deletions

View File

@ -1,2 +1,3 @@
### Relevant Articles:
- [Intro to Security and WebSockets](http://www.baeldung.com/spring-security-websockets)
- [Spring WebSockets: Specific User Chat](http://www.baeldung.com/spring-websocket-specific-user-chat)

View File

@ -11,9 +11,9 @@
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-spring-5</artifactId>
<artifactId>parent-spring-4</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-spring-5</relativePath>
<relativePath>../parent-spring-4</relativePath>
</parent>
<dependencies>
@ -177,9 +177,11 @@
<properties>
<hibernate-core.version>5.2.10.Final</hibernate-core.version>
<spring-security.version>4.2.3.RELEASE</spring-security.version>
<spring-data-jpa.version>1.11.3.RELEASE</spring-data-jpa.version>
<h2database.version>1.4.196</h2database.version>
<logback-classic.version>1.2.3</logback-classic.version>
<jackson.version>2.8.7</jackson.version>
</properties>
</project>

View File

@ -0,0 +1,8 @@
package com.baeldung.springsecuredsockets;
public class Constants {
public static final String SECURED_CHAT_HISTORY = "/secured/history";
public static final String SECURED_CHAT = "/secured/chat";
public static final String SECURED_CHAT_ROOM = "/secured/room";
public static final String SECURED_CHAT_SPECIFIC_USER = "/secured/user/queue/specific-user";
}

View File

@ -9,7 +9,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
@ -20,7 +20,7 @@ import java.sql.SQLException;
@EnableJpaRepositories
@ComponentScan("com.baeldung.springsecuredsockets")
@Import({ SecurityConfig.class, DataStoreConfig.class, SocketBrokerConfig.class, SocketSecurityConfig.class })
public class AppConfig implements WebMvcConfigurer {
public class AppConfig extends WebMvcConfigurerAdapter {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");

View File

@ -88,7 +88,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.authorizeRequests()
.antMatchers("/", "/index", "/authenticate")
.permitAll()
.antMatchers("/secured/**/**", "/secured/socket", "/secured/success")
.antMatchers("/secured/**/**", "/secured/**/**/**", "/secured/socket", "/secured/success")
.authenticated()
.anyRequest().authenticated()
.and()

View File

@ -1,27 +1,33 @@
package com.baeldung.springsecuredsockets.config;
import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT;
import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_HISTORY;
import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_ROOM;
import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_SPECIFIC_USER;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
@ComponentScan("com.baeldung.springsecuredsockets.controllers")
public class SocketBrokerConfig implements WebSocketMessageBrokerConfigurer {
public class SocketBrokerConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/secured/history");
config.enableSimpleBroker(SECURED_CHAT_HISTORY, SECURED_CHAT_SPECIFIC_USER);
config.setApplicationDestinationPrefixes("/spring-security-mvc-socket");
config.setUserDestinationPrefix("/secured/user");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/secured/chat").withSockJS();
registry.addEndpoint(SECURED_CHAT_ROOM).withSockJS();
registry.addEndpoint(SECURED_CHAT).withSockJS();
}
}

View File

@ -15,7 +15,7 @@ public class SocketSecurityConfig extends AbstractSecurityWebSocketMessageBroker
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.simpDestMatchers("/secured/**").authenticated()
.simpDestMatchers("/secured/**", "/secured/**/**").authenticated()
.anyMessage().authenticated();
}
}

View File

@ -1,11 +1,19 @@
package com.baeldung.springsecuredsockets.controllers;
import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT;
import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_HISTORY;
import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_ROOM;
import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_SPECIFIC_USER;
import com.baeldung.springsecuredsockets.transfer.socket.Message;
import com.baeldung.springsecuredsockets.transfer.socket.OutputMessage;
import java.security.Principal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
@ -19,10 +27,19 @@ public class SocketController {
private SimpMessagingTemplate simpMessagingTemplate;
private static final Logger log = LoggerFactory.getLogger(SocketController.class);
@MessageMapping("/secured/chat")
@SendTo("/secured/history")
public OutputMessage send(Message msg) throws Exception {
@MessageMapping(SECURED_CHAT)
@SendTo(SECURED_CHAT_HISTORY)
public OutputMessage sendAll(Message msg) throws Exception {
OutputMessage out = new OutputMessage(msg.getFrom(), msg.getText(), new SimpleDateFormat("HH:mm").format(new Date()));
return out;
}
/**
* Example of sending message to specific user using 'convertAndSendToUser()' and '/queue'
*/
@MessageMapping(SECURED_CHAT_ROOM)
public void sendSpecific(@Payload Message msg, Principal user, @Header("simpSessionId") String sessionId) throws Exception {
OutputMessage out = new OutputMessage(msg.getFrom(), msg.getText(), new SimpleDateFormat("HH:mm").format(new Date()));
simpMessagingTemplate.convertAndSendToUser(msg.getTo(), SECURED_CHAT_SPECIFIC_USER, out);
}
}

View File

@ -3,6 +3,7 @@ package com.baeldung.springsecuredsockets.transfer.socket;
public class Message {
private String from;
private String to;
private String text;
public String getFrom() {
@ -11,6 +12,13 @@ public class Message {
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getText() {
return text;
}

View File

@ -4,15 +4,20 @@
<!DOCTYPE html>
<html>
<head>
<title>Spring Secured Sockets</title>
<link href="<c:url value="/resources/styles/style.css"/>" rel="stylesheet">
<script src="<c:url value="/resources/vendor/jquery/jquery.min.js" />"></script>
</head>
<body>
<h1>ACCESS DENIED!</h1>
<br/>
<br/>
<a href="${pageContext.request.contextPath}/login">Click to login.</a>
</body>
<head>
<title>Spring Secured Sockets</title>
<link href="<c:url value="/resources/styles/app.css"/>" rel="stylesheet">
<link href="<c:url value="/resources/styles/denied.css"/>" rel="stylesheet">
<script src="<c:url value="/resources/vendor/jquery/jquery.min.js" />"></script>
</head>
<body>
<main>
<div class="wrapper">
<h1>ACCESS DENIED!</h1>
<a href="${pageContext.request.contextPath}/login">Click to login.</a>
</div>
</main>
</body>
</html>

View File

@ -4,27 +4,32 @@
<!DOCTYPE html>
<html ng-app='angularApp'>
<head>
<title>Spring Secured Sockets</title>
<link href="<c:url value="/resources/styles/style.css"/>" rel="stylesheet">
<script src="<c:url value="/resources/vendor/jquery/jquery.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular-route.min.js" />"></script>
<script src="<c:url value="/resources/scripts/app.js" />"></script>
<script src="<c:url value="/resources/scripts/services/SocketService.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/indexController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/loginController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/socketController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/successController.js" />"></script>
<script src="<c:url value="/resources/scripts/routes/router.js" />"></script>
</head>
<body ng-controller="indexController">
<h1>Welcome!</h1>
<br />
<span>{{greeting}}</span>
<br />
<br />
<a href="${pageContext.request.contextPath}/login">Click to login.</a>
</body>
<head>
<title>Spring Secured Sockets</title>
<link href="<c:url value="/resources/styles/app.css"/>" rel="stylesheet">
<link href="<c:url value="/resources/styles/index.css"/>" rel="stylesheet">
<script src="<c:url value="/resources/vendor/jquery/jquery.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular-route.min.js" />"></script>
<script src="<c:url value="/resources/scripts/app.js" />"></script>
<script src="<c:url value="/resources/scripts/services/SocketService.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/indexController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/socketController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/successController.js" />"></script>
<script src="<c:url value="/resources/scripts/routes/router.js" />"></script>
</head>
<body ng-controller="indexController">
<main>
<div class="wrapper">
<h1>Welcome!</h1>
<span>{{greeting}}</span>
<a href="${pageContext.request.contextPath}/login">Click to login.</a>
</div>
</main>
</body>
</html>

View File

@ -4,42 +4,50 @@
<!DOCTYPE html>
<html ng-app='angularApp'>
<head>
<title>Spring Secured Sockets</title>
<link href="<c:url value="/resources/styles/style.css"/>" rel="stylesheet">
<script src="<c:url value="/resources/vendor/jquery/jquery.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular-route.min.js" />"></script>
<script src="<c:url value="/resources/scripts/app.js" />"></script>
<script src="<c:url value="/resources/scripts/services/SocketService.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/indexController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/loginController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/socketController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/successController.js" />"></script>
<script src="<c:url value="/resources/scripts/routes/router.js" />"></script>
</head>
<body ng-controller="loginController">
<c:set var="context" scope="session" value="${pageContext.request.contextPath}"/>
<!-- Must match the endpoint specified in security config -->
<h1>JSP Login Form</h1><br/>
<form name='f' action="authenticate" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td><input name="submit" type="submit" value="submit"/></td>
</tr>
</table>
</form>
<head>
<title>Spring Secured Sockets</title>
<link href="<c:url value="/resources/styles/app.css"/>" rel="stylesheet">
<link href="<c:url value="/resources/styles/login.css"/>" rel="stylesheet">
<script src="<c:url value="/resources/vendor/jquery/jquery.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular-route.min.js" />"></script>
<script src="<c:url value="/resources/scripts/app.js" />"></script>
<script src="<c:url value="/resources/scripts/services/SocketService.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/indexController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/socketController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/successController.js" />"></script>
<script src="<c:url value="/resources/scripts/routes/router.js" />"></script>
</head>
<body>
<c:set var="context" scope="session" value="${pageContext.request.contextPath}"/>
<main>
<div class="wrapper">
<!-- Must match the endpoint specified in security config -->
<h1>JSP Login Form</h1>
<form name='f' action="authenticate" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type="text" name="username" placeholder="k everyperson"/></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" placeholder="1234abcd"/></td>
</tr>
<tr>
<td><input name="submit" type="submit" value="submit"/></td>
</tr>
</table>
</form>
</div>
</main>
<!-- CSRF Token -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</body>
<!-- CSRF Token -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</body>
</html>

View File

@ -4,48 +4,56 @@
<!DOCTYPE html>
<html ng-app='angularApp'>
<head>
<title>Spring Secured Sockets</title>
<link href="<c:url value="/resources/styles/style.css"/>" rel="stylesheet">
<script src="<c:url value="/resources/vendor/sockjs/sockjs.min.js" />"></script>
<script src="<c:url value="/resources/vendor/stomp/stomp.min.js" />"></script>
<script src="<c:url value="/resources/vendor/jquery/jquery.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular-route.min.js" />"></script>
<script src="<c:url value="/resources/scripts/app.js" />"></script>
<script src="<c:url value="/resources/scripts/services/SocketService.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/indexController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/loginController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/socketController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/successController.js" />"></script>
<script src="<c:url value="/resources/scripts/routes/router.js" />"></script>
</head>
<body ng-controller="socketController">
<h1>Socket Chat</h1>
<c:set var = "context" scope = "session" value = "${pageContext.request.contextPath}"/>
<div>
<div>
<input type="text" id="from" placeholder="Choose a nickname"/>
</div>
<br/>
<div>
<button id="connect" ng-click="connect('${context}');">Connect</button>
<button id="subscribe" ng-click="subscribe();">Subscribe</button>
<button id="disconnect" disabled="disabled" ng-click="disconnect();">Disconnect</button>
</div>
<br/>
<div id="conversationDiv">
<input type="text" id="text" placeholder="Write a message..."/>
<button id="sendMessage" ng-click="sendMessage('${context}');">Send</button>
<p id="response"></p>
</div>
</div>
<head>
<title>Spring Secured Sockets</title>
<link href="<c:url value="/resources/styles/app.css"/>" rel="stylesheet">
<link href="<c:url value="/resources/styles/socket.css"/>" rel="stylesheet">
<a href="${context}/secured/success">Click to go back!</a>
<a href="${context}/">Click to start over (you will still be authenticated)!</a>
<script src="<c:url value="/resources/vendor/sockjs/sockjs.min.js" />"></script>
<script src="<c:url value="/resources/vendor/stomp/stomp.min.js" />"></script>
<script src="<c:url value="/resources/vendor/jquery/jquery.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular-route.min.js" />"></script>
<script src="<c:url value="/resources/scripts/app.js" />"></script>
<script src="<c:url value="/resources/scripts/services/SocketService.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/indexController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/socketController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/successController.js" />"></script>
<script src="<c:url value="/resources/scripts/routes/router.js" />"></script>
</head>
<body ng-controller="socketController">
<c:set var="context" scope="session" value="${pageContext.request.contextPath}"/>
<main>
<div class="wrapper">
<h1>Socket Chat</h1>
<div id="all">
<h3>(Chat With Everyone)</h3>
<input type="text" id="from" placeholder="Choose Your Username"/>
<button id="connectAll" ng-click="connectAll('${context}');">Connect All</button>
<button id="subscribeAll" ng-click="subscribeAll();">Subscribe All</button>
</div>
<div id="specific">
<h3>(Chat With A Specific User)</h3>
<input type="text" id="to" placeholder="Choose a Recipient"/>
<button id="connectSpecific" ng-click="connectSpecific('${context}');">Connect Specific</button>
<button id="subscribeSpecific" ng-click="subscribeSpecific();">Subscribe Specific</button>
</div>
<div id="conversationDiv">
<h3>(Send and See Messages)</h3>
<input type="text" id="text" placeholder="Write a message..."/>
<button id="sendMessage" ng-click="sendMessage('${context}');">Send</button>
<div id="response"></div>
<button id="disconnect" disabled="disabled" ng-click="disconnect();">Disconnect</button>
</div>
<a href="${context}/secured/success">Click to go back!</a>
<a href="${context}/">Click to start over (you will still be authenticated)!</a>
</div>
</main>
<!-- CSRF Token -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</body>
<!-- CSRF Token -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</body>
</html>

View File

@ -4,28 +4,33 @@
<!DOCTYPE html>
<html ng-app='angularApp'>
<head>
<title>Spring Secured Sockets</title>
<link href="<c:url value="/resources/styles/style.css"/>" rel="stylesheet">
<script src="<c:url value="/resources/vendor/jquery/jquery.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular-route.min.js" />"></script>
<script src="<c:url value="/resources/scripts/app.js" />"></script>
<script src="<c:url value="/resources/scripts/services/SocketService.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/indexController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/loginController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/socketController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/successController.js" />"></script>
<script src="<c:url value="/resources/scripts/routes/router.js" />"></script>
</head>
<body ng-controller="successController">
<h1>Congrats! You've logged in.</h1>
<head>
<title>Spring Secured Sockets</title>
<link href="<c:url value="/resources/styles/app.css"/>" rel="stylesheet">
<link href="<c:url value="/resources/styles/success.css"/>" rel="stylesheet">
<a href="${pageContext.request.contextPath}/secured/socket">Click to chat!</a>
<a href="${pageContext.request.contextPath}/">Click to start over (you will still be authenticated)!</a>
<script src="<c:url value="/resources/vendor/jquery/jquery.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular.min.js" />"></script>
<script src="<c:url value="/resources/vendor/angular/angular-route.min.js" />"></script>
<!-- CSRF Token -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</body>
<script src="<c:url value="/resources/scripts/app.js" />"></script>
<script src="<c:url value="/resources/scripts/services/SocketService.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/indexController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/socketController.js" />"></script>
<script src="<c:url value="/resources/scripts/controllers/successController.js" />"></script>
<script src="<c:url value="/resources/scripts/routes/router.js" />"></script>
</head>
<body ng-controller="successController">
<main>
<div class="wrapper">
<h1>Congrats! You've logged in.</h1>
<a href="${pageContext.request.contextPath}/secured/socket">Click to chat!</a>
<a href="${pageContext.request.contextPath}/">Click to start over (you will still be authenticated)!</a>
</div>
</main>
<!-- CSRF Token -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</body>
</html>

View File

@ -1,12 +1,13 @@
'use strict';
angularApp
.controller('indexController', function ($scope) {
$scope.greeting = '';
.controller('indexController', function ($scope) {
$scope.initialize = function () {
$scope.greeting = "Howdy!"
};
$scope.greeting = '';
$scope.initialize();
});
$scope.initialize = function () {
$scope.greeting = "Howdy!"
};
$scope.initialize();
});

View File

@ -1,6 +0,0 @@
'use strict';
angularApp
.controller('loginController', function ($scope) {
});

View File

@ -1,37 +1,52 @@
'use strict';
angularApp
.controller('socketController', function ($scope, SocketService) {
.controller('socketController', function ($scope, SocketService) {
$scope.stompClient = null;
$scope.sendEndpoint = '/secured/chat';
$scope.subscribeEndpoint = '/secured/history';
$scope.elems = {
connect: 'connect',
from: 'from',
text: 'text',
disconnect: 'disconnect',
conversationDiv: 'conversationDiv',
response: 'response'
};
/**
* URL mapping endpoints.
*/
$scope.connect = function (context) {
$scope.sendEndpoint = '/secured/chat';
$scope.sendEndpoint = context + $scope.sendEndpoint ;
$scope.stompClient = SocketService.connect($scope.sendEndpoint, $scope.elems);
};
var SECURED_CHAT = '/secured/chat';
var SECURED_CHAT_HISTORY = '/secured/history';
var SECURED_CHAT_ROOM = '/secured/room';
var SECURED_CHAT_SPECIFIC_USER = '/secured/user/queue/specific-user';
$scope.subscribe = function () {
$scope.stompClient.subscribe($scope.subscribeEndpoint, function (msgOut) {
SocketService.messageOut(JSON.parse(msgOut.body), $scope.elems);
});
};
var opts = {
from: 'from',
to: 'to',
text: 'text',
disconnect: 'disconnect',
conversationDiv: 'conversationDiv',
response: 'response'
};
$scope.disconnect = function () {
SocketService.disconnect($scope.elems, $scope.stompClient);
};
$scope.sendEndpoint = '';
$scope.stompClient = null;
$scope.sendMessage = function () {
SocketService.sendMessage( $scope.elems, $scope.stompClient, $scope.sendEndpoint);
};
});
/**
* Broadcast to All Users.
*/
$scope.connectAll = function (context) {
$scope.sendEndpoint = context + SECURED_CHAT;
$scope.stompClient = SocketService.connect($scope.sendEndpoint , opts, true);
};
$scope.subscribeAll = function () { SocketService.subscribeToAll($scope.stompClient, SECURED_CHAT_HISTORY, opts); };
/**
* Broadcast to Specific User.
*/
$scope.connectSpecific = function (context) {
$scope.sendEndpoint = context + SECURED_CHAT_ROOM;
$scope.stompClient = SocketService.connect(context + SECURED_CHAT_ROOM, opts, false);
};
$scope.subscribeSpecific = function () { SocketService.subscribeToSpecific($scope.stompClient, SECURED_CHAT_SPECIFIC_USER, opts); };
$scope.disconnect = function () { SocketService.disconnect(opts, $scope.stompClient); };
$scope.sendMessage = function () { SocketService.sendMessage(opts, $scope.stompClient, $scope.sendEndpoint); };
});

View File

@ -1,13 +1,12 @@
'use strict';
angularApp
.controller('successController', function ($scope) {
.controller('successController', function ($scope) {
$scope.successMsg = '';
$scope.successMsg = '';
$scope.initialize = function () {
$scope.successMsg = "You've logged in!";
};
$scope.initialize = function () {
$scope.successMsg = "You've logged in!";
};
$scope.initialize();
});
$scope.initialize();
});

View File

@ -1,19 +1,16 @@
'use strict';
angularApp
.config(function ($routeProvider) {
$routeProvider
.when('/index', {
controller: 'indexController'
})
.when('/login', {
controller: 'loginController'
})
.when('/sockets', {
controller: 'socketController'
})
.when('/success', {
controller: 'successController'
})
.otherwise('/index');
});
.config(function ($routeProvider) {
$routeProvider
.when('/index', {
controller: 'indexController'
})
.when('/sockets', {
controller: 'socketController'
})
.when('/success', {
controller: 'successController'
})
.otherwise('/index');
});

View File

@ -1,46 +1,99 @@
'use strict';
var idHelper = function (context) {
return document.getElementById(context);
};
function SocketService() {
var that = this,
idHelper = function(context) {
return document.getElementById(context);
};
that.setConnected = function (elems, connected) {
idHelper(elems.connect).disabled = connected;
idHelper(elems.disconnect).disabled = !connected;
idHelper(elems.conversationDiv).style.visibility = connected ? 'visible' : 'hidden';
idHelper(elems.response).innerHTML = '';
var that = this;
that.sessionId = '';
/**
* Generic methods.
*/
that.setConnected = function (opts, connected) {
idHelper('connectAll').disabled = connected;
idHelper('connectSpecific').disabled = connected;
idHelper(opts.disconnect).disabled = !connected;
idHelper(opts.response).innerHTML = '';
idHelper('subscribeAll').disabled = !connected;
idHelper('subscribeSpecific').disabled = !connected;
};
that.connect = function (endpoint, opts, isBroadcastAll) {
var socket = new SockJS(endpoint), stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
that.setConnected(opts, true);
if (!isBroadcastAll) {
var url = stompClient.ws._transport.url;
console.log(stompClient.ws._transport.url);
url = url.replace("ws://localhost:8080/spring-security-mvc-socket/secured/room/", "");
url = url.replace("/websocket", "");
url = url.replace(/^[0-9]+\//, "");
console.log("Your current session is: " + url);
that.sessionId = url;
}
});
return stompClient;
};
that.disconnect = function (opts, stompClient) {
if (stompClient !== null && stompClient !== undefined) { stompClient.disconnect(); }
that.setConnected(opts, false);
};
that.sendMessage = function (opts, stompClient, endpoint) {
var to = idHelper(opts.to).value;
var from = idHelper(opts.from).value;
var msg = {
'from': (from === undefined || from === null ) ? to : from,
'to': (to === undefined || to === null ) ? "ALL" : to,
'text': idHelper(opts.text).value
};
that.connect = function (endpoint, elems) {
var socket = new SockJS(endpoint), stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
that.setConnected(elems, true);
});
return stompClient;
};
console.log(JSON.stringify(msg));
stompClient.send(endpoint, {}, JSON.stringify(msg));
};
that.disconnect = function (elems, stompClient) {
if (stompClient !== null && stompClient !== undefined) stompClient.disconnect();
that.setConnected(elems, false);
};
that.messageOut = function (msg, opts) {
var r = idHelper(opts.response), p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(msg.from + ': ' + msg.text + ' (' + msg.time + ')'));
r.appendChild(p);
};
/**
* Broadcast to All Users.
*/
that.subscribeToAll = function(client, url, opts) {
idHelper('subscribeAll').disabled = true;
idHelper('subscribeSpecific').disabled = true;
client.subscribe(url, function (msgOut) {
that.messageOut(JSON.parse(msgOut.body), opts);
});
};
/**
* Broadcast to Specific User.
*/
that.subscribeToSpecific = function(client, url, opts) {
idHelper('subscribeAll').disabled = true;
idHelper('subscribeSpecific').disabled = true;
client.subscribe(url + "-user" + that.sessionId, function (msgOut) {
that.messageOut(JSON.parse(msgOut.body), opts);
});
};
that.sendMessage = function (elems, stompClient, endpoint) {
stompClient.send(endpoint, {},
JSON.stringify({
'from': idHelper(elems.from).value,
'text': idHelper(elems.text).value
}));
};
that.messageOut = function (msg, elems) {
var r = idHelper(elems.response), p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(msg.from + ': ' + msg.text + ' (' + msg.time + ')'));
r.appendChild(p);
};
}
angularApp
.service('SocketService', SocketService);
.service('SocketService', SocketService);

View File

@ -0,0 +1,70 @@
@import url('https://fonts.googleapis.com/css?family=Poiret+One');
html, body, main {
padding: 0;
margin: 0;
position: absolute;
height: 100%;
width: 100%;
color: white;
font-family: 'Poiret One', sans-serif;
opacity:.95;
}
main {
background-size: cover;
}
main > div.wrapper {
position: relative;
left: 15%;
top: 15%;
width: 40%;
}
h1 {
text-transform: uppercase;
font-size: 48px;
letter-spacing: 2px;
}
span, a {
font-size: 24px;
letter-spacing: 1px;
}
a {
text-decoration: none;
color: white;
}
a:hover {
color: lightgray;
}
input {
width: 225px;
background: none !important;
border-radius: 25px;
background-color: #fff;
color: white;
outline: none;
margin-left: 2px;
padding-left: 25px;
padding-bottom: 9px;
padding-top: 9px;
}
button {
width: 100px;
align-content: center;
text-align: center;
background: transparent;
border-radius: 25px;
padding: 6px;
color: white;
}
button:hover {
opacity: .6;
}

View File

@ -0,0 +1,3 @@
main {
background-color: black;
}

View File

@ -0,0 +1,7 @@
main {
background-color: black;
}
span, a {
top: 175px;
}

View File

@ -0,0 +1,17 @@
main {
background-color: black;
}
input[type="submit"] {
width: 100px;
align-content: center;
text-align: center;
background: transparent;
border-radius: 25px;
padding: 6px;
color: white;
}
input[type="submit"]:hover {
opacity:.6;
}

View File

@ -0,0 +1,19 @@
main {
background-color: black;
}
div#all, div#specific, div#conversationDiv {
border: 1px solid white;
border-radius: 25px;
padding: 15px;
margin: 15px
}
button[disabled=true] {
color: lightgray;
border: 1px solid lightgray;
}
button[disabled=true]:hover {
opacity: 1;
}

View File

@ -0,0 +1,3 @@
main {
background-color: black;
}