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