Commit 009690c8 by Tuukka Kivilahti

Merge branch 'groupmgmt' into 'master'

Groupmgmt

Humm.. Ehkä vähän turhan iso committi.
Ei pitäisi rikkoa mitään, mutta ei toisaalta oikein vielä toteuta kaikkea haluttua toiminnallisuuttakaan.

Tarkoitus siis lisätä ldap-hallintamahdollisuus moyaan.

kattonut: @tkfftk
2 parents 2d67c6f3 8c607a95
......@@ -36,6 +36,10 @@ public class BootstrapBean implements BootstrapBeanLocal {
dbUpdates.add(new String[] { "ALTER TABLE products ALTER COLUMN vat TYPE NUMERIC(4,3)" });
dbUpdates.add(new String[] { "ALTER TABLE actionlog_messages DROP COLUMN crew" });
dbUpdates.add(new String[] { "delete from application_permissions where application ilike '%terminal%'" });
dbUpdates.add(new String[] {
"ALTER TABLE org_roles ADD ldap_role boolean not null default false",
"ALTER TABLE org_roles ADD ldap_weight integer NOT NULL default 100"
});
}
@EJB
......
package fi.codecrew.moya.beans;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import fi.codecrew.moya.beanutil.LdapUserHandler;
import fi.codecrew.moya.model.LanEventPrivatePropertyKey;
/**
* Session Bean implementation class LdapBean
*/
@Stateless
@LocalBean
public class LdapBean implements LdapBeanLocal {
@EJB
private EventBean eventbean;
/**
* Default constructor.
*/
public LdapConnection getConnection() {
String ldapurl = eventbean.getPrivatePropertyString(LanEventPrivatePropertyKey.LDAP_URL);
String userBase = eventbean.getPrivatePropertyString(LanEventPrivatePropertyKey.LDAP_USER_OU);
String groupBase = eventbean.getPrivatePropertyString(LanEventPrivatePropertyKey.LDAP_GROUP_OU);
LdapConnection conn = null;
if (ldapurl != null && !ldapurl.isEmpty() && userBase != null && !userBase.isEmpty() && groupBase != null && !groupBase.isEmpty()) {
String bindDn = eventbean.getPrivatePropertyString(LanEventPrivatePropertyKey.LDAP_BIND_DN);
String bindPw = eventbean.getPrivatePropertyString(LanEventPrivatePropertyKey.LDAP_BIND_PW);
conn = new LdapConnection(ldapurl, userBase, groupBase, bindDn, bindPw);
}
return conn;
}
private static class LdapConnection extends LdapUserHandler
{
public LdapConnection(String ldapUri, String userBaseDn, String groupBaseDn, String mgmtUser, String mgmtPass) {
super(ldapUri, userBaseDn, groupBaseDn, mgmtUser, mgmtPass);
}
}
}
......@@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory;
import fi.codecrew.moya.enums.apps.IAppPermission;
import fi.codecrew.moya.enums.apps.UserPermission;
import fi.codecrew.moya.facade.EventUserFacade;
import fi.codecrew.moya.facade.RoleFacade;
import fi.codecrew.moya.facade.UserFacade;
import fi.codecrew.moya.model.ApplicationPermission;
......@@ -51,6 +52,11 @@ public class RoleBean implements RoleBeanLocal {
@EJB
private UserFacade userFacade;
@EJB
private EventUserFacade eventuserfacade;
private EventBeanLocal permbean;
// VIEW_ALL pitää olla että voidaan hakea roolien perusteella.
@Override
@RolesAllowed({ UserPermission.S_READ_ROLES, UserPermission.S_VIEW_ALL })
......@@ -161,6 +167,27 @@ public class RoleBean implements RoleBeanLocal {
return role;
}
private void checkRoleLdap()
{
}
@Override
@RolesAllowed(UserPermission.S_WRITE_ROLES)
public Role addRole(EventUser eventuser, Role role)
{
eventuser = eventuserfacade.reload(eventuser);
role = roleFacade.reload(role);
if (!eventuser.getRoles().contains(role)) {
eventuser.getRoles().add(role);
}
if (!role.getUsers().contains(eventuser)) {
role.getUsers().add(eventuser);
}
return role;
}
@Override
@RolesAllowed(UserPermission.S_WRITE_ROLES)
public void saveRoles(EventUser usr, List<Role> usersRoles) {
......
......@@ -167,6 +167,8 @@ public class UserBean implements UserBeanLocal {
// private EventUser currentEventuser;
// private ArrayList<Role> currentEventuserRoles;
// HUOMHUOM! Älä määrittele tätä UserBeanLocal interfacelle.
// Käytä Viewien puolelta findUsersRoles joka tarkistaa käyttäjän oikeudet ensin.
public Set<Role> localFindUsersRoles(EventUser u) {
// if (currentEventuser != null && u.equals(currentEventuser)) {
// logger.debug("Returnin cached eventuserroles for user {}: {}",
......@@ -448,12 +450,6 @@ public class UserBean implements UserBeanLocal {
// return userFacade.find(id);
// }
@Override
@RolesAllowed(UserPermission.S_VIEW_ALL)
public SearchResult<User> getUsers(SearchQuery search) {
return userFacade.searchAllUsers(search);
}
// @Override
// public long getUsersCount(String search) {
// return userFacade.searchUserCount(search);
......@@ -683,17 +679,23 @@ public class UserBean implements UserBeanLocal {
}
@Override
public SearchResult<User> getEventUsers(SearchQuery search) {
if (search.getSearch() == null || search.getSearch().isEmpty())
{
throw new RuntimeException("You should be using getThisEventsUsers if not searching globally...");
// return userFacade.searchEventUsers(search);
} else {
return userFacade.searchAllUsers(search);
}
@RolesAllowed(UserPermission.S_VIEW_ALL)
public SearchResult<User> getUsers(SearchQuery search) {
return userFacade.searchAllUsers(search);
}
// @Override
// public SearchResult<User> getEventUsers(SearchQuery search) {
// if (search.getSearch() == null || search.getSearch().isEmpty())
// {
// throw new RuntimeException("You should be using getThisEventsUsers if not searching globally...");
// // return userFacade.searchEventUsers(search);
// } else {
// return userFacade.searchAllUsers(search);
// }
//
// }
//
@Override
public SearchResult<EventUser> getThisEventsUsers(UserSearchQuery searchQuery) {
SearchResult<EventUser> returnUsers = eventUserFacade.searchEventUsers(searchQuery);
......@@ -769,4 +771,9 @@ public class UserBean implements UserBeanLocal {
return false;
}
@Override
public User getUser(Integer id) {
return userFacade.find(id);
}
}
\ No newline at end of file
package fi.codecrew.moya.beanutil;
/**
* Copyright Iudex / Tuomas Riihimäki
*
*/
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import javax.naming.AuthenticationException;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.OrgRole;
import fi.codecrew.moya.utilities.PasswordFunctions;
public class LdapUserHandler {
private final String ldapURI;
private final String userBaseDn;
//private final String roleBaseDn;
private final String mgmtPass;
private final String mgmtUser;
private final String roleBaseDn;
private String fallbackuser = null;
private String fallbackpass = null;
private static final String MEMBER_OF_FIELD = "memberOf";
private static final Logger logger = LoggerFactory.getLogger(LdapUserHandler.class);
private static final Charset LATIN1 = Charset.forName("ISO-8859-1");
private Integer gidBase = 20000;
private Integer uidBase = 20000;
public enum PasswordChangeStatus {
PWD_CHANGED, PWD_COMPLEXITY_NOT_MET, UNKNOWN_ERROR, WRONG_PASSWORD, UNKNOWN_USER,
}
public LdapUserHandler(String ldapUri, String userBaseDn, String roleBaseDn, String mgmtUser, String mgmtPass)
{
this.ldapURI = ldapUri;
this.userBaseDn = userBaseDn;
this.roleBaseDn = roleBaseDn;
this.mgmtUser = mgmtUser;
this.mgmtPass = mgmtPass;
}
protected InitialLdapContext getContext() throws NamingException {
return createInitialContext(mgmtUser, mgmtPass, true);
}
private InitialLdapContext createInitialContext(String userRDN, String password, boolean pool) throws NamingException {
Hashtable<String, String> authEnv = new Hashtable<String, String>(11);
authEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
authEnv.put(Context.PROVIDER_URL, ldapURI);
if (password != null && userRDN != null && !userRDN.isEmpty()) {
authEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
authEnv.put(Context.SECURITY_PRINCIPAL, userRDN);
authEnv.put(Context.SECURITY_CREDENTIALS, password);
authEnv.put(Context.REFERRAL, "follow");
if (ldapURI.startsWith("ldaps"))
{
authEnv.put("java.naming.ldap.factory.socket",
"fi.iudex.utils.ldap.NocheckSSLSocketFactory");
authEnv.put(Context.SECURITY_PROTOCOL, "ssl");
}
if (pool) {
// Default AD timeout value is 900..
authEnv.put("com.sun.jndi.ldap.connect.pool.timeout", "900");
authEnv.put("com.sun.jndi.ldap.connect.pool", "true");
}
// authEnv.put(Context.SECURITY_PROTOCOL, "ssl");
}
return new InitialLdapContext(authEnv, null);
}
protected List<String> createLdapAttrSingleAttrSearch(String baseDn, String filter, String field) {
Map<String, List<String>> retMap = createLdapAttrUniqueDnSearch(baseDn, filter, field);
List<String> ret = null;
if (retMap != null) {
ret = retMap.get(field);
}
return ret;
}
protected Map<String, List<String>> createLdapAttrUniqueDnSearch(String baseDn, String filter, String... fields)
{
Map<String, Map<String, List<String>>> retMap = createLdapAttrSearch(baseDn, filter, fields);
Map<String, List<String>> ret = null;
if (retMap != null) {
if (retMap.isEmpty()) {
ret = new HashMap<>();
} else if (retMap.size() != 1) {
throw new RuntimeException("Got multiple results for attribute search with filter: " + filter);
} else {
ret = retMap.values().iterator().next();
}
}
return ret;
}
protected Map<String, Map<String, List<String>>> createLdapAttrSearch(String baseDn, String filter, String... fields)
{
InitialLdapContext ctx = null;
Map<String, Map<String, List<String>>> ret = new HashMap<>();
try {
ctx = getContext();
SearchControls ctls = new SearchControls();
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
ctls.setReturningAttributes(fields);
NamingEnumeration<SearchResult> results = ctx.search(baseDn, filter, ctls);
while (results.hasMore())
{
SearchResult result = results.next();
logger.info("Got dn:{}", result.getName());
Map<String, List<String>> resultAttrs = ret.get(result.getName());
if (resultAttrs == null) {
resultAttrs = new HashMap<>();
ret.put(result.getName(), resultAttrs);
}
NamingEnumeration<? extends Attribute> searchAttrs = result.getAttributes().getAll();
while (searchAttrs.hasMore()) {
Attribute next = searchAttrs.next();
logger.info("Got {}, {}, {}", next.getID(), next.get(), searchAttrs.hasMore());
if (next == null || next.get() == null)
continue;
List<String> resultList = resultAttrs.get(next.getID());
if (resultList == null) {
resultList = new ArrayList<>();
resultAttrs.put(next.getID(), resultList);
}
NamingEnumeration<?> searchField = next.getAll();
while (searchField.hasMore()) {
Object fieldResult = searchField.next();
if (fieldResult != null) {
resultList.add(fieldResult.toString());
}
}
}
}
} catch (NamingException e) {
logger.warn("Error searching parameters", e);
} finally {
close(ctx);
}
return ret;
}
// public Set<String> getMemberships(String user) {
// Set<String> rolenames = new HashSet<String>();
// InitialLdapContext ctx = null;
// try {
// ctx = getContext();
// NamingEnumeration<SearchResult> roleSearch = getLdapParameters(ctx, user, MEMBER_OF_FIELD);
// if (roleSearch.hasMore())
// {
// SearchResult result = roleSearch.next();
//
// if (roleSearch.hasMore()) {
// logger.warn("Found multiple users Clearing usergroups! {}", roleSearch.next());
// return null;
// }
// Attribute groupAttrs = result.getAttributes().get(MEMBER_OF_FIELD);
//
// if (groupAttrs != null) {
// NamingEnumeration<?> roleOUs = groupAttrs.getAll();
// while (roleOUs.hasMore()) {
// String roleObject = roleOUs.next().toString();
// Matcher roleFinder = GROUP_PATTERN.matcher(roleObject);
//
// if (roleFinder.find()) {
// String roleName = roleFinder.group(1);
// logger.info("Got group {} to user {}", roleName, user);
// rolenames.add(roleName);
// }
// else {
// logger.info("role pattern did not match {}", roleObject);
// }
// }
// }
//
// }
// } catch (CommunicationException ce) {
// rolenames = null;
// logger.info("Error connecting to server", ce);
//
// } catch (NamingException e) {
// logger.warn("Error while getting group names.", e);
// } finally {
// close(ctx);
// }
// return rolenames;
//
// }
protected NamingEnumeration<SearchResult> getLdapParameters(InitialLdapContext ctx, String user, String... attrs) throws NamingException {
StringBuilder filter = new StringBuilder("(&(objectClass=posixAccount)(uid=").append(user).append("))");
SearchControls ctls = new SearchControls();
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
ctls.setReturningAttributes(attrs);
return ctx.search(this.userBaseDn, filter.toString(), ctls);
}
public String createUser(EventUser user, List<OrgRole> roles)
{
InitialLdapContext ctx = null;
OrgRole primary = null;
for (OrgRole role : roles) {
if (role.isLdapRole() && (primary == null || primary.getLdapWeight() < role.getLdapWeight())) {
primary = role;
}
}
String dnStr = null;
try {
StringBuilder dnBld = new StringBuilder();
dnBld.append("uid=").append(user.getLogin());
dnBld.append(",ou=").append(primary.getName());
dnBld.append(",").append(userBaseDn);
String dn = dnBld.toString();
ctx = getContext();
BasicAttributes entry = new BasicAttributes();
entry.put(new BasicAttribute("uid", user.getLogin()));
entry.put(new BasicAttribute("givenName", user.getFirstnames()));
entry.put(new BasicAttribute("sn", user.getLastname()));
entry.put(new BasicAttribute("cn", user.getWholeName()));
entry.put(new BasicAttribute("loginShell", "/bin/bash"));
entry.put(new BasicAttribute("homeDirectory", user.getLogin()));
entry.put(new BasicAttribute("uidNumber", uidBase + user.getId()));
entry.put(new BasicAttribute("gidNumber", gidBase + primary.getId()));
entry.put(new BasicAttribute("userPassword", user.getPassword()));
entry.put(new BasicAttribute("mail", user.getEmail()));
BasicAttribute oc = new BasicAttribute("objectClass");
oc.add("inetOrgPerson");
oc.add("posixAccount");
oc.add("shadowAccount");
oc.add("person");
oc.add("organizationalPerson");
entry.put(oc);
ctx.createSubcontext(dn, entry);
dnStr = dn;
} catch (NamingException e) {
logger.warn("Error while creating user to ldap");
} finally {
close(ctx);
}
return dnStr;
}
protected String buildUserRdn(String username) {
InitialLdapContext ctx = null;
String ret = null;
try {
ctx = getContext();
SearchControls ctls = new SearchControls();
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
ctls.setReturningAttributes(new String[] { "dn" });
NamingEnumeration<SearchResult> result = ctx.search(this.userBaseDn, "uid=" + username, ctls);
if (result.hasMore()) {
SearchResult dn = result.next();
ret = dn.getNameInNamespace();
}
} catch (NamingException e) {
logger.warn("Error building RDN", e);
} finally {
close(ctx);
}
return ret;
}
public boolean authenticate(String username, char[] passwd) {
String pwd = new String(passwd);
if (username == null || passwd == null || username.isEmpty() || pwd.isEmpty()) {
return false;
}
InitialLdapContext userCtx = null;
try {
String userDn = buildUserRdn(username);
if (userDn == null || userDn.isEmpty()) {
logger.info("Username {}, not found when authenticating");
return false;
}
userCtx = createInitialContext(userDn, pwd, false);
return true;
} catch (AuthenticationException authEx) {
logger.info("Authentication failed!", authEx);
} catch (CommunicationException ce) {
// If ldap server can not be reached, check if we are trying to auth with fallback credentials
// WARNING!!!! THIS IS A BACKDOOR! DO NOT USE IN PRODUCTION!
if (username.equals(fallbackuser) && pwd.equals(fallbackpass)) {
logger.warn("Login successfull for backupuser. ");
return true;
} else {
logger.info("Error connecting to ldapserver", ce);
}
} catch (NamingException e) {
logger.warn("Error connecting to auth context", e);
} finally {
close(userCtx);
}
return false;
}
protected void close(InitialLdapContext userCtx) {
try {
if (userCtx != null) {
userCtx.close();
}
userCtx = null;
} catch (NamingException e) {
logger.warn("Error closing...", e);
}
}
public PasswordChangeStatus changePassword(String username, String oldPwd, String newPwd) {
InitialLdapContext userCtx = null;
try {
String newHash = PasswordFunctions.getEncryptedPassword(newPwd);
String userDn = buildUserRdn(username);
if (userDn == null || userDn.isEmpty()) {
return PasswordChangeStatus.UNKNOWN_USER;
}
logger.info("Chpass {} for user {} ", newHash, userDn);
userCtx = createInitialContext(userDn, oldPwd, false);
ModificationItem[] mods = new ModificationItem[1];
Attribute mod0 = new BasicAttribute("userpassword", newHash);
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, mod0);
userCtx.modifyAttributes(userDn, mods);
} catch (NamingException e) {
logger.warn("Error changing password", e);
return PasswordChangeStatus.UNKNOWN_ERROR;
} finally {
close(userCtx);
}
return PasswordChangeStatus.PWD_CHANGED;
}
protected void setFallbackpass(String fallbackpass) {
this.fallbackpass = fallbackpass;
}
protected void setFallbackuser(String fallbackuser) {
this.fallbackuser = fallbackuser;
}
}
package fi.codecrew.moya.beans;
import javax.ejb.Local;
@Local
public interface LdapBeanLocal {
}
......@@ -36,4 +36,6 @@ public interface RoleBeanLocal {
public List<Role> getRoles(EventUser selectedUser);
Role addRole(EventUser eventuser, Role role);
}
......@@ -26,7 +26,7 @@ public interface UserBeanLocal {
SearchResult<User> getUsers(SearchQuery search);
SearchResult<User> getEventUsers(SearchQuery search);
//SearchResult<User> getEventUsers(SearchQuery search);
EventUser mergeChanges(EventUser user);
......@@ -40,6 +40,8 @@ public interface UserBeanLocal {
boolean resetPassword(User user, String password, String hash);
public User getUser(Integer id);
/**
* Search EventUser entity by User entity ID
*
......
......@@ -107,7 +107,7 @@ public class EventUser extends GenericEntity {
@OneToMany(mappedBy = "eventUser")
private List<GameID> gameIDs;
public List<GameID> getGameIDs() {
return gameIDs;
}
......@@ -115,7 +115,7 @@ public class EventUser extends GenericEntity {
public void setGameIDs(List<GameID> gameIDs) {
this.gameIDs = gameIDs;
}
public EventUser getCreator() {
return creator;
}
......@@ -449,11 +449,9 @@ public class EventUser extends GenericEntity {
return ret;
}
public String getShortUserDescriptor() {
StringBuilder sb = new StringBuilder();
sb.append(getNick()).append(" // ").append(getWholeName()).append(" // ").append(getEmail());
return sb.toString();
return user.getShortUserDescriptor();
}
}
......@@ -8,6 +8,11 @@ public enum LanEventPrivatePropertyKey {
CHECKOUT_FI_MERCHANT_PASSWORD(Type.TEXT, null),
CHECKOUT_FI_MERCHANT_ID(Type.TEXT, null),
CHECKOUT_FI_KEY_EXPIRE(Type.DATE, null),
LDAP_URL(Type.TEXT, null),
LDAP_BIND_DN(Type.TEXT, null),
LDAP_BIND_PW(Type.TEXT, null),
LDAP_USER_OU(Type.TEXT, null),
LDAP_GROUP_OU(Type.TEXT, null),
;
private enum Type {
......
......@@ -57,6 +57,28 @@ public class OrgRole extends GenericEntity {
@ManyToMany(mappedBy = "orgRoles")
private List<Role> eventRoles;
@Column(name = "ldap_role", nullable = false)
private boolean ldapRole = false;
@Column(name = "ldap_weight", nullable = false)
private int ldapWeight = 100;
public boolean isLdapRole() {
return ldapRole;
}
public void setLdapRole(boolean ldapRole) {
this.ldapRole = ldapRole;
}
public int getLdapWeight() {
return ldapWeight;
}
public void setLdapWeight(int ldapWeight) {
this.ldapWeight = ldapWeight;
}
public OrgRole() {
super();
}
......
......@@ -14,7 +14,6 @@ import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
......@@ -409,4 +408,10 @@ public class User extends GenericEntity implements IUser {
return age;
}
public String getShortUserDescriptor() {
StringBuilder sb = new StringBuilder();
sb.append(getNick()).append(" // ").append(getWholeName()).append(" // ").append(getEmail());
return sb.toString();
}
}
package fi.codecrew.moya.utilities;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
* Copyright Iudex / Tuomas Riihimäki
*
*/
public class ByteUtils {
public static int parseUnsigned(byte... b) {
if (b.length > 4) {
throw new RuntimeException("Integer should never have more than 4 bytes!");
}
return new BigInteger(1, b).intValue();
}
public static Long parseUnsignedLong(byte[] b) {
if (b.length > 8) {
throw new RuntimeException("Long should never have more than 4 bytes!");
}
return new BigInteger(1, b).longValue();
}
public static short parseSigned(byte b0, byte b1) {
return (short) (((b0 & 0xff) << 8) | (b1 & 0xff));
}
public static Integer parseSignedO(byte b, byte c) {
return Integer.valueOf(parseSigned(b, c));
}
public static Integer parseSigned(byte b1, byte b2, byte b3, byte b4) {
return (b1 & 0xff) << 24 | (b2 & 0xff) << 16 | (b3 & 0xff) << 8 | (b4 & 0xff);
}
public static void main(String[] ads)
{
System.out.println(parseUnsigned((byte) 0x31, (byte) 0x79));
// System.out.println(parseSignedDecimal("+5.123"));
// System.out.println(parseSignedDecimal("-5.123"));
// System.out.println(parseSignedDecimal(" - 5123"));
// System.out.println(parseSignedDecimal(null));
// System.out.println(parseSignedDecimal(""));
// System.out.println(parseSignedDecimal(" "));
}
public static BigDecimal parseSignedDecimal(String number) {
if (number == null || (number = number.trim()).isEmpty()) {
return null;
}
number = number.trim();
char firstChar = number.charAt(0);
boolean signPositive = true;
switch (firstChar) {
case '-':
signPositive = false;
case '+':
number = number.substring(1).trim();
}
BigDecimal ret = new BigDecimal(number);
if (!signPositive) {
ret = ret.negate();
}
return ret;
}
// public static int parseSignedInt(byte... b) {
// if (b.length > 4) {
// throw new
// RuntimeException("Integer should never have more than 4 bytes!");
// }
// // return new BigInteger(1, b).intValue();
//
// int value = (b[b.length - 1] & 0xff);
// if (b.length > 1) {
// value |= (b[b.length - 2] & 0xff) << 8;
// }
// if (b.length > 2) {
// value |= (b[b.length - 3] & 0xff) << 16;
// }
// if (b.length > 3) {
// value |= (b[b.length - 4] & 0xff) << 24;
// }
// return value;
// }
/**
* Copies the integer value to four bytes in the destination bytearray beginning from the offset
*
* Notice! This function handles signed integers: -1 -> 0xff 0xff 0xff 0xff
*
* @param dst
* @param offset
* @param value
*/
public static void intToBytearray(byte[] dst, int offset, int value) {
dst[offset++] = (byte) (value >>> 24);
dst[offset++] = (byte) (value >>> 16);
dst[offset++] = (byte) (value >>> 8);
dst[offset] = (byte) (value);
}
public static byte[] toArray(int... bytes) {
byte[] ret = new byte[bytes.length];
for (int i = 0; i < bytes.length; ++i) {
ret[i] = (byte) (bytes[i]);
}
return ret;
}
public static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
int val = ((int) b) & 0xff;
if (val < 0x10)
sb.append("0");
sb.append(Integer.toHexString(val));
}
return sb.toString();
}
}
......@@ -70,7 +70,6 @@ public class JpegReader {
JpegImageParser parser = new JpegImageParser();
ByteSource byteSource = new ByteSourceFile(file);
@SuppressWarnings("rawtypes")
List<Segment> segments = parser.readSegments(byteSource, new int[] { 0xffee }, true);
if (segments != null && segments.size() >= 1) {
UnknownSegment app14Segment = (UnknownSegment) segments.get(0);
......
package fi.codecrew.moya.utilities;
import java.security.MessageDigest;
public class MD4Digest extends MessageDigest {
/**
* The size in bytes of the input block to the tranformation algorithm.
*/
private static final int BLOCK_LENGTH = 64; // = 512 / 8;
/**
* 4 32-bit words (interim result)
*/
private int[] context = new int[4];
/**
* Number of bytes processed so far mod. 2 power of 64.
*/
private long count;
/**
* 512 bits input buffer = 16 x 32-bit words holds until reaches 512 bits.
*/
private byte[] buffer = new byte[BLOCK_LENGTH];
/**
* 512 bits work buffer = 16 x 32-bit words
*/
private int[] X = new int[16];
public MD4Digest() {
super("MD4");
engineReset();
}
@Override
public void engineUpdate(byte b) {
int i = (int) (count % BLOCK_LENGTH);
count++;
buffer[i] = b;
if (i == BLOCK_LENGTH - 1)
transform(buffer, 0);
}
@Override
protected void engineUpdate(byte[] input, int offset, int len) {
// make sure we don't exceed input's allocated size/length
if (offset < 0 || len < 0 || (long) offset + len > input.length)
throw new ArrayIndexOutOfBoundsException();
// compute number of bytes still unhashed; ie. present in buffer
int bufferNdx = (int) (count % BLOCK_LENGTH);
count += len; // update number of bytes
int partLen = BLOCK_LENGTH - bufferNdx;
int i = 0;
if (len >= partLen) {
System.arraycopy(input, offset, buffer, bufferNdx, partLen);
transform(buffer, 0);
for (i = partLen; i + BLOCK_LENGTH - 1 < len; i += BLOCK_LENGTH)
transform(input, offset + i);
bufferNdx = 0;
}
// buffer remaining input
if (i < len)
System.arraycopy(input, offset + i, buffer, bufferNdx, len - i);
}
@Override
protected byte[] engineDigest() {
// pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512
int bufferNdx = (int) (count % BLOCK_LENGTH);
int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx);
// padding is alwas binary 1 followed by binary 0s
byte[] tail = new byte[padLen + 8];
tail[0] = (byte) 0x80;
// append length before final transform:
// save number of bits, casting the long to an array of 8 bytes
// save low-order byte first.
for (int i = 0; i < 8; i++)
tail[padLen + i] = (byte) ((count * 8) >>> (8 * i));
engineUpdate(tail, 0, tail.length);
byte[] result = new byte[16];
// cast this MD4's context (array of 4 ints) into an array of 16 bytes.
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
result[i * 4 + j] = (byte) (context[i] >>> (8 * j));
// reset the engine
engineReset();
return result;
}
@Override
protected void engineReset() {
// initial values of MD4 i.e. A, B, C, D
// as per rfc-1320; they are low-order byte first
context[0] = 0x67452301;
context[1] = 0xEFCDAB89;
context[2] = 0x98BADCFE;
context[3] = 0x10325476;
count = 0L;
for (int i = 0; i < BLOCK_LENGTH; i++)
buffer[i] = 0;
}
/**
* MD4 basic transformation.
* <p>
* Transforms context based on 512 bits from input block starting from the offset'th byte.
*
* @param block
* input sub-array.
* @param offset
* starting position of sub-array.
*/
private void transform(byte[] block, int offset) {
// encodes 64 bytes from input block into an array of 16 32-bit
// entities. Use A as a temp var.
for (int i = 0; i < 16; i++)
X[i] = (block[offset++] & 0xFF) |
(block[offset++] & 0xFF) << 8 |
(block[offset++] & 0xFF) << 16 |
(block[offset++] & 0xFF) << 24;
int A = context[0];
int B = context[1];
int C = context[2];
int D = context[3];
A = FF(A, B, C, D, X[0], 3);
D = FF(D, A, B, C, X[1], 7);
C = FF(C, D, A, B, X[2], 11);
B = FF(B, C, D, A, X[3], 19);
A = FF(A, B, C, D, X[4], 3);
D = FF(D, A, B, C, X[5], 7);
C = FF(C, D, A, B, X[6], 11);
B = FF(B, C, D, A, X[7], 19);
A = FF(A, B, C, D, X[8], 3);
D = FF(D, A, B, C, X[9], 7);
C = FF(C, D, A, B, X[10], 11);
B = FF(B, C, D, A, X[11], 19);
A = FF(A, B, C, D, X[12], 3);
D = FF(D, A, B, C, X[13], 7);
C = FF(C, D, A, B, X[14], 11);
B = FF(B, C, D, A, X[15], 19);
A = GG(A, B, C, D, X[0], 3);
D = GG(D, A, B, C, X[4], 5);
C = GG(C, D, A, B, X[8], 9);
B = GG(B, C, D, A, X[12], 13);
A = GG(A, B, C, D, X[1], 3);
D = GG(D, A, B, C, X[5], 5);
C = GG(C, D, A, B, X[9], 9);
B = GG(B, C, D, A, X[13], 13);
A = GG(A, B, C, D, X[2], 3);
D = GG(D, A, B, C, X[6], 5);
C = GG(C, D, A, B, X[10], 9);
B = GG(B, C, D, A, X[14], 13);
A = GG(A, B, C, D, X[3], 3);
D = GG(D, A, B, C, X[7], 5);
C = GG(C, D, A, B, X[11], 9);
B = GG(B, C, D, A, X[15], 13);
A = HH(A, B, C, D, X[0], 3);
D = HH(D, A, B, C, X[8], 9);
C = HH(C, D, A, B, X[4], 11);
B = HH(B, C, D, A, X[12], 15);
A = HH(A, B, C, D, X[2], 3);
D = HH(D, A, B, C, X[10], 9);
C = HH(C, D, A, B, X[6], 11);
B = HH(B, C, D, A, X[14], 15);
A = HH(A, B, C, D, X[1], 3);
D = HH(D, A, B, C, X[9], 9);
C = HH(C, D, A, B, X[5], 11);
B = HH(B, C, D, A, X[13], 15);
A = HH(A, B, C, D, X[3], 3);
D = HH(D, A, B, C, X[11], 9);
C = HH(C, D, A, B, X[7], 11);
B = HH(B, C, D, A, X[15], 15);
context[0] += A;
context[1] += B;
context[2] += C;
context[3] += D;
}
private int FF(int a, int b, int c, int d, int x, int s) {
int t = a + ((b & c) | (~b & d)) + x;
return t << s | t >>> (32 - s);
}
private int GG(int a, int b, int c, int d, int x, int s) {
int t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999;
return t << s | t >>> (32 - s);
}
private int HH(int a, int b, int c, int d, int x, int s) {
int t = a + (b ^ c ^ d) + x + 0x6ED9EBA1;
return t << s | t >>> (32 - s);
}
}
package fi.codecrew.moya.utilities;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Copyright Iudex / Tuomas Riihimäki
*
*/
public class NTLMFunctions {
private static final Charset UTF16LE_ENCODING = Charset.forName("UTF-16LE");
private static final Logger logger = LoggerFactory.getLogger(NTLMFunctions.class);
public static String getNTHash(String passAttr)
{
StringBuilder pwd = new StringBuilder();
// pwd.append('"');
pwd.append(passAttr);
// pwd.append('"');
String ret = null;
try {
byte pwdBytes[] = pwd.toString().getBytes(UTF16LE_ENCODING);
//MD4 algo = new MD4();
MessageDigest algo = new MD4Digest();
byte[] bytes = algo.digest(pwdBytes);
ret = ByteUtils.toHexString(bytes);
//logger.info("hex: {}", ret);
} finally {
}
return ret;
}
}
......@@ -2,7 +2,8 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:tools="http://java.sun.com/jsf/composite/tools" xmlns:role="http://java.sun.com/jsf/composite/tools/role">
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:p="http://primefaces.org/ui" xmlns:tools="http://java.sun.com/jsf/composite/tools"
xmlns:role="http://java.sun.com/jsf/composite/tools/role">
<composite:interface>
......@@ -10,6 +11,7 @@
<composite:implementation>
<p>
<h:form id="roleform">
<f:facet name="errorMessage">
......@@ -20,33 +22,65 @@
</h:form>
</p>
<h2>#{i18n['role.permissionheader']}</h2>
<p>
<h:form id="permissionform">
<h:commandButton id="save1" value="#{i18n['role.savePermissions']}" action="#{roleView.savePermissions}" />
<h:dataTable border="1" id="bortalApps" value="#{roleView.rolePermissions}" var="bapp">
<h:column>
<f:facet name="header">
<h:outputText value="#{i18n['applicationPermission.name']}" />
</f:facet>
<h:outputText value="#{bapp.name}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{i18n['applicationPermission.description']}" />
</f:facet>
<h:outputText value="#{i18n[bapp.key]}" />
</h:column>
<h:column>
<h:selectManyCheckbox id="permissions" layout="pageDirection" value="#{bapp.selected}">
<f:selectItems value="#{bapp.permissions}" var="per" itemLabel="#{i18n[per.i18nKey]}" />
</h:selectManyCheckbox>
</h:column>
</h:dataTable>
<h:commandButton id="save2" value="#{i18n['role.savePermissions']}" action="#{roleView.savePermissions}" />
<h:form id="addmember">
<h:outputText value="#{i18n['roleView.adduser']}" />
<p:autoComplete id="useradder" value="#{roleView.addableUser}" completeMethod="#{roleView.searchUser}" converter="#{userConverter}" var="usr" itemValue="#{usr}"
itemLabel="#{usr.shortUserDescriptor}">
<p:ajax onerror="location.reload(true);" update=":editor:addmember,:editor:memberlist" event="itemSelect" listener="#{roleView.addUser}" />
</p:autoComplete>
</h:form>
</p>
<h:dataTable id="memberlist" value="#{roleView.role.users}" var="usr">
<h:column>
<h:outputText value="#{usr.login}" />
</h:column>
<h:column>
<h:outputText value="#{usr.nick}" />
</h:column>
<h:column>
<h:outputText value="#{usr.wholeName}" />
</h:column>
<h:column>
<h:outputText value="#{usr.email}" />
</h:column>
</h:dataTable>
<button id="roledisplayer" onclick='$("#roleeditor").show(); $(this).hide();'>#{i18n['role.showPermissioneditor']}</button>
<div id="roleeditor" style="display: none">
<button onclick='$("#roleeditor").hide(); $("#roledisplayer").show();'>#{i18n['role.hidePermissioneditor']}</button>
<h2>#{i18n['role.permissionheader']}</h2>
<p>
<h:form id="permissionform">
<h:commandButton id="save1" value="#{i18n['role.savePermissions']}" action="#{roleView.savePermissions}" />
<h:dataTable border="1" id="bortalApps" value="#{roleView.rolePermissions}" var="bapp">
<h:column>
<f:facet name="header">
<h:outputText value="#{i18n['applicationPermission.name']}" />
</f:facet>
<h:outputText value="#{bapp.name}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{i18n['applicationPermission.description']}" />
</f:facet>
<h:outputText value="#{i18n[bapp.key]}" />
</h:column>
<h:column>
<h:selectManyCheckbox id="permissions" layout="pageDirection" value="#{bapp.selected}">
<f:selectItems value="#{bapp.permissions}" var="per" itemLabel="#{i18n[per.i18nKey]}" />
</h:selectManyCheckbox>
</h:column>
</h:dataTable>
<h:commandButton id="save2" value="#{i18n['role.savePermissions']}" action="#{roleView.savePermissions}" />
</h:form>
</p>
</div>
</composite:implementation>
......
......@@ -12,7 +12,7 @@
<f:event type="preRenderView" listener="#{roleView.initViewFromId()}" />
</f:metadata>
<ui:define name="content">
<role:edit />
<role:edit id="editor"/>
</ui:define>
</ui:composition>
</h:body>
......
......@@ -15,11 +15,16 @@ import org.slf4j.LoggerFactory;
import fi.codecrew.moya.beans.EventBeanLocal;
import fi.codecrew.moya.beans.RoleBeanLocal;
import fi.codecrew.moya.beans.UserBeanLocal;
import fi.codecrew.moya.enums.BortalApplication;
import fi.codecrew.moya.enums.apps.IAppPermission;
import fi.codecrew.moya.enums.apps.UserPermission;
import fi.codecrew.moya.model.ApplicationPermission;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.Role;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.util.UserSearchQuery;
import fi.codecrew.moya.utilities.SearchResult;
import fi.codecrew.moya.web.cdiview.GenericCDIView;
import fi.codecrew.moya.web.helpers.BortalApplicationWrapper;
......@@ -41,6 +46,10 @@ public class RoleView extends GenericCDIView {
private transient EventBeanLocal eventbean;
private ArrayList<BortalApplicationWrapper> rolePermissions;
@EJB
private UserBeanLocal userbean;
private User addableUser;
private static final Logger logger = LoggerFactory.getLogger(RoleView.class);
......@@ -59,6 +68,23 @@ public class RoleView extends GenericCDIView {
}
}
public void addUser()
{
EventUser eu = userbean.getEventUser(addableUser);
role = rolebean.addRole(eu, role);
addableUser = null;
}
public List<User> searchUser(String user)
{
// By default this returns only 20 first results.
UserSearchQuery usq = new UserSearchQuery();
usq.setSearch(user);
usq.setOnlyThisEvent(false);
SearchResult<User> ret = userbean.getUsers(usq);
return ret.getResults();
}
public boolean isCanReadRoles() {
return permbean.hasPermission(UserPermission.READ_ROLES);
}
......@@ -170,4 +196,12 @@ public class RoleView extends GenericCDIView {
initPermissions();
}
public User getAddableUser() {
return addableUser;
}
public void setAddableUser(User addableUser) {
this.addableUser = addableUser;
}
}
......@@ -76,11 +76,11 @@ public class UserSearchView extends PaginationView<User> {
this.setRowCount(new Long(sr.getResultcount()).intValue());
setResultcount(sr.getResultcount());
setEventUserResults(sr.getResults());
return sr.getResults();
}
@Override
public void setRowIndex(int rowIndex) {
if (getPageSize() == 0) {
......@@ -99,7 +99,7 @@ public class UserSearchView extends PaginationView<User> {
this.setEventUserResults(eventusers.getResults());
}
else {
super.setResult(userbean.getEventUsers(getSearchQuery()));
super.setResult(userbean.getUsers(getSearchQuery()));
}
super.beginConversation();
}
......
package fi.codecrew.moya.web.converter;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import fi.codecrew.moya.beans.UserBeanLocal;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.utilities.jsf.GenericIntegerEntityConverter;
@Named
@RequestScoped
public class UserConverter extends GenericIntegerEntityConverter<User> {
@EJB
private UserBeanLocal userbean;
@Override
protected User find(Integer id) {
return userbean.getUser(id);
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!