-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic JPA modeling and basic services
- Loading branch information
1 parent
fd7f3e4
commit e05e5ff
Showing
15 changed files
with
861 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
backend/src/main/java/org/hawkular/accounts/backend/boundary/PermissionChecker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/* | ||
* Copyright 2015 Red Hat, Inc. and/or its affiliates | ||
* and other contributors as indicated by the @author tags. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.hawkular.accounts.backend.boundary; | ||
|
||
import javax.ejb.Stateless; | ||
import javax.inject.Inject; | ||
import org.hawkular.accounts.backend.entity.HawkularUser; | ||
import org.hawkular.accounts.backend.entity.Organization; | ||
import org.hawkular.accounts.backend.entity.Owner; | ||
import org.keycloak.KeycloakPrincipal; | ||
|
||
/** | ||
* | ||
* @author Juraci Paixão Kröhling <juraci at kroehling.de> | ||
*/ | ||
@Stateless | ||
public class PermissionChecker { | ||
|
||
@Inject | ||
UserService userService; | ||
|
||
/** | ||
* Determines whether the current {@link HawkularUser} has access to the resource owned by {@link Owner} | ||
* | ||
* @param currentUser the user to be checked | ||
* @param owner the owner of the resource | ||
* @return true if the user is the owner or if the user belongs to an organization that owns the resource | ||
*/ | ||
public boolean hasAccessTo(HawkularUser currentUser, Owner owner) { | ||
if (currentUser.equals(owner)) { | ||
return true; | ||
} | ||
|
||
// users don't belong to users, so, if the owner is an user and is not the current user, then it doesn't | ||
// have access | ||
if (owner instanceof HawkularUser) { | ||
return false; | ||
} | ||
|
||
return isMemberOf(currentUser, (Organization) owner); | ||
} | ||
|
||
/** | ||
* Determines whether the current {@link KeycloakPrincipal} has access to the resources owned by {@link Owner}. | ||
* | ||
* @param principal the {@link KeycloakPrincipal} representing the current user | ||
* @param owner the owner of the resource | ||
* @return true if the user is the owner or if the user belongs to an organization that owns the resource | ||
* @see PermissionChecker#hasAccessTo( | ||
* org.hawkular.accounts.backend.entity.User, org.hawkular.accounts.backend.entity.Owner) | ||
*/ | ||
public boolean hasAccessTo(KeycloakPrincipal principal, Owner owner) { | ||
// Here's a bit of explanation: judging by the name of this class, we wouldn't expect any record to be created. | ||
// But in fact, the user *already* exists, just not in our database. So, on the first call of this method for | ||
// a new user, we create it on our side, using Keycloak's ID for this user. | ||
HawkularUser user = userService.getOrCreateById(principal.getName()); | ||
return hasAccessTo(user, owner); | ||
} | ||
|
||
/** | ||
* Recursively checks whether an user is a member or owner of an organization. Examples: | ||
* | ||
* jdoe is owner of acme -> true | ||
* jdoe is member of acme -> true | ||
* jdoe is member of emca which is member of acme -> true | ||
* emca is member of acme -> true | ||
* | ||
* @param member the member to be checked | ||
* @param organization the organization that might contain the user | ||
* @return true if the user belongs to the organization recursively | ||
*/ | ||
public boolean isMemberOf(Owner member, Organization organization) { | ||
// simplest case first: is the member a direct member of this organization? | ||
// example: jsmith is a member of acme | ||
if (organization.getMembers().contains(member)) { | ||
return true; | ||
} | ||
|
||
// if the member is the owner of the current organization (or any organization that owns the current organization) | ||
// then he's directly or indirectly owner of the current organization, therefore, he's member of it | ||
// example: jdoe is the owner of acme, acme is owner of emca, therefore, jdoe is the owner of emca | ||
if (isOwnerOf(member, organization)) { | ||
return true; | ||
} | ||
|
||
// if the "member" is part of an organization that owns the current organization, then it's a member of it | ||
// example: jsmith is part of acme, acme is owner of emca, therefore, jsmith is member of emca. | ||
Owner organizationOwner = organization.getOwner(); | ||
if (organizationOwner instanceof Organization) { | ||
if (isMemberOf(member, (Organization) organizationOwner)) { | ||
return true; | ||
} | ||
} | ||
|
||
// if the member is part of a child organization, then it's a member of this one | ||
// example: jdoe is member of emca, emca is member of acme, therefore, jdoe is member of acme | ||
for (Owner organizationMember : organization.getMembers()) { | ||
if (organizationMember instanceof Organization) { | ||
return isMemberOf(member, (Organization) organizationMember); | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* Recursively checks if the specified owner is a direct or indirect owner of the given organization. For instance, | ||
* if jdoe is the owner of acme, and acme owns emca, then jdoe owns emca indirectly. | ||
* | ||
* @param owner the {@link Owner} to check. In our example above, it would be jdoe or acme. | ||
* @param organization the {@link Organization} to verify ownership of. In our example above, it would be emca. | ||
* @return whether or not the specified owner is directly or indirectly the owner of the given organization. | ||
*/ | ||
public boolean isOwnerOf(Owner owner, Organization organization) { | ||
|
||
if (organization.getOwner().equals(owner)) { | ||
return true; | ||
} | ||
|
||
Owner organizationOwner = organization.getOwner(); | ||
if (organizationOwner instanceof Organization) { | ||
return isOwnerOf(owner, (Organization) organizationOwner); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} |
77 changes: 77 additions & 0 deletions
77
backend/src/main/java/org/hawkular/accounts/backend/boundary/UserService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Copyright 2015 Red Hat, Inc. and/or its affiliates | ||
* and other contributors as indicated by the @author tags. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.hawkular.accounts.backend.boundary; | ||
|
||
import java.util.List; | ||
import javax.ejb.Stateless; | ||
import javax.inject.Inject; | ||
import javax.persistence.EntityManager; | ||
import javax.persistence.criteria.CriteriaBuilder; | ||
import javax.persistence.criteria.CriteriaQuery; | ||
import javax.persistence.criteria.Root; | ||
import org.hawkular.accounts.backend.entity.HawkularUser; | ||
import org.hawkular.accounts.backend.entity.HawkularUser_; | ||
|
||
/** | ||
* | ||
* @author Juraci Paixão Kröhling <juraci at kroehling.de> | ||
*/ | ||
@Stateless | ||
public class UserService { | ||
|
||
@Inject | ||
EntityManager em; | ||
|
||
/** | ||
* Retrieves an {@link HawkularUser} based in its ID | ||
* @param id the user ID | ||
* @return the existing user with the given ID or null if the user is not found. | ||
*/ | ||
public HawkularUser getById(String id) { | ||
CriteriaBuilder builder = em.getCriteriaBuilder(); | ||
CriteriaQuery<HawkularUser> query = builder.createQuery(HawkularUser.class); | ||
Root<HawkularUser> root = query.from(HawkularUser.class); | ||
query.select(root); | ||
query.where(builder.equal(root.get(HawkularUser_.id), id)); | ||
|
||
List<HawkularUser> results = em.createQuery(query).getResultList(); | ||
if (results.size() == 1) { | ||
return results.get(0); | ||
} | ||
|
||
if (results.size() > 1) { | ||
throw new IllegalStateException("More than one user found for ID " + id); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* Retrieves an {@link HawkularUser} based on its ID. If no user is found, a new one is created and returned. | ||
* @param id the user ID | ||
* @return an {@link HawkularUser} instance representing the user with the given ID. It's never null. | ||
*/ | ||
public HawkularUser getOrCreateById(String id) { | ||
HawkularUser user = getById(id); | ||
if (null == user) { | ||
user = new HawkularUser(id); | ||
em.persist(user); | ||
} | ||
|
||
return user; | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
backend/src/main/java/org/hawkular/accounts/backend/control/ApplicationResources.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright 2015 Red Hat, Inc. and/or its affiliates | ||
* and other contributors as indicated by the @author tags. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.hawkular.accounts.backend.control; | ||
|
||
import javax.enterprise.context.ApplicationScoped; | ||
import javax.enterprise.inject.Produces; | ||
import javax.persistence.PersistenceContext; | ||
|
||
/** | ||
* | ||
* @author Juraci Paixão Kröhling <juraci at kroehling.de> | ||
*/ | ||
@ApplicationScoped | ||
public class ApplicationResources { | ||
@Produces | ||
@PersistenceContext | ||
private static javax.persistence.EntityManager em; | ||
|
||
} |
33 changes: 33 additions & 0 deletions
33
...nd/src/main/java/org/hawkular/accounts/backend/control/HawkularAccountsMessageLogger.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright 2015 Red Hat, Inc. and/or its affiliates | ||
* and other contributors as indicated by the @author tags. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.hawkular.accounts.backend.control; | ||
|
||
import org.jboss.logging.Logger; | ||
import org.jboss.logging.annotations.MessageLogger; | ||
import org.jboss.logging.annotations.ValidIdRange; | ||
|
||
/** | ||
* | ||
* @author Juraci Paixão Kröhling <juraci at kroehling.de> | ||
*/ | ||
@MessageLogger(projectCode = "HAWKACC") | ||
@ValidIdRange(min = 100000, max = 109999) | ||
public interface HawkularAccountsMessageLogger { | ||
HawkularAccountsMessageLogger LOGGER = Logger.getMessageLogger | ||
(HawkularAccountsMessageLogger.class, HawkularAccountsMessageLogger.class.getPackage().getName()); | ||
|
||
} |
Oops, something went wrong.