expand required credentials

This commit is contained in:
Bill Burke 2013-08-04 11:48:09 -04:00
parent 9ff4ef4d64
commit 4e61981b69
20 changed files with 322 additions and 373 deletions

View file

@ -21,6 +21,8 @@ public class RealmRepresentation {
protected String publicKey; protected String publicKey;
protected List<RoleRepresentation> roles; protected List<RoleRepresentation> roles;
protected List<RequiredCredentialRepresentation> requiredCredentials; protected List<RequiredCredentialRepresentation> requiredCredentials;
protected List<RequiredCredentialRepresentation> requiredResourceCredentials;
protected List<RequiredCredentialRepresentation> requiredOAuthClientCredentials;
protected List<UserRepresentation> users; protected List<UserRepresentation> users;
protected List<RoleMappingRepresentation> roleMappings; protected List<RoleMappingRepresentation> roleMappings;
protected List<ScopeMappingRepresentation> scopeMappings; protected List<ScopeMappingRepresentation> scopeMappings;
@ -147,6 +149,22 @@ public class RealmRepresentation {
this.requiredCredentials = requiredCredentials; this.requiredCredentials = requiredCredentials;
} }
public List<RequiredCredentialRepresentation> getRequiredResourceCredentials() {
return requiredResourceCredentials;
}
public void setRequiredResourceCredentials(List<RequiredCredentialRepresentation> requiredResourceCredentials) {
this.requiredResourceCredentials = requiredResourceCredentials;
}
public List<RequiredCredentialRepresentation> getRequiredOAuthClientCredentials() {
return requiredOAuthClientCredentials;
}
public void setRequiredOAuthClientCredentials(List<RequiredCredentialRepresentation> requiredOAuthClientCredentials) {
this.requiredOAuthClientCredentials = requiredOAuthClientCredentials;
}
public int getAccessCodeLifespan() { public int getAccessCodeLifespan() {
return accessCodeLifespan; return accessCodeLifespan;
} }

View file

