001 package railo.runtime.security; 002 003 import java.io.IOException; 004 import java.util.Set; 005 006 import railo.commons.digest.MD5; 007 import railo.commons.io.IOUtil; 008 import railo.commons.io.res.Resource; 009 import railo.runtime.coder.Base64Coder; 010 import railo.runtime.exp.ApplicationException; 011 import railo.runtime.exp.PageException; 012 import railo.runtime.op.Caster; 013 import railo.runtime.type.Array; 014 import railo.runtime.type.util.ListUtil; 015 016 /** 017 * User Password Information 018 */ 019 public final class CredentialImpl implements Credential { 020 String username; 021 String password; 022 String[] roles; 023 private Resource rolesDir; 024 private static final char ONE=(char)1; 025 026 /** 027 * credential constructor 028 * @param username 029 */ 030 public CredentialImpl(String username,Resource rolesDir) { 031 this(username,null,new String[0],rolesDir); 032 } 033 034 /** 035 * credential constructor 036 * @param username 037 * @param password 038 */ 039 public CredentialImpl(String username,String password,Resource rolesDir) { 040 this(username,password,new String[0],rolesDir); 041 } 042 043 /** 044 * credential constructor 045 * @param username 046 * @param password 047 * @param roles 048 * @throws PageException 049 */ 050 public CredentialImpl(String username,String password, String roles,Resource rolesDir) throws PageException { 051 this(username,password,toRole(roles),rolesDir); 052 } 053 054 /** 055 * credential constructor 056 * @param username 057 * @param password 058 * @param roles 059 * @throws PageException 060 */ 061 public CredentialImpl(String username,String password, Array roles,Resource rolesDir) throws PageException { 062 this(username,password,toRole(roles),rolesDir); 063 } 064 065 /** 066 * credential constructor 067 * @param username 068 * @param password 069 * @param roles 070 */ 071 public CredentialImpl(String username,String password,String[] roles,Resource rolesDir) { 072 this.username=username; 073 this.password=password; 074 this.roles=roles; 075 this.rolesDir=rolesDir; 076 } 077 078 @Override 079 public String getPassword() { 080 return password; 081 } 082 @Override 083 public String[] getRoles() { 084 return roles; 085 } 086 @Override 087 public String getUsername() { 088 return username; 089 } 090 091 /** 092 * convert a Object to a String Array of Roles 093 * @param oRoles 094 * @return roles 095 * @throws PageException 096 */ 097 public static String[] toRole(Object oRoles) throws PageException { 098 if(oRoles instanceof String) { 099 oRoles=ListUtil.listToArrayRemoveEmpty(oRoles.toString(),","); 100 } 101 102 if(oRoles instanceof Array) { 103 Array arrRoles = (Array) oRoles; 104 String[] roles=new String[arrRoles.size()]; 105 for(int i=0;i<roles.length;i++) { 106 roles[i]=Caster.toString(arrRoles.get(i+1,"")); 107 } 108 return roles; 109 } 110 throw new ApplicationException("invalid roles definition for tag loginuser"); 111 } 112 113 public String serialize() { 114 return serialize(null); 115 } 116 117 public String serialize(Set<Object> done) { 118 return "createObject('java','railo.runtime.security.Credential').init('"+username+"','"+password+"','"+ListUtil.arrayToList(roles,",")+"')"; 119 } 120 121 122 @Override 123 public String encode() throws PageException{ 124 String raw=ListUtil.arrayToList(roles,","); 125 if(raw.length()>100){ 126 try { 127 if(!rolesDir.exists())rolesDir.mkdirs(); 128 String md5 = MD5.getDigestAsString(raw); 129 IOUtil.write(rolesDir.getRealResource(md5), raw, "utf-8", false); 130 return Caster.toB64(username+ONE+password+ONE+"md5:"+md5,"UTF-8"); 131 } 132 catch (IOException e) {} 133 } 134 try { 135 return Caster.toB64(username+ONE+password+ONE+raw,"UTF-8"); 136 } catch (Exception e) { 137 throw Caster.toPageException(e); 138 } 139 } 140 141 /** 142 * decode the Credential form a Base64 String value 143 * @param encoded 144 * @return Credential from decoded string 145 * @throws PageException 146 */ 147 public static Credential decode(Object encoded,Resource rolesDir) throws PageException { 148 String dec; 149 try { 150 dec=Base64Coder.decodeToString(Caster.toString(encoded),"UTF-8"); 151 } catch (Exception e) { 152 throw Caster.toPageException(e); 153 } 154 155 Array arr=ListUtil.listToArray(dec,""+ONE); 156 int len=arr.size(); 157 if(len==3) { 158 String str=Caster.toString(arr.get(3,"")); 159 if(str.startsWith("md5:")){ 160 if(!rolesDir.exists())rolesDir.mkdirs(); 161 str=str.substring(4); 162 Resource md5 = rolesDir.getRealResource(str); 163 try { 164 str=IOUtil.toString(md5, "utf-8"); 165 } catch (IOException e) { 166 str=""; 167 } 168 } 169 170 return new CredentialImpl(Caster.toString(arr.get(1,"")),Caster.toString(arr.get(2,"")),str,rolesDir); 171 } 172 if(len==2) return new CredentialImpl(Caster.toString(arr.get(1,"")),Caster.toString(arr.get(2,"")),rolesDir); 173 if(len==1) return new CredentialImpl(Caster.toString(arr.get(1,"")),rolesDir); 174 175 return null; 176 } 177 178 @Override 179 public String toString() { 180 return "username:"+username+";password:"+password+";roles:"+roles; 181 } 182 183 }