Merge branch 'master' of https://github.com/girirajsharma/keycloak into girirajsharma-master

Conflicts:
	connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-master.xml
	services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
This commit is contained in:
Stian Thorgersen committed 2015-05-11 13:36:30 +02:00
commit d00e0021b6
71 files changed
+3221 -430

No files matched your search

@@ -303,6 +303,18 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'RealmEventsCtrl'
})
.when('/realms/:realm/admin-events', {
templateUrl : resourceUrl + '/partials/realm-events-admin.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
}
},
controller : 'RealmAdminEventsCtrl'
})
.when('/realms/:realm/events-settings', {
templateUrl : resourceUrl + '/partials/realm-events-config.html',
resolve : {
@@ -1180,7 +1180,7 @@ module.controller('RealmSMTPSettingsCtrl', function($scope, Current, Realm, real
}
});
module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmEventsConfig, RealmEvents, realm, serverInfo, $location, Notifications, TimeUnit, Dialog) {
module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmEventsConfig, RealmEvents, RealmAdminEvents, realm, serverInfo, $location, Notifications, TimeUnit, Dialog) {
$scope.realm = realm;
$scope.eventsConfig = eventsConfig;
@@ -1198,7 +1198,13 @@ module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmE
$scope.eventSelectOptions = {
'multiple': true,
'simple_tags': true,
'tags': serverInfo.eventTypes
'tags': serverInfo.enums['eventType']
};
$scope.adminEnabledEventOperationsOptions = {
'multiple': true,
'simple_tags': true,
'tags': serverInfo.enums['operationType']
};
var oldCopy = angular.copy($scope.eventsConfig);
@@ -1238,6 +1244,14 @@ module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmE
});
});
};
$scope.clearAdminEvents = function() {
Dialog.confirmDelete($scope.realm.realm, 'admin-events', function() {
RealmAdminEvents.remove({ id : $scope.realm.realm }, function() {
Notifications.success("The admin events has been cleared.");
});
});
};
});
module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm, serverInfo) {
@@ -1247,7 +1261,7 @@ module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm, server
$scope.eventSelectOptions = {
'multiple': true,
'simple_tags': true,
'tags': serverInfo.eventTypes
'tags': serverInfo.enums['eventType']
};
$scope.query = {
@@ -1308,6 +1322,106 @@ module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm, server
$scope.update();
});
module.controller('RealmAdminEventsCtrl', function($scope, RealmAdminEvents, realm, serverInfo, $modal, $filter) {
$scope.realm = realm;
$scope.page = 0;
$scope.query = {
id : realm.realm,
max : 5,
first : 0
}
$scope.query.authRealm = 'master';
$scope.adminEnabledEventOperationsOptions = {
'multiple': true,
'simple_tags': true,
'tags': serverInfo.enums['operationType']
};
$scope.update = function() {
$scope.query.first = 0;
for (var i in $scope.query) {
if ($scope.query[i] === '') {
delete $scope.query[i];
}
}
$scope.events = RealmAdminEvents.query($scope.query);
}
$scope.reset = function() {
$scope.query.first = 0;
$scope.query.max = 5;
$scope.query.operationTypes = '';
$scope.query.resourcePath = '';
$scope.query.authRealm = 'master';
$scope.query.authClient = '';
$scope.query.authUser = '';
$scope.query.authIpAddress = '';
$scope.query.dateFrom = '';
$scope.query.dateTo = '';
$scope.update();
}
$scope.queryUpdate = function() {
for (var i in $scope.query) {
if ($scope.query[i] === '') {
delete $scope.query[i];
}
}
$scope.events = RealmAdminEvents.query($scope.query);
}
$scope.firstPage = function() {
$scope.query.first = 0;
$scope.queryUpdate();
}
$scope.previousPage = function() {
$scope.query.first -= parseInt($scope.query.max);
if ($scope.query.first < 0) {
$scope.query.first = 0;
}
$scope.queryUpdate();
}
$scope.nextPage = function() {
$scope.query.first += parseInt($scope.query.max);
$scope.queryUpdate();
}
$scope.update();
$scope.viewRepresentation = function(event) {
$modal.open({
templateUrl: resourceUrl + '/partials/modal/realm-events-admin-representation.html',
controller: 'RealmAdminEventsModalCtrl',
resolve: {
event: function () {
return event;
}
}
})
}
$scope.viewAuth = function(event) {
$modal.open({
templateUrl: resourceUrl + '/partials/modal/realm-events-admin-auth.html',
controller: 'RealmAdminEventsModalCtrl',
resolve: {
event: function () {
return event;
}
}
})
}
});
module.controller('RealmAdminEventsModalCtrl', function($scope, $filter, event) {
$scope.event = event;
});
module.controller('RealmBruteForceCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications, TimeUnit) {
console.log('RealmBruteForceCtrl');
@@ -180,6 +180,12 @@ module.factory('RealmEvents', function($resource) {
});
});
module.factory('RealmAdminEvents', function($resource) {
return $resource(authUrl + '/admin/realms/:id/admin-events', {
id : '@realm'
});
});
module.factory('RealmLDAPConnectionTester', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/testLDAPConnection');
});
@@ -0,0 +1,8 @@
<div style="padding: 20px 20px 0 20px">
<table class="table table-striped table-bordered">
<tr><td width="100px">Realm</td><td>{{event.authDetails.realmId}}</td></tr>
<tr><td width="100px">Client</td><td>{{event.authDetails.clientId}}</td></tr>
<tr><td width="100px">User</td><td>{{event.authDetails.userId}}</td></tr>
<tr><td width="100px">IP Address</td><td>{{event.authDetails.ipAddress}}</td></tr>
</table>
</div>
@@ -0,0 +1,3 @@
<div style="padding: 20px 20px 10px 20px">
<pre ng-bind = "{{event.representation}} | json"></pre>
</div>
@@ -0,0 +1,128 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
<h1>
<span><strong>Admin Events</strong> {{realm.realm|capitalize}}</span>
<kc-tooltip>Displays saved admin events for the realm. Events are related to admin account, for example a realm creation. To enable persisted events go to config.</kc-tooltip>
</h1>
<ul class="nav nav-tabs">
<li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">Login Events</a></li>
<li data-ng-class="(path[2] == 'admin-events') && 'active'"><a href="#/realms/{{realm.realm}}/admin-events">Admin Events</a></li>
<li data-ng-class="(path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events-settings">Config</a></li>
</ul>
<h2></h2>
<div id="content">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th class="kc-table-actions" colspan="5">
<div class="pull-right">
<select data-ng-model="query.max" data-ng-click="update()" class="btn btn-default">
<option>5</option>
<option>10</option>
<option>50</option>
<option>100</option>
</select>
<button class="btn btn-default" data-ng-click="filter = !filter">
<span class="glyphicon glyphicon-plus" data-ng-show="!filter"></span>
<span class="glyphicon glyphicon-minus" data-ng-show="filter"></span>
Filter
</button>
<button class="btn btn-default btn-primary" data-ng-click="update()">Update</button>
<button class="btn btn-default btn-primary" data-ng-click="reset()">Reset</button>
</div>
<form class="form-horizontal" data-ng-show="filter">
<div class="form-group">
<label class="col-sm-2 control-label" for="adminEnabledEventOperations">Operation Types</label>
<div class="col-sm-5">
<input ui-select2="adminEnabledEventOperationsOptions" id="adminEnabledEventOperations" ng-model="query.operationTypes" data-placeholder="Select operations..."/>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="resource">Resource Path</label>
<div class="col-sm-4">
<input class="form-control" type="text" id="resource" name="resource" data-ng-model="query.resourcePath">
</div>
<span tooltip-placement="right" tooltip="Filter by resource path. Supports wildcards '*' to match a single part of the path and '**' matches multiple parts. For example 'realms/*/clients/asbc' matches client with id asbc in any realm, while or 'realms/master/**' matches anything in the master realm." class="fa fa-info-circle"></span>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="dateFrom">Date (From)</label>
<div class="col-sm-4">
<input class="form-control" type="date" id="dateFrom" name="dateFrom" data-ng-model="query.dateFrom">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="dateTo">Date (To)</label>
<div class="col-sm-4">
<input class="form-control" type="date" id="dateTo" name="dateTo" data-ng-model="query.dateTo">
</div>
</div>
<fieldset>
<legend><span class="text">Authentication Details</span></legend>
<div class="form-group" data-ng-show="'master' === realm.realm">
<label class="col-sm-2 control-label" for="realm">Realm</label>
<div class="col-sm-4">
<input class="form-control" type="text" id="realm" name="realm" data-ng-model="query.authRealm">
</div>
<span tooltip-placement="right" tooltip="Filter by realm Id. This filter is supported only for master realm." class="fa fa-info-circle"></span>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="client">Client</label>
<div class="col-sm-4">
<input class="form-control" type="text" id="client" name="client" data-ng-model="query.authClient">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="user">User</label>
<div class="col-sm-4">
<input class="form-control" type="text" id="user" name="user" data-ng-model="query.authUser">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="ipAddress">IP Address</label>
<div class="col-sm-4">
<input class="form-control" type="text" id="ipAddress" name="ipAddress" data-ng-model="query.authIpAddress">
</div>
</div>
</fieldset>
</form>
</th>
</tr>
<tr>
<th width="100px">Time</th>
<th width="180px">Operation Type</th>
<th width="180px">Resource Path</th>
<th>Details</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="7">
<button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0"><i data-ng-class="query.first == 0 && 'text-muted'" class="fa fa-angle-double-left"></i></button>
<button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0"><i data-ng-class="query.first == 0 && 'text-muted'" class="fa fa-angle-left"></i></button>
<button data-ng-click="nextPage()" class="next" ng-disabled="events.length < query.max"><i data-ng-class="events.length < query.max && 'text-muted'" class="fa fa-angle-right"></i></button>
</td>
</tr>
</tfoot>
<tbody>
<tr data-ng-repeat="event in events">
<td>{{event.time|date:'shortDate'}}<br>{{event.time|date:'mediumTime'}}</td>
<td data-ng-class="events-error">{{event.operationType}}</td>
<td>{{event.resourcePath}}</td>
<td>
<button type="button" class="btn btn-default btn-xs" data-ng-click="viewAuth(event)">
Auth
</button>
<button type="button" class="btn btn-default btn-xs" data-ng-click="viewRepresentation(event)" data-ng-show="event.representation">
Representation
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<kc-menu></kc-menu>
@@ -2,69 +2,120 @@
<h1><strong>Events</strong> {{realm.realm|capitalize}}</span> Events</h1>
<ul class="nav nav-tabs">
<li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">View</a></li>
<li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">Login Events</a></li>
<li data-ng-class="(path[2] == 'admin-events') && 'active'"><a href="#/realms/{{realm.realm}}/admin-events">Admin Events</a></li>
<li data-ng-class="(path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events-settings">Config</a></li>
</ul>
<div id="content">
<h2><span>{{realm.realm}}</span> Events Config</h2>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageEvents">
<fieldset class="border-top">
<div class="form-group">
<label class="col-md-2 control-label" for="enabled">Save Events</label>
<div class="col-md-6">
<input ng-model="eventsConfig.eventsEnabled" name="enabled" id="enabled" onoffswitch />
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageEvents">
<fieldset class="border-top">
<div class="form-group">
<label class="col-md-2 control-label" for="eventsListeners" class="control-label">Event Listeners</label>
<div class="col-md-6">
<select ui-select2 ng-model="eventsConfig.eventsListeners" data-placeholder="Select an action..." multiple>
<option ng-repeat="listener in eventListeners" value="{{listener}}">{{listener}}</option>
</select>
</div>
<span tooltip-placement="right" tooltip="Configure what listeners receive events for the realm." class="fa fa-info-circle"></span>
</div>
<kc-tooltip>If enabled events are saved to the database which makes events available to the admin and account management consoles.</kc-tooltip>
</div>
</fieldset>
<div class="form-group" data-ng-show="eventsConfig.eventsEnabled">
<label class="col-md-2 control-label" for="enabledEventTypes" class="control-label">Saved Types</label>
<fieldset>
<legend><span class="text">Login Events Settings</span></legend>
<div class="col-md-6">
<input ui-select2="eventSelectOptions" id="enabledEventTypes" ng-model="eventsConfig.enabledEventTypes" data-placeholder="Select event types..."/>
<div class="form-group">
<label class="col-md-2 control-label" for="enabled">Save Events</label>
<div class="col-md-6">
<input ng-model="eventsConfig.eventsEnabled" name="enabled" id="enabled" onoffswitch />
</div>
<span tooltip-placement="right" tooltip="If enabled login events are saved to the database which makes events available to the admin and account management consoles." class="fa fa-info-circle"></span>
</div>
<kc-tooltip>Configure what event types are saved. By default events related to login and users modifying their accounts are persisted.</kc-tooltip>
</div>
<div class="form-group" data-ng-show="eventsConfig.eventsEnabled">
<label class="col-md-2 control-label" for="enabledEventTypes" class="control-label">Saved Types</label>
<div class="form-group" data-ng-show="access.manageEvents && eventsConfig.eventsEnabled">
<label class="col-md-2 control-label" for="password">Clear Events</label>
<div class="col-md-6">
<button class="btn btn-danger" type="submit" data-ng-click="clearEvents()" >Clear Events</button>
</div>
<kc-tooltip>Deletes all events in the database.</kc-tooltip>
</div>
<div class="form-group input-select" data-ng-show="eventsConfig.eventsEnabled">
<label class="col-md-2 control-label" for="expiration">Expiration</label>
<div class="col-md-6 form-inline">
<input class="form-control" type="number" data-ng-model="eventsConfig.eventsExpiration" id="expiration" name="expiration" min="0"/>
<select class="form-control" name="expirationUnit" data-ng-model="eventsConfig.expirationUnit" >
<option>Minutes</option>
<option>Hours</option>
<option>Days</option>
</select>
</div>
<div class="col-sm-1"></div>
<kc-tooltip>Sets the expiration for events. Expired events are periodically deleted from the database.</kc-tooltip>
</div>
<div class="col-md-6">
<input ui-select2="eventSelectOptions" id="enabledEventTypes" ng-model="eventsConfig.enabledEventTypes" data-placeholder="Select event types..."/>
</div>
<div class="form-group">
<label class="col-md-2 control-label" for="eventsListeners" class="control-label">Listeners</label>
<div class="col-md-6">
<select ui-select2 ng-model="eventsConfig.eventsListeners" data-placeholder="Select an action..." multiple>
<option ng-repeat="listener in eventListeners" value="{{listener}}">{{listener}}</option>
</select>
<span tooltip-placement="right" tooltip="Configure what event types are saved. By default events related to login and users modifying their accounts are persisted." class="fa fa-info-circle"></span>
</div>
<kc-tooltip>Configure what listeners receive events for the realm.</kc-tooltip>
</div>
</fieldset>
<div class="form-group" data-ng-show="access.manageEvents && eventsConfig.eventsEnabled">
<label class="col-md-2 control-label" for="password">Clear Events</label>
<div class="col-md-6">
<button class="btn btn-danger" type="submit" data-ng-click="clearEvents()" >Clear Events</button>
</div>
<span tooltip-placement="right" tooltip="Deletes all events in the database." class="fa fa-info-circle"></span>
</div>
<div class="form-group input-select" data-ng-show="eventsConfig.eventsEnabled">
<label class="col-md-2 control-label" for="expiration">Expiration</label>
<div class="col-md-6">
<input class="form-control" type="number" data-ng-model="eventsConfig.eventsExpiration" id="expiration" name="expiration" min="0"/>
</div>
<div class="col-md-2 select-kc">
<select name="expirationUnit" data-ng-model="eventsConfig.expirationUnit" >
<option>Minutes</option>
<option>Hours</option>
<option>Days</option>
</select>
<span tooltip-placement="right" tooltip="Sets the expiration for events. Expired events are periodically deleted from the database." class="fa fa-info-circle"></span>
</div>
</div>
</fieldset>
<div class="pull-right form-actions" data-ng-show="access.manageEvents">
<button data-kc-reset data-ng-show="changed">Clear changes</button>
<button data-kc-save data-ng-show="changed">Save</button>
</div>
</form>
<fieldset>
<legend><span class="text">Admin Events Settings</span></legend>
<div class="form-group">
<label class="col-md-2 control-label" for="adminEventsEnabled">Save Events</label>
<div class="col-md-6">
<input ng-model="eventsConfig.adminEventsEnabled" name="adminEventsEnabled" id="adminEventsEnabled" onoffswitch />
</div>
<span tooltip-placement="right" tooltip="If enabled admin events are saved to the database which makes events available to the admin console." class="fa fa-info-circle"></span>
</div>
<div class="form-group" data-ng-show="eventsConfig.adminEventsEnabled">
<label class="col-md-2 control-label" for="adminEnabledEventOperations" class="control-label">Saved Operations</label>
<div class="col-md-6">
<input ui-select2="adminEnabledEventOperationsOptions" id="adminEnabledEventOperations" ng-model="eventsConfig.adminEnabledEventOperations" data-placeholder="Select operations..."/>
</div>
<span tooltip-placement="right" tooltip="Configure what operations are saved." class="fa fa-info-circle"></span>
</div>
<div class="form-group" data-ng-show="eventsConfig.adminEventsEnabled">
<label class="col-md-2 control-label" for="adminEventsDetailsEnabled">Include Representation</label>
<div class="col-md-6">
<input ng-model="eventsConfig.adminEventsDetailsEnabled" name="adminEventsDetailsEnabled" id="adminEventsDetailsEnabled" onoffswitch />
</div>
<span tooltip-placement="right" tooltip="Include JSON representation for create and update requests." class="fa fa-info-circle"></span>
</div>
<div class="form-group" data-ng-show="access.manageEvents && eventsConfig.adminEventsEnabled">
<label class="col-md-2 control-label" for="password">Clear Admin Events</label>
<div class="col-md-6">
<button class="btn btn-danger" type="submit" data-ng-click="clearAdminEvents()" >Clear Admin Events</button>
</div>
<span tooltip-placement="right" tooltip="Deletes all admin events in the database." class="fa fa-info-circle"></span>
</div>
</fieldset>
<div class="pull-right form-actions" data-ng-show="access.manageEvents">
<button data-kc-reset data-ng-show="changed">Clear changes</button>
<button data-kc-save data-ng-show="changed">Save</button>
</div>
</form>
</div>
</div>
<kc-menu></kc-menu>
<kc-menu></kc-menu>
@@ -5,7 +5,8 @@
</h1>
<ul class="nav nav-tabs">
<li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">View</a></li>
<li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">Login Events</a></li>
<li data-ng-class="(path[2] == 'admin-events') && 'active'"><a href="#/realms/{{realm.realm}}/admin-events">Admin Events</a></li>
<li data-ng-class="(path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events-settings">Config</a></li>
</ul>
@@ -121,4 +122,4 @@
</table>
</div>
<kc-menu></kc-menu>
<kc-menu></kc-menu>