First round of testing for Security complete, now alpha

This commit is contained in:
Admin
2017-03-31 14:57:48 -05:00
parent cd5417c2e0
commit 2f1adf9d4b
7 changed files with 71 additions and 65 deletions

View File

@@ -5,7 +5,7 @@
<groupId>com.bwssystems.HABridge</groupId> <groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId> <artifactId>ha-bridge</artifactId>
<version>4.3.1Secure-g</version> <version>4.5.0alpha</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>HA Bridge</name> <name>HA Bridge</name>

View File

@@ -273,7 +273,8 @@ public class BridgeSettings extends BackupHandler {
perms.add(PosixFilePermission.OWNER_WRITE); perms.add(PosixFilePermission.OWNER_WRITE);
try { try {
Files.setPosixFilePermissions(filePath, perms); if(System.getProperty("os.name").toLowerCase().indexOf("win") <= 0)
Files.setPosixFilePermissions(filePath, perms);
} catch(UnsupportedOperationException e) { } catch(UnsupportedOperationException e) {
log.info("Cannot set permissions for config file on this system as it is not supported. Continuing"); log.info("Cannot set permissions for config file on this system as it is not supported. Continuing");
} }

View File

@@ -58,6 +58,7 @@ public class DeviceResource {
private void setupEndpoints() { private void setupEndpoints() {
log.info("HABridge device management service started.... "); log.info("HABridge device management service started.... ");
before(API_CONTEXT + "/*", (request, response) -> { before(API_CONTEXT + "/*", (request, response) -> {
// This never gets called as the HueMulator class covers this path. This is here for backup
if(bridgeSettings.getBridgeSecurity().isSecure()) { if(bridgeSettings.getBridgeSecurity().isSecure()) {
User authUser = bridgeSettings.getBridgeSecurity().getAuthenticatedUser(request); User authUser = bridgeSettings.getBridgeSecurity().getAuthenticatedUser(request);
if(authUser == null) { if(authUser == null) {

View File

@@ -69,11 +69,19 @@ public class HueMulator {
public void setupServer() { public void setupServer() {
log.info("Hue emulator service started...."); log.info("Hue emulator service started....");
before(HUE_CONTEXT + "/*", (request, response) -> { before(HUE_CONTEXT + "/*", (request, response) -> {
if(bridgeSettingMaster.getBridgeSecurity().isSecureHueApi()) { if(bridgeSettingMaster.getBridgeSecurity().isSecure()) {
String pathInfo = request.pathInfo();
if(pathInfo != null && pathInfo.contains(HUE_CONTEXT + "/devices")) {
User authUser = bridgeSettingMaster.getBridgeSecurity().getAuthenticatedUser(request); User authUser = bridgeSettingMaster.getBridgeSecurity().getAuthenticatedUser(request);
if(authUser == null) { if(authUser == null) {
halt(401, "{\"message\":\"User not authenticated\"}"); halt(401, "{\"message\":\"User not authenticated\"}");
} }
} else if (bridgeSettingMaster.getBridgeSecurity().isSecureHueApi()) {
User authUser = bridgeSettingMaster.getBridgeSecurity().getAuthenticatedUser(request);
if(authUser == null) {
halt(401, "{\"message\":\"User not authenticated\"}");
}
}
} }
}); });
// http://ip_address:port/api/{userId}/groups returns json objects of // http://ip_address:port/api/{userId}/groups returns json objects of

View File

@@ -69,7 +69,7 @@
</div> </div>
</nav> </nav>
<div ng-view> <div ng-view prerender-action="authorized()">
</div> </div>

View File

@@ -79,23 +79,37 @@ app.config (function ($locationProvider, $routeProvider) {
app.run( async function ($rootScope, $location, Auth, bridgeService) { app.run( async function ($rootScope, $location, Auth, bridgeService) {
bridgeService.getHABridgeVersion(); bridgeService.getHABridgeVersion();
await bridgeService.sleep(4000);
Auth.init();
$rootScope.$on('$routeChangeStart', function (event, next) { $rootScope.$on('securitySetupReceived', function(event, data) {
if (!Auth.checkPermissionForView(next)){ Auth.init();
if(Auth.isLoggedIn()) {
bridgeService.loadBridgeSettings();
bridgeService.getTestUser();
bridgeService.getSecurityInfo();
bridgeService.viewMapTypes();
$location.path("/");
} else {
event.preventDefault(); event.preventDefault();
$location.path("/login"); $location.path("/login");
} }
}); });
if(Auth.isLoggedIn()) { $rootScope.$on('$routeChangeStart', function (event, next) {
bridgeService.loadBridgeSettings(); if(Auth.isLoggedIn()) {
bridgeService.getTestUser(); bridgeService.loadBridgeSettings();
bridgeService.getSecurityInfo(); bridgeService.getTestUser();
bridgeService.viewMapTypes(); bridgeService.getSecurityInfo();
await bridgeService.sleep(2000); bridgeService.viewMapTypes();
} }
if (!Auth.checkPermissionForView(next)){
event.preventDefault();
$location.path("/login");
} else {
$location.path(next.originalPath);
}
});
}); });
String.prototype.replaceAll = function (search, replace) String.prototype.replaceAll = function (search, replace)
@@ -110,17 +124,12 @@ String.prototype.replaceAll = function (search, replace)
}; };
app.service ('bridgeService', function ($http, $base64, $location, ngToast) { app.service ('bridgeService', function ($rootScope, $http, $base64, $location, ngToast) {
var self = this; var self = this;
this.state = {base: "./api/devices", bridgelocation: ".", systemsbase: "./system", huebase: "./api", configs: [], backups: [], devices: [], device: {}, this.state = {base: "./api/devices", bridgelocation: ".", systemsbase: "./system", huebase: "./api", configs: [], backups: [], devices: [], device: {},
mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false,
isInControl: false, showVera: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false, isInControl: false, showVera: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false,
showDomoticz: false, showSomfy: false, showLifx: false, habridgeversion: {}, viewDevId: "", queueDevId: "", securityInfo: {}, username: "test"}; showDomoticz: false, showSomfy: false, showLifx: false, habridgeversion: {}, viewDevId: "", queueDevId: "", securityInfo: {}};
this.sleep = function (ms) {
return new Promise(resolve => setTimeout(resolve, ms));
};
this.displayWarn = function(errorTitle, error) { this.displayWarn = function(errorTitle, error) {
var toastContent = errorTitle; var toastContent = errorTitle;
@@ -165,7 +174,9 @@ app.service ('bridgeService', function ($http, $base64, $location, ngToast) {
this.displayTimer = function (theTitle, timeMillis) { this.displayTimer = function (theTitle, timeMillis) {
ngToast.create({ ngToast.create({
className: "success", className: "success",
content: theTitle + " in " + timeMillis + " milliseconds"}); timeout: timeMillis,
dismissOnClick: false,
content: theTitle + " in " + timeMillis/1000 + " seconds"});
}; };
this.viewDevices = function () { this.viewDevices = function () {
@@ -208,6 +219,7 @@ app.service ('bridgeService', function ($http, $base64, $location, ngToast) {
version: response.data.version, version: response.data.version,
isSecure: response.data.isSecure isSecure: response.data.isSecure
}; };
$rootScope.$broadcast('securitySetupReceived', 'done');
}, },
function (error) { function (error) {
self.displayWarn("Cannot get version: ", error); self.displayWarn("Cannot get version: ", error);
@@ -241,7 +253,7 @@ app.service ('bridgeService', function ($http, $base64, $location, ngToast) {
var newSecurityInfo = {}; var newSecurityInfo = {};
newSecurityInfo = { newSecurityInfo = {
useLinkButton: useLinkButton, useLinkButton: useLinkButton,
seucreHueApi: secureHueApi, secureHueApi: secureHueApi,
execGarden: execGarden execGarden: execGarden
}; };
return $http.post(this.state.systemsbase + "/changesecurityinfo", newSecurityInfo ).then( return $http.post(this.state.systemsbase + "/changesecurityinfo", newSecurityInfo ).then(
@@ -264,21 +276,10 @@ app.service ('bridgeService', function ($http, $base64, $location, ngToast) {
return self.state.habridgeversion.isSecure; return self.state.habridgeversion.isSecure;
}; };
this.initA = async function() {
self.getHABridgeVersion();
await self.sleep(4000);
};
this.initB = async function() {
self.loadBridgeSettings();
self.getTestUser();
self.getSecurityInfo();
self.viewMapTypes();
await self.sleep(4000);
};
this.changePassword = function (aPassword, aPassword2) { this.changePassword = function (aPassword, aPassword2) {
var newUserInfo = {}; var newUserInfo = {};
newUserInfo = { newUserInfo = {
username: self.state.username, username: self.state.loggedInUser,
password: aPassword, password: aPassword,
password2: aPassword2 password2: aPassword2
}; };
@@ -305,8 +306,7 @@ app.service ('bridgeService', function ($http, $base64, $location, ngToast) {
function (response) { function (response) {
self.displaySuccess("User added") self.displaySuccess("User added")
if(!self.isSecure()) { if(!self.isSecure()) {
self.initA(); self.getHABridgeVersion();
$location.path('/login');
} }
}, },
function (error) { function (error) {
@@ -331,29 +331,10 @@ app.service ('bridgeService', function ($http, $base64, $location, ngToast) {
); );
}; };
this.validateUser = function (username, aPassword) {
var newUserInfo = {};
newUserInfo = {
username: username,
password: aPassword
};
var theEncodedPayload = $base64.encode(angular.toJson(newUserInfo));
return $http.post(this.state.systemsbase + "/login", theEncodedPayload ).then(
function (response) {
var theResult = response.data;
self.state.username = theResult.user;
self.displaySuccess("Success!")
},
function (error) {
self.displayWarn("Login Error: ", error);
}
);
};
this.pushLinkButton = function () { this.pushLinkButton = function () {
return $http.put(this.state.systemsbase + "/presslinkbutton").then( return $http.put(this.state.systemsbase + "/presslinkbutton").then(
function (response) { function (response) {
self.displayTimer("Linnk your device in ", 30000); self.displayTimer("Link your device", 30000);
}, },
function (error) { function (error) {
self.displayWarn("Cannot get security info: ", error); self.displayWarn("Cannot get security info: ", error);
@@ -1331,8 +1312,9 @@ app.directive('nuCheck', [function () {
scope.showPassword = true; scope.showPassword = true;
} }
else { else {
scope.addingUser = true; scope.addingUser = false;
scope.username = scope.loggedInUser; if(scope.loggedInUser !== undefined)
scope.username = scope.loggedInUser;
scope.showPassword = scope.isSecure; scope.showPassword = scope.isSecure;
} }
}); });
@@ -1360,8 +1342,11 @@ app.directive('pwCheck', [function () {
}]); }]);
app.controller('SecurityDialogCtrl', function ($scope, bridgeService, ngDialog) { app.controller('SecurityDialogCtrl', function ($scope, bridgeService, ngDialog) {
$scope.username = bridgeService.state.username; $scope.loggedInUser = bridgeService.state.loggedInUser;
$scope.loggedInUser = bridgeService.state.username; if(bridgeService.state.loggedInUser !== undefined)
$scope.username = bridgeService.state.loggedInUser;
else
$scope.username = ""
$scope.secureHueApi = bridgeService.state.securityInfo.secureHueApi; $scope.secureHueApi = bridgeService.state.securityInfo.secureHueApi;
$scope.useLinkButton = bridgeService.state.securityInfo.useLinkButton; $scope.useLinkButton = bridgeService.state.securityInfo.useLinkButton;
$scope.execGarden = bridgeService.state.securityInfo.execGarden; $scope.execGarden = bridgeService.state.securityInfo.execGarden;
@@ -1382,13 +1367,20 @@ app.controller('SecurityDialogCtrl', function ($scope, bridgeService, ngDialog)
$scope.addUser = function (newUser, password, password2) { $scope.addUser = function (newUser, password, password2) {
bridgeService.addUser(newUser, password, password2); bridgeService.addUser(newUser, password, password2);
$scope.addingUser = false; $scope.addingUser = false;
$scope.username = $scope.loggedInUser; if(bridgeService.staet.loggedInUser !== undefined)
$scope.username = bridgeService.state.loggedInUser;
else
$scope.username = ""
$scope.showPassword = $scope.isSecure; $scope.showPassword = $scope.isSecure;
}; };
$scope.delUser = function (newUser) { $scope.delUser = function (newUser) {
bridgeService.delUser(newUser); bridgeService.delUser(newUser);
$scope.addingUser = false; $scope.addingUser = false;
if(bridgeService.state.loggedInUser !== undefined)
$scope.username = bridgeService.state.loggedInUser;
else
$scope.username = ""
$scope.showPassword = $scope.isSecure; $scope.showPassword = $scope.isSecure;
}; };
@@ -3229,6 +3221,10 @@ app.controller('LoginController', function ($scope, $location, Auth) {
$scope.failed = true; $scope.failed = true;
}); });
}; };
$scope.logout = function() {
Auth.logout();
};
}); });
app.controller('VersionController', function ($scope, bridgeService) { app.controller('VersionController', function ($scope, bridgeService) {
@@ -3280,11 +3276,8 @@ app.factory('Auth', function($resource, $rootScope, $sessionStorage, $http, $bas
var theResult = response.data; var theResult = response.data;
$sessionStorage.user = theResult.user; $sessionStorage.user = theResult.user;
$rootScope.user = $sessionStorage.user; $rootScope.user = $sessionStorage.user;
bridgeService.loadBridgeSettings(); bridgeService.state.loggedInUser = $sessionStorage.user.username;
bridgeService.getHABridgeVersion(); bridgeService.getHABridgeVersion();
bridgeService.getTestUser();
bridgeService.getSecurityInfo();
bridgeService.viewMapTypes();
}, function(error) { }, function(error) {
bridgeService.displayWarn("Login Error: ", error); bridgeService.displayWarn("Login Error: ", error);
}); });
@@ -3294,6 +3287,8 @@ app.factory('Auth', function($resource, $rootScope, $sessionStorage, $http, $bas
auth.logout = function() { auth.logout = function() {
delete $sessionStorage.user; delete $sessionStorage.user;
delete $rootScope.user; delete $rootScope.user;
delete bridgeService.state.loggedInUser;
bridgeService.displaySuccess("User Logged Out");
}; };

View File

@@ -18,6 +18,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<button type="button" class="btn btn-success" ng-click="login(username, password)">Submit</button> <button type="button" class="btn btn-success" ng-click="login(username, password)">Submit</button>
<button type="button" class="btn btn-danger" ng-click="logout()">Logout</button>
</div> </div>
</form> </form>