package models;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.apache.commons.lang3.StringUtils;
import play.Logger;
import play.data.validation.ValidationError;
import uk.bl.Const;
import com.avaje.ebean.ExpressionList;
import com.avaje.ebean.Page;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name = "role")
public class Role extends ActModel {
/**
*
*/
private static final long serialVersionUID = 5670206529564297517L;
@ManyToMany
@JoinTable(name = "permission_role", joinColumns = { @JoinColumn(name = "role_id", referencedColumnName="id") },
inverseJoinColumns = { @JoinColumn(name = "permission_id", referencedColumnName="id") })
public List<Permission> permissions = new ArrayList<>();
@JsonIgnore
@ManyToMany
@JoinTable(name = "role_user", joinColumns = { @JoinColumn(name = "role_id", referencedColumnName="id") },
inverseJoinColumns = { @JoinColumn(name = "user_id", referencedColumnName="id") })
public List<User> users;
@Column(columnDefinition = "text")
public String name;
@JsonIgnore
@Column(columnDefinition = "text")
public String description;
@JsonIgnore
@Column(columnDefinition = "text")
public String revision;
public static final Finder<Long, Role> find = new Finder<Long, Role>(Long.class, Role.class);
public List<ValidationError> validate() {
List<ValidationError> errors = new ArrayList<>();
if (name == null || name.length() == 0) {
errors.add(new ValidationError("name", "No name was given."));
}
if (errors.size() > 0)
return errors;
return null;
}
/**
* Retrieve all roles.
*/
public static List<Role> findAll() {
return find.all();
}
public static List<Role> findNonSysAdminRoles() {
return find.where().ne("name", "sys_admin").findList();
}
/**
* Retrieve an object by Id (id).
* @param nid
* @return object
*/
public static Role findById(Long id) {
Role res = find.where().eq(Const.ID, id).findUnique();
return res;
}
public static Role findByName(String name)
{
return find.where()
.eq("name",
name)
.findUnique();
}
/**
* This method filters roles by name and returns a list of filtered Role objects.
* @param name
* @return
*/
public static List<Role> filterByName(String name) {
List<Role> res = new ArrayList<Role>();
ExpressionList<Role> ll = find.where().icontains("name", name);
res = ll.findList();
return res;
}
/**
* This method checks if this Role has a permission passed as string parameter.
* @param permissionName
* @return true if exists
*/
public boolean hasPermission(String permissionName) {
if (StringUtils.isNotEmpty(permissionName)) {
Permission permission = Permission.findByName(permissionName);
if (this.permissions.contains(permission)) {
return true;
}
}
return false;
}
/**
* This method checks whether user has a permission by its id.
* @param permissionName
* @return true if exists
*/
public boolean hasPermission(Long permissionId) {
if (permissionId != null) {
Permission permission = Permission.findById(permissionId);
if (this.permissions.contains(permission)) {
return true;
}
}
return false;
}
// public static List<Permission> getNotAssignedPermissions(List<Permission> assignedPermissions) {
// return Permission.find.where().not(Expr.in("permissions", assignedPermissions)).findList();
// }
/**
* This method returns permissions that are not assigned to this role.
* @return list of Permission objects
*/
public static List<Permission> getNotAssignedPermissions(List<Permission> assignedPermissions) {
List<Permission> allPermissionList = Permission.findAll();
// Logger.debug("Permissions count: " + allPermissionList.size());
List<Permission> res = new ArrayList<Permission>();
if (assignedPermissions != null && assignedPermissions.size() > 0) {
Iterator<Permission> itrAllPermissions = allPermissionList.iterator();
while (itrAllPermissions.hasNext()) {
Permission curPermission = itrAllPermissions.next();
// Logger.debug("curPermission: " + curPermission.name);
if (!assignedPermissions.contains(curPermission)) {
res.add(curPermission);
}
}
}
return res;
}
//
// public static List<Permission> getNotAssignedPermissions(String permissionsStr) {
// List<Permission> allPermissionList = Permission.findAll();
//// Logger.debug("Permissions count: " + allPermissionList.size());
// List<Permission> res = new ArrayList<Permission>();
// if (permissionsStr != null && permissionsStr.length() > 0) {
// List<String> assignedList = Arrays.asList(permissionsStr.split(Const.COMMA + " "));
//// Logger.debug("original permissions: " + permissionsStr);
//// Logger.debug("assignedList: " + assignedList);
// Iterator<Permission> itrAllPermissions = allPermissionList.iterator();
// while (itrAllPermissions.hasNext()) {
// Permission curPermission = itrAllPermissions.next();
//// Logger.debug("curPermission: " + curPermission.name);
// if (!assignedList.contains(curPermission.name)) {
// res.add(curPermission);
// }
// }
// }
// return res;
// }
// /**
// * This method checks if a given role is included in the list of passed user roles.
// * Simple "contains" method of string does not help for roles since part of the role name
// * like "exper_user" could be a name of the other role like "user".
// * @param roleName The given role name
// * @param roles The user roles as a string separated by comma
// * @return true if role name is included
// */
// public static boolean isIncludedByUrl(Long roleId, String url) {
// boolean res = false;
//// Logger.debug("isIncludedByUrl() roleId: " + roleId + ",url: " + url);
// try {
// if (StringUtils.isNotEmpty(url)) {
// List<Role> roles = User.findByUrl(url).roles;
//// Logger.debug("roles.size: "+ roles.size());
// res = isIncluded(roleId, roles);
// }
// } catch (Exception e) {
// Logger.debug("User is not yet stored in database.");
// }
// return res;
// }
/**
* This method evaluates index of the role in the role enumeration.
* @param roles
* @return
*/
public static int getRoleSeverity(List<Role> roles) {
int res = Const.Roles.values().length;
if (roles != null && roles.size() > 0 ) {
Iterator<Role> itr = roles.iterator();
while (itr.hasNext()) {
Role currentRole = itr.next();
int currentLevel = Const.Roles.valueOf(currentRole.name).ordinal();
if (currentLevel < res) {
res = currentLevel;
}
}
}
return res;
}
/**
* This method validates whether user is allowed to
* change given role.
* @param role
* @param user
* @return true if user is allowed
*/
public static boolean isAllowed(Role role, User user) {
boolean res = false;
if (role != null && role.name != null && role.name.length() > 0) {
try {
int roleIndex = Const.Roles.valueOf(role.name).ordinal();
int userIndex = getRoleSeverity(user.roles);
// Logger.debug("roleIndex: " + roleIndex + ", userIndex: " + userIndex);
if (roleIndex >= userIndex) {
res = true;
}
} catch (Exception e) {
Logger.debug("New created role is allowed.");
res = true;
}
}
// Logger.debug("role allowance check: " + role + ", user: " + user + ", res: " + res);
return res;
}
/**
* This method initializes User object by the default Role.
* @param userUrl
* @return
*/
public static List<Role> setDefaultRole() {
List<Role> res = new ArrayList<Role>();
Role role = findByName(Const.DEFAULT_ROLE);
if (role != null && role.name != null && role.name.length() > 0) {
res.add(role);
}
return res;
}
/**
* This method initializes User object by the default Role by the role name.
* @param userUrl
* @return
*/
public static List<Role> setRoleByName(String roleName) {
List<Role> res = new ArrayList<Role>();
Role role = findByName(roleName);
if (role != null && role.name != null && role.name.length() > 0) {
res.add(role);
}
return res;
}
/**
* Return a page of User
*
* @param page Page to display
* @param pageSize Number of Roles per page
* @param sortBy User property used for sorting
* @param order Sort order (either or asc or desc)
* @param filter Filter applied on the name column
*/
public static Page<Role> page(int page, int pageSize, String sortBy, String order, String filter) {
return find.where().icontains("name", filter)
.orderBy(sortBy + " " + order)
.findPagingList(pageSize)
.setFetchAhead(false)
.getPage(page);
}
public String permissionsAsString() {
// Logger.debug("permissionsAsString");
List<String> names = new ArrayList<String>();
for (Permission permission : this.permissions) {
names.add(permission.name);
}
return StringUtils.join(names, ", ");
}
public static Map<String, String> options() {
LinkedHashMap<String,String> options = new LinkedHashMap<String,String>();
for(Role s : Role.findAll()) {
options.put(s.id.toString(), s.name);
}
return options;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
Role other = (Role) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
@Override
public String toString() {
return "Role [permissions=" + permissions + ", users=" + users
+ ", name=" + name + ", description=" + description
+ ", revision=" + revision + "]";
}
}