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    }