mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-18 16:17:30 +00:00
First round of testing for Security complete, now alpha
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -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>
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div ng-view>
|
<div ng-view prerender-action="authorized()">
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user