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    }