KEYCLOAK-1866

Allow changing name and view details of imported realm
This commit is contained in:
Stian Thorgersen 2015-09-22 13:19:06 +02:00
parent d08fca4e0a
commit 7ac1d1f14c
6 changed files with 70 additions and 116 deletions

View file

@ -2036,3 +2036,26 @@ module.directive( 'kcOpen', function ( $location ) {
});
};
});
module.directive('kcOnReadFile', function ($parse) {
console.debug('kcOnReadFile');
return {
restrict: 'A',
scope: false,
link: function(scope, element, attrs) {
var fn = $parse(attrs.kcOnReadFile);
element.on('change', function(onChangeEvent) {
var reader = new FileReader();
reader.onload = function(onLoadEvent) {
scope.$apply(function() {
fn(scope, {$fileContent:onLoadEvent.target.result});
});
};
reader.readAsText((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
});
}
};
});

View file

@ -155,7 +155,7 @@ module.controller('RealmDropdownCtrl', function($scope, Realm, Current, Auth, $l
}
});
module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $http, WhoAmI, $location, Dialog, Notifications, Auth) {
module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $http, WhoAmI, $location, $route, Dialog, Notifications, Auth, $modal) {
console.log('RealmCreateCtrl');
Current.realm = null;
@ -169,55 +169,21 @@ module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $
var oldCopy = angular.copy($scope.realm);
$scope.onFileSelect = function($files) {
$scope.files = $files;
$scope.importFile = function($fileContent){
$scope.realm = angular.copy(JSON.parse($fileContent));
$scope.importing = true;
};
$scope.clearFileSelect = function() {
$scope.files = null;
}
$scope.uploadFile = function() {
//$files: an array of files selected, each file has name, size, and type.
for (var i = 0; i < $scope.files.length; i++) {
var $file = $scope.files[i];
$scope.upload = $upload.upload({
url: authUrl + '/admin/realms', //upload.php script, node.js route, or servlet url
// method: POST or PUT,
// headers: {'headerKey': 'headerValue'}, withCredential: true,
data: {myObj: ""},
file: $file
/* set file formData name for 'Content-Desposition' header. Default: 'file' */
//fileFormDataName: myFile,
/* customize how data is added to formData. See #40#issuecomment-28612000 for example */
//formDataAppender: function(formData, key, val){}
}).progress(function(evt) {
console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
}).success(function(data, status, headers) {
Realm.query(function(data) {
Current.realms = data;
WhoAmI.get(function(user) {
Auth.user = user;
Notifications.success("The realm has been uploaded.");
var location = headers('Location');
if (location) {
$location.url("/realms/" + location.substring(location.lastIndexOf('/') + 1));
} else {
$location.url("/realms");
}
});
});
})
.error(function() {
Notifications.error("The realm can not be uploaded. Please verify the file.");
});
//.then(success, error, progress);
}
$scope.viewImportDetails = function() {
$modal.open({
templateUrl: resourceUrl + '/partials/modal/view-object.html',
controller: 'ObjectModalCtrl',
resolve: {
object: function () {
return $scope.realm;
}
}
})
};
$scope.$watch('realm', function() {
@ -226,6 +192,12 @@ module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $
}
}, true);
$scope.$watch('realm.realm', function() {
if (create) {
$scope.realm.id = $scope.realm.realm;
}
}, true);
$scope.save = function() {
var realmCopy = angular.copy($scope.realm);
Realm.create(realmCopy, function() {
@ -243,10 +215,17 @@ module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $
};
$scope.cancel = function() {
window.history.back();
$location.url("/");
};
$scope.reset = function() {
$route.reload();
}
});
module.controller('ObjectModalCtrl', function($scope, object) {
$scope.object = object;
});
module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $location, Dialog, Notifications, WhoAmI, Auth) {
$scope.createRealm = !realm.realm;

View file

@ -0,0 +1,3 @@
<div style="padding: 20px 20px 10px 20px">
<pre ng-bind = "{{object}} | json"></pre>
</div>

View file

@ -1,29 +1,22 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
<form class="form-horizontal" name="realmForm" novalidate>
<fieldset>
<legend><span class="text">Import Realm</span></legend>
<div class="form-group">
<label for="import-file" class="col-sm-2 control-label">Import JSON File </label>
<div class="col-md-6">
<div class="controls kc-button-input-file" data-ng-show="!files || files.length == 0">
<label for="import-file" class="btn btn-default">Select file <i class="pficon pficon-import"></i></label>
<input id="import-file" type="file" class="hidden" ng-file-select="onFileSelect($files)">
</div>
<span class="kc-uploaded-file" data-ng-show="files.length > 0">{{files[0].name}}</span>
</div>
</div>
<div class="form-group">
<div class="col-md-10 col-md-offset-2">
<button type="submit" data-ng-disabled="files.length == 0" data-ng-click="uploadFile()" class="btn btn-primary">Upload</button>
<button type="submit" data-ng-disabled="files.length == 0" data-ng-click="clearFileSelect()" class="btn btn-default">Cancel</button>
</div>
</div>
</fieldset>
</form>
<form class="form-horizontal" name="realmForm" novalidate>
<fieldset>
<legend><span class="text">Create Realm</span></legend>
<div class="form-group">
<label for="name" class="col-sm-2 control-label">Import</label>
<div class="col-md-6" data-ng-hide="importing">
<label for="import-file" class="btn btn-default">Select file <i class="pficon pficon-import"></i></label>
<input id="import-file" type="file" class="hidden" kc-on-read-file="importFile($fileContent)">
</div>
<div class="col-md-6" data-ng-show="importing">
<button class="btn btn-default" data-ng-click="viewImportDetails()">View details</button>
<button class="btn btn-default" data-ng-click="reset()">Clear import</button>
</div>
</div>
<div class="form-group">
<label for="name" class="col-sm-2 control-label">Name <span class="required">*</span></label>
@ -42,6 +35,7 @@
<div class="form-group">
<div class="col-md-10 col-md-offset-2">
<button kc-save data-ng-disabled="!changed">Create</button>
<button kc-cancel data-ng-click="cancel()">Cancel</button>
</div>
</div>
</form>

View file

@ -111,7 +111,7 @@ public class RealmAdminResource {
* @return
*/
@Path("attack-detection")
public AttackDetectionResource getClientImporter() {
public AttackDetectionResource getAttackDetection() {
AttackDetectionResource resource = new AttackDetectionResource(auth, realm, adminEvent);
ResteasyProviderFactory.getInstance().injectProperties(resource);
return resource;

View file

@ -144,51 +144,6 @@ public class RealmsAdminResource {
}
}
/**
* Import a realm from uploaded JSON file
*
* The posted represenation is expected to be a multipart/form-data encapsulation
* of a JSON file. The same format a browser would use when uploading a file.
*
* @param uriInfo
* @param input multipart/form data
* @return
* @throws IOException
*/
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadRealm(@Context final UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
RealmManager realmManager = new RealmManager(session);
realmManager.setContextPath(keycloak.getContextPath());
if (!auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
throw new ForbiddenException();
}
if (!auth.hasRealmRole(AdminRoles.CREATE_REALM)) {
throw new ForbiddenException();
}
Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
List<InputPart> inputParts = uploadForm.get("file");
RealmRepresentation rep = null;
for (InputPart inputPart : inputParts) {
// inputPart.getBody doesn't work as content-type is wrong, and inputPart.setMediaType is not supported on AS7 (RestEasy 2.3.2.Final)
rep = JsonSerialization.readValue(inputPart.getBodyAsString(), RealmRepresentation.class);
RealmModel realm = realmManager.importRealm(rep);
grantPermissionsToRealmCreator(realm);
URI location = null;
if (inputParts.size() == 1) {
location = AdminRoot.realmsUrl(uriInfo).path(realm.getName()).build();
return Response.created(location).build();
}
}
return Response.noContent().build();
}
private void grantPermissionsToRealmCreator(RealmModel realm) {
if (auth.hasRealmRole(AdminRoles.ADMIN)) {
return;