@ -15,6 +15,7 @@ public class ResourceRepresentation {
protected String adminUrl; protected String adminUrl;
protected boolean surrogateAuthRequired; protected boolean surrogateAuthRequired;
protected boolean useRealmMappings; protected boolean useRealmMappings;
protected boolean enabled;
protected List<CredentialRepresentation> credentials; protected List<CredentialRepresentation> credentials;
protected List<RoleRepresentation> roles; protected List<RoleRepresentation> roles;
protected List<RoleMappingRepresentation> roleMappings; protected List<RoleMappingRepresentation> roleMappings;
@ -36,6 +37,14 @@ public class ResourceRepresentation {
this.name = name; this.name = name;
} }
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isSurrogateAuthRequired() { public boolean isSurrogateAuthRequired() {
return surrogateAuthRequired; return surrogateAuthRequired;
} }
@ -52,6 +61,13 @@ public class ResourceRepresentation {
this.roles = roles; this.roles = roles;
} }
public ResourceRepresentation role(RoleRepresentation role) {
if (this.roles == null) this.roles = new ArrayList<RoleRepresentation>();
this.roles.add(role);
return this;
}
public ResourceRepresentation role(String role, String description) { public ResourceRepresentation role(String role, String description) {
if (this.roles == null) this.roles = new ArrayList<RoleRepresentation>(); if (this.roles == null) this.roles = new ArrayList<RoleRepresentation>();
this.roles.add(new RoleRepresentation(role, description)); this.roles.add(new RoleRepresentation(role, description));

View file

@ -14,6 +14,20 @@
"secret" : true "secret" : true
} }
], ],
"requiredResourceCredentials" : [
{
"type" : "Password",
"input" : true,
"secret" : true
}
],
"requiredOAuthClientCredentials" : [
{
"type" : "Password",
"input" : true,
"secret" : true
}
],
"users" : [ "users" : [
{ {
"username" : "bburke@redhat.com", "username" : "bburke@redhat.com",

View file

@ -49,7 +49,6 @@
</button> </button>
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes <button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes
</button> </button>
<a href="#/realms/{{realm.id}}/users" data-ng-hide="changed">View users &#187;</a>
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed"> <button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">
Delete Delete
</button> </button>

View file

@ -1,75 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Log in to Subway</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/base.css">
<link rel="stylesheet" type="text/css" href="css/forms.css">
<link rel="stylesheet" type="text/css" href="css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register customer">
<h1><a href="#" title="Go to the home page"><img src="img/subway-logo.png" alt="Subway logo"></a></h1>
<div class="content">
<h2>Log in to <strong>Subway</strong></h2>
<p class="powered"><a href="#">Powered by Keycloak</a></p>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form>
<div>
<label for="username">Username</label><input type="text" id="username" autofocus>
</div>
<div>
<label for="password">Password</label><input type="password" id="password">
</div>
<div>
<label for="one-time-pswd" class="two-lines">One-time-password</label><input type="password" id="one-time-pswd">
</div>
<div class="aside-btn">
<input type="checkbox" id="remember"><label for="remember">Remember Username</label>
<p>Forgot <a href="#">Username</a> or <a href="#">Password</a>?</p>
</div>
<input type="button" value="Log In">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Does not have an account? <a href="realm-register.html">Register</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -1,81 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Register with Subway</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/base.css">
<link rel="stylesheet" type="text/css" href="css/forms.css">
<link rel="stylesheet" type="text/css" href="css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register customer register">
<h1><a href="#" title="Go to the home page"><img src="img/subway-logo.png" alt="Subway logo"></a></h1>
<div class="content">
<h2>Log in to <strong>Subway</strong></h2>
<p class="powered"><a href="#">Powered by Keycloak</a></p>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form>
<p class="subtitle">All fields required</p>
<div>
<label for="name">Full name</label><input type="text" id="name" autofocus>
</div>
<div>
<label for="email">Email</label><input type="email" id="email">
</div>
<div>
<label for="username">Username</label><input type="text" id="username">
</div>
<div>
<label for="password">Password</label><input type="password" id="password" placeholder="At least 6 characters">
</div>
<div>
<label for="password-confirm" class="two-lines">Password confirmation</label><input type="password" id="password-confirm">
</div>
<div class="aside-btn">
<p>By registering you agree to the <a href="#">Terms of Service</a> and the <a href="#">Privacy Policy</a>.</p>
</div>
<input type="button" value="Register">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Already have an account? <a href="realm-login.html">Log in</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -1,77 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Log in to Keycloak</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/base.css">
<link rel="stylesheet" type="text/css" href="css/forms.css">
<link rel="stylesheet" type="text/css" href="css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register">
<h1><a href="#" title="Go to the home page"><img src="img/red-hat-logo.png" alt="Red Hat logo"></a></h1>
<div class="content">
<h2>Log in to <strong>Keycloak</strong></h2>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form action="rest/saas/login" method="POST">
<div class="feedback feedback-error">
<p><font color="red"><strong>Email is not valid</strong>. Please enter a valid email address.</font></p>
</div>
<div>
<label for="username">Username</label><input type="text" id="username" autofocus>
</div>
<div>
<label for="password">Password</label><input type="password" id="password">
</div> <!--
<div>
<label for="one-time-pswd" class="two-lines">One-time-password</label><input type="password" id="one-time-pswd">
</div> -->
<div class="aside-btn">
<input type="checkbox" id="remember"><label for="remember">Remember Username</label>
<p>Forgot <a href="#">Username</a> or <a href="#">Password</a>?</p>
</div>
<input type="button" value="Log In">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Does not have an account? <a href="saas-register.html">Register</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -67,7 +67,7 @@
</section> </section>
<section class="info-area"> <section class="info-area">
<h3>Info area</h3> <h3>Info area</h3>
<p>Does not have an account? <a href="saas-register.html">Register</a>.</p> <p>Does not have an account? <a href="<%=application.getContextPath()%>/saas/saas-register.html">Register</a>.</p>
<ul> <ul>
<li><strong>Domain:</strong> 10.0.0.1</li> <li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li> <li><strong>Zone:</strong> Live</li>

View file

@ -1,80 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Register with Keycloak</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/base.css">
<link rel="stylesheet" type="text/css" href="css/forms.css">
<link rel="stylesheet" type="text/css" href="css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register register">
<h1><a href="#" title="Go to the home page"><img src="img/red-hat-logo.png" alt="Red Hat logo"></a></h1>
<div class="content">
<h2>Register with <strong>Keycloak</strong></h2>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form>
<p class="subtitle">All fields required</p>
<div>
<label for="name">Full name</label><input type="text" id="name" autofocus>
</div>
<div>
<label for="email">Email</label><input type="email" id="email">
</div>
<div>
<label for="username">Username</label><input type="text" id="username">
</div>
<div>
<label for="password">Password</label><input type="password" id="password" placeholder="At least 6 characters">
</div>
<div>
<label for="password-confirm" class="two-lines">Password confirmation</label><input type="password" id="password-confirm">
</div>
<div class="aside-btn">
<p>By registering you agree to the <a href="#">Terms of Service</a> and the <a href="#">Privacy Policy</a>.</p>
</div>
<input type="button" value="Register">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Already have an account? <a href="saas-login.html">Log in</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -73,7 +73,7 @@
</section> </section>
<section class="info-area"> <section class="info-area">
<h3>Info area</h3> <h3>Info area</h3>
<p>Already have an account? <a href="saas-login.html">Log in</a>.</p> <p>Already have an account? <a href="<%=application.getContextPath()%>/saas/saas-login.jsp">Log in</a>.</p>
<ul> <ul>
<li><strong>Domain:</strong> 10.0.0.1</li> <li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li> <li><strong>Zone:</strong> Live</li>

View file

@ -51,7 +51,7 @@
<section class="info-area"> <section class="info-area">
<h3>Info area</h3> <h3>Info area</h3>
<p> <p>
Does not have an account? <a href="saas-register.html">Register</a>. No account? <a href="saas-register.html">Register</a>.
</p> </p>
<ul> <ul>
<li><strong>Domain:</strong> 10.0.0.1</li> <li><strong>Domain:</strong> 10.0.0.1</li>

View file

@ -23,6 +23,7 @@ import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import java.net.URI; import java.net.URI;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
@ -203,7 +204,15 @@ public class AuthenticationManager {
public boolean authenticateForm(RealmModel realm, UserModel user, MultivaluedMap<String, String> formData) { public boolean authenticateForm(RealmModel realm, UserModel user, MultivaluedMap<String, String> formData) {
Set<String> types = new HashSet<String>(); Set<String> types = new HashSet<String>();
for (RequiredCredentialModel credential : realm.getRequiredCredentials()) { List<RequiredCredentialModel> requiredCredentials = null;
if (realm.hasRole(user, RealmManager.RESOURCE_ROLE)) {
requiredCredentials = realm.getResourceRequiredCredentials();
} else if (realm.hasRole(user, RealmManager.IDENTITY_REQUESTER_ROLE)) {
requiredCredentials = realm.getOAuthClientRequiredCredentials();
} else {
requiredCredentials = realm.getRequiredCredentials();
}
for (RequiredCredentialModel credential : requiredCredentials) {
types.add(credential.getType()); types.add(credential.getType());
} }

View file

@ -110,6 +110,20 @@ public class RealmManager {
} }
} }
if (rep.getRequiredResourceCredentials() != null) {
for (RequiredCredentialRepresentation requiredCred : rep.getRequiredCredentials()) {
addResourceRequiredCredential(newRealm, requiredCred);
}
}
if (rep.getRequiredOAuthClientCredentials() != null) {
for (RequiredCredentialRepresentation requiredCred : rep.getRequiredCredentials()) {
addOAuthClientRequiredCredential(newRealm, requiredCred);
}
}
if (rep.getUsers() != null) { if (rep.getUsers() != null) {
for (UserRepresentation userRep : rep.getUsers()) { for (UserRepresentation userRep : rep.getUsers()) {
UserModel user = createUser(newRealm, userRep); UserModel user = createUser(newRealm, userRep);
@ -180,68 +194,42 @@ public class RealmManager {
} }
public void addRequiredCredential(RealmModel newRealm, RequiredCredentialRepresentation requiredCred) { public void addRequiredCredential(RealmModel newRealm, RequiredCredentialRepresentation requiredCred) {
RequiredCredentialModel credential = initializeCred(requiredCred);
newRealm.addRequiredCredential(credential);
}
public void addResourceRequiredCredential(RealmModel newRealm, RequiredCredentialRepresentation requiredCred) {
RequiredCredentialModel credential = initializeCred(requiredCred);
newRealm.addResourceRequiredCredential(credential);
}
public void addOAuthClientRequiredCredential(RealmModel newRealm, RequiredCredentialRepresentation requiredCred) {
RequiredCredentialModel credential = initializeCred(requiredCred);
newRealm.addOAuthClientRequiredCredential(credential);
}
private RequiredCredentialModel initializeCred(RequiredCredentialRepresentation requiredCred) {
RequiredCredentialModel credential = new RequiredCredentialModel(); RequiredCredentialModel credential = new RequiredCredentialModel();
credential.setType(requiredCred.getType()); credential.setType(requiredCred.getType());
credential.setInput(requiredCred.isInput()); credential.setInput(requiredCred.isInput());
credential.setSecret(requiredCred.isSecret()); credential.setSecret(requiredCred.isSecret());
newRealm.addRequiredCredential(credential); return credential;
} }
protected void createResources(RealmRepresentation rep, RealmModel realm) { protected void createResources(RealmRepresentation rep, RealmModel realm) {
RoleModel loginRole = realm.getRole(RealmManager.RESOURCE_ROLE); RoleModel loginRole = realm.getRole(RealmManager.RESOURCE_ROLE);
ResourceManager manager = new ResourceManager(this);
for (ResourceRepresentation resourceRep : rep.getResources()) { for (ResourceRepresentation resourceRep : rep.getResources()) {
createResource(realm, loginRole, resourceRep); manager.createResource(realm, loginRole, resourceRep);
} }
} }
public void createResource(RealmModel realm, RoleModel loginRole, ResourceRepresentation resourceRep) { public RoleRepresentation toRepresentation(RoleModel role) {
ResourceModel resource = realm.addResource(resourceRep.getName()); RoleRepresentation rep = new RoleRepresentation();
resource.setManagementUrl(resourceRep.getAdminUrl()); rep.setId(role.getId());
resource.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired()); rep.setName(role.getName());
resource.updateResource(); rep.setDescription(role.getDescription());
return rep;
}
UserModel resourceUser = resource.getResourceUser();
if (resourceRep.getCredentials() != null) {
for (CredentialRepresentation cred : resourceRep.getCredentials()) {
UserCredentialModel credential = new UserCredentialModel();
credential.setType(cred.getType());
credential.setValue(cred.getValue());
realm.updateCredential(resourceUser, credential);
}
}
realm.grantRole(resourceUser, loginRole);
if (resourceRep.getRoles() != null) {
for (RoleRepresentation roleRep : resourceRep.getRoles()) {
RoleModel role = resource.addRole(roleRep.getName());
if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
}
}
if (resourceRep.getRoleMappings() != null) {
for (RoleMappingRepresentation mapping : resourceRep.getRoleMappings()) {
UserModel user = realm.getUser(mapping.getUsername());
for (String roleString : mapping.getRoles()) {
RoleModel role = resource.getRole(roleString.trim());
if (role == null) {
role = resource.addRole(roleString.trim());
}
realm.grantRole(user, role);
}
}
}
if (resourceRep.getScopeMappings() != null) {
for (ScopeMappingRepresentation mapping : resourceRep.getScopeMappings()) {
UserModel user = realm.getUser(mapping.getUsername());
for (String roleString : mapping.getRoles()) {
RoleModel role = resource.getRole(roleString.trim());
if (role == null) {
role = resource.addRole(roleString.trim());
}
resource.addScope(user, role.getName());
}
}
}
if (resourceRep.isUseRealmMappings()) realm.addScope(resource.getResourceUser(), "*");
}
} }

View file

@ -0,0 +1,98 @@
package org.keycloak.services.managers;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.ResourceRepresentation;
import org.keycloak.representations.idm.RoleMappingRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.ScopeMappingRepresentation;
import org.keycloak.services.models.RealmModel;
import org.keycloak.services.models.ResourceModel;
import org.keycloak.services.models.RoleModel;
import org.keycloak.services.models.UserCredentialModel;
import org.keycloak.services.models.UserModel;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ResourceManager {
protected RealmManager realmManager;
public ResourceManager(RealmManager realmManager) {
this.realmManager = realmManager;
}
public ResourceModel createResource(RealmModel realm, RoleModel loginRole, ResourceRepresentation resourceRep) {
ResourceModel resource = realm.addResource(resourceRep.getName());
resource.setManagementUrl(resourceRep.getAdminUrl());
resource.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
resource.updateResource();
UserModel resourceUser = resource.getResourceUser();
if (resourceRep.getCredentials() != null) {
for (CredentialRepresentation cred : resourceRep.getCredentials()) {
UserCredentialModel credential = new UserCredentialModel();
credential.setType(cred.getType());
credential.setValue(cred.getValue());
realm.updateCredential(resourceUser, credential);
}
}
realm.grantRole(resourceUser, loginRole);
if (resourceRep.getRoles() != null) {
for (RoleRepresentation roleRep : resourceRep.getRoles()) {
RoleModel role = resource.addRole(roleRep.getName());
if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
}
}
if (resourceRep.getRoleMappings() != null) {
for (RoleMappingRepresentation mapping : resourceRep.getRoleMappings()) {
UserModel user = realm.getUser(mapping.getUsername());
for (String roleString : mapping.getRoles()) {
RoleModel role = resource.getRole(roleString.trim());
if (role == null) {
role = resource.addRole(roleString.trim());
}
realm.grantRole(user, role);
}
}
}
if (resourceRep.getScopeMappings() != null) {
for (ScopeMappingRepresentation mapping : resourceRep.getScopeMappings()) {
UserModel user = realm.getUser(mapping.getUsername());
for (String roleString : mapping.getRoles()) {
RoleModel role = resource.getRole(roleString.trim());
if (role == null) {
role = resource.addRole(roleString.trim());
}
resource.addScope(user, role.getName());
}
}
}
if (resourceRep.isUseRealmMappings()) realm.addScope(resource.getResourceUser(), "*");
return resource;
}
public ResourceModel createResource(RealmModel realm, ResourceRepresentation resourceRep) {
RoleModel loginRole = realm.getRole(RealmManager.RESOURCE_ROLE);
return createResource(realm, loginRole, resourceRep);
}
public ResourceRepresentation getResource(ResourceModel resourceModel, boolean bulk) {
ResourceRepresentation rep = new ResourceRepresentation();
rep.setName(resourceModel.getName());
rep.setEnabled(resourceModel.isEnabled());
rep.setAdminUrl(resourceModel.getManagementUrl());
rep.setSurrogateAuthRequired(resourceModel.isSurrogateAuthRequired());
List<RoleModel> roles = resourceModel.getRoles();
for (RoleModel role : roles) {
rep.role(realmManager.toRepresentation(role));
}
return rep;
}
}

View file

@ -100,4 +100,14 @@ public interface RealmModel {
void addRealmAdmin(UserModel agent); void addRealmAdmin(UserModel agent);
RoleModel getRoleById(String id); RoleModel getRoleById(String id);
void addResourceRequiredCredential(RequiredCredentialModel cred);
List<RequiredCredentialModel> getResourceRequiredCredentials();
void addOAuthClientRequiredCredential(RequiredCredentialModel cred);
List<RequiredCredentialModel> getOAuthClientRequiredCredentials();
boolean hasRole(UserModel user, String role);
} }

View file

@ -13,9 +13,11 @@ import org.keycloak.services.models.UserCredentialModel;
import org.keycloak.services.models.UserModel; import org.keycloak.services.models.UserModel;
import org.keycloak.services.models.picketlink.mappings.RealmData; import org.keycloak.services.models.picketlink.mappings.RealmData;
import org.keycloak.services.models.picketlink.mappings.ResourceData; import org.keycloak.services.models.picketlink.mappings.ResourceData;
import org.keycloak.services.models.picketlink.relationships.OAuthClientRequiredCredentialRelationship;
import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship; import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship;
import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship; import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship;
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship; import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
import org.keycloak.services.models.picketlink.relationships.ResourceRequiredCredentialRelationship;
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship; import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
import org.picketlink.idm.IdentityManager; import org.picketlink.idm.IdentityManager;
import org.picketlink.idm.PartitionManager; import org.picketlink.idm.PartitionManager;
@ -252,6 +254,48 @@ public class RealmAdapter implements RealmModel {
RelationshipQuery<RequiredCredentialRelationship> query = getRelationshipManager().createRelationshipQuery(RequiredCredentialRelationship.class); RelationshipQuery<RequiredCredentialRelationship> query = getRelationshipManager().createRelationshipQuery(RequiredCredentialRelationship.class);
query.setParameter(RequiredCredentialRelationship.REALM, realm.getName()); query.setParameter(RequiredCredentialRelationship.REALM, realm.getName());
List<RequiredCredentialRelationship> results = query.getResultList(); List<RequiredCredentialRelationship> results = query.getResultList();
return getRequiredCredentialModels(results);
}
@Override
public void addResourceRequiredCredential(RequiredCredentialModel cred) {
ResourceRequiredCredentialRelationship relationship = new ResourceRequiredCredentialRelationship();
addRequiredCredential(cred, relationship);
}
@Override
public List<RequiredCredentialModel> getResourceRequiredCredentials() {
RelationshipQuery<ResourceRequiredCredentialRelationship> query = getRelationshipManager().createRelationshipQuery(ResourceRequiredCredentialRelationship.class);
query.setParameter(ResourceRequiredCredentialRelationship.REALM, realm.getName());
List<ResourceRequiredCredentialRelationship> results = query.getResultList();
return getRequiredCredentialModels(results);
}
@Override
public void addOAuthClientRequiredCredential(RequiredCredentialModel cred) {
OAuthClientRequiredCredentialRelationship relationship = new OAuthClientRequiredCredentialRelationship();
addRequiredCredential(cred, relationship);
}
@Override
public List<RequiredCredentialModel> getOAuthClientRequiredCredentials() {
RelationshipQuery<OAuthClientRequiredCredentialRelationship> query = getRelationshipManager().createRelationshipQuery(OAuthClientRequiredCredentialRelationship.class);
query.setParameter(ResourceRequiredCredentialRelationship.REALM, realm.getName());
List<OAuthClientRequiredCredentialRelationship> results = query.getResultList();
return getRequiredCredentialModels(results);
}
@Override
public void addRequiredCredential(RequiredCredentialModel cred) {
RequiredCredentialRelationship relationship = new RequiredCredentialRelationship();
addRequiredCredential(cred, relationship);
}
protected List<RequiredCredentialModel> getRequiredCredentialModels(List<? extends RequiredCredentialRelationship> results) {
List<RequiredCredentialModel> rtn = new ArrayList<RequiredCredentialModel>(); List<RequiredCredentialModel> rtn = new ArrayList<RequiredCredentialModel>();
for (RequiredCredentialRelationship relationship : results) { for (RequiredCredentialRelationship relationship : results) {
RequiredCredentialModel model = new RequiredCredentialModel(); RequiredCredentialModel model = new RequiredCredentialModel();
@ -262,10 +306,7 @@ public class RealmAdapter implements RealmModel {
} }
return rtn; return rtn;
} }
protected void addRequiredCredential(RequiredCredentialModel cred, RequiredCredentialRelationship relationship) {
@Override
public void addRequiredCredential(RequiredCredentialModel cred) {
RequiredCredentialRelationship relationship = new RequiredCredentialRelationship();
relationship.setCredentialType(cred.getType()); relationship.setCredentialType(cred.getType());
relationship.setInput(cred.isInput()); relationship.setInput(cred.isInput());
relationship.setSecret(cred.isSecret()); relationship.setSecret(cred.isSecret());
@ -422,6 +463,13 @@ public class RealmAdapter implements RealmModel {
return SampleModel.hasRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole()); return SampleModel.hasRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
} }
@Override
public boolean hasRole(UserModel user, String role) {
RoleModel roleModel = getRole(role);
return hasRole(user, roleModel);
}
@Override @Override
public void grantRole(UserModel user, RoleModel role) { public void grantRole(UserModel user, RoleModel role) {
SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole()); SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());

View file

@ -0,0 +1,8 @@
package org.keycloak.services.models.picketlink.relationships;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class OAuthClientRequiredCredentialRelationship extends RequiredCredentialRelationship {
}

View file

@ -0,0 +1,8 @@
package org.keycloak.services.models.picketlink.relationships;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ResourceRequiredCredentialRelationship extends RequiredCredentialRelationship {
}

View file

@ -0,0 +1,32 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.representations.idm.ResourceRepresentation;
import org.keycloak.services.models.RealmModel;
import org.keycloak.services.models.UserModel;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class RealmResourcesResource {
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
protected UserModel admin;
protected RealmModel realm;
public RealmResourcesResource(UserModel admin, RealmModel realm) {
this.admin = admin;
this.realm = realm;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
List<ResourceRepresentation> getResources() {
return null;
}
}

View file

@ -10,6 +10,20 @@
"secret" : true "secret" : true
} }
], ],
"requiredResourceCredentials" : [
{
"type" : "Password",
"input" : true,
"secret" : true
}
],
"requiredOAuthClientCredentials" : [
{
"type" : "Password",
"input" : true,
"secret" : true
}
],
"users" : [ "users" : [
{ {
"username" : "wburke", "username" : "wburke",