001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.commons.io.res.type.s3;
020
021import java.io.IOException;
022import java.util.ArrayList;
023import java.util.Iterator;
024import java.util.List;
025
026import lucee.commons.lang.Md5;
027import lucee.commons.lang.StringUtil;
028import lucee.runtime.exp.PageException;
029import lucee.runtime.functions.s3.StoreGetACL;
030import lucee.runtime.op.Caster;
031import lucee.runtime.type.Array;
032import lucee.runtime.type.Struct;
033import lucee.runtime.type.util.KeyConstants;
034
035public class AccessControl {
036
037        public static final short TYPE_GROUP=1;
038        public static final short TYPE_EMAIL=2;
039        public static final short TYPE_CANONICAL_USER=4;
040        
041        private String id;
042        private String displayName;
043        private String permission;
044        private String uri;
045        private short type;
046        private String email;
047        
048        /**
049         * @return the type
050         */
051        public short getType() {
052                return type;
053        }
054
055        /**
056         * @param type the type to set
057         */
058        public void setType(short type) {
059                this.type = type;
060        }
061
062        /**
063         * @return the id
064         */
065        public String getId() {
066                return id;
067        }
068        /**
069         * @param id the id to set
070         */
071        public void setId(String id) {
072                this.id = id;
073        }
074        /**
075         * @return the displayName
076         */
077        public String getDisplayName() {
078                return displayName;
079        }
080        /**
081         * @param displayName the displayName to set
082         */
083        public void setDisplayName(String displayName) {
084                this.displayName = displayName;
085        }
086        /**
087         * @return the permission
088         */
089        public String getPermission() {
090                return permission;
091        }
092        
093        public void setPermission(String permission) {
094                this.permission=permission;
095        }
096        
097        /**
098         * @return the uri
099         */
100        public String getUri() {
101                return uri;
102        }
103        /**
104         * @param uri the uri to set
105         */
106        public void setUri(String uri) {
107                this.uri = uri;
108        }
109        
110
111        
112        /**
113         * @return the email
114         */
115        public String getEmail() {
116                return email;
117        }
118
119        /**
120         * @param email the email to set
121         */
122        public void setEmail(String email) {
123                this.email = email;
124        }
125        
126
127        @Override
128        public String toString(){
129                return "displayName:"+displayName+";email:"+email+";id:"+id+";permission:"+permission+";type:"+type+";uri:"+uri;
130        }
131
132        public String hash() {
133                try {
134                        return Md5.getDigestAsString(toString());
135                } catch (IOException e) {
136                        return null;
137                }
138        }
139        @Override
140        public int hashCode() {
141                return hash().hashCode();
142        }
143        
144        
145        
146        
147        
148        
149        
150
151        public static List<AccessControl> toAccessControlList(Object objACL) throws S3Exception, PageException{
152                Array arr = Caster.toArray(objACL,null);
153                if(arr==null)
154                        throw new S3Exception("ACL Object must be a Array of Structs");
155                
156                Struct sct;
157                Iterator<Object> it = arr.valueIterator();
158                List<AccessControl> acl=new ArrayList<AccessControl>();
159                while(it.hasNext()){
160                        sct=Caster.toStruct(it.next(), null);
161                        if(sct==null)
162                                throw new S3Exception("ACL Object must be a Array of Structs");
163                        acl.add(toAccessControl(sct));
164                }
165                return acl;
166        }
167        
168        
169        public static AccessControl toAccessControl(Struct sct) throws S3Exception, PageException{
170                AccessControl ac=new AccessControl();
171        ac.setPermission(AccessControl.toPermission(sct.get(StoreGetACL.PERMISSION,null)));
172        
173        
174        
175        // Email
176        String email = Caster.toString(sct.get(KeyConstants._email,null),null);
177        if(!StringUtil.isEmpty(email)){
178                ac.setType(AccessControl.TYPE_EMAIL);
179                ac.setEmail(email);
180                return ac;
181        }
182        
183        // Group
184        String uri=AccessControl.groupToURI(sct.get(KeyConstants._group,null));
185        if(!StringUtil.isEmpty(uri)) {
186                ac.setType(AccessControl.TYPE_GROUP);
187                ac.setUri(uri);
188                return ac;
189        }
190        
191        // Canonical
192        String id = Caster.toString(sct.get(KeyConstants._id),null);
193        String displayName = Caster.toString(sct.get(StoreGetACL.DISPLAY_NAME),null);
194        if(StringUtil.isEmpty(id)) 
195                throw new S3Exception("missing id for Canonical User defintion");
196        
197        ac.setType(AccessControl.TYPE_CANONICAL_USER);
198        ac.setId(id);
199        ac.setDisplayName(displayName);
200        
201        return ac;
202        }
203        
204        
205        public static String toPermission(Object oPermission) throws S3Exception {
206                String permission=Caster.toString(oPermission,null);
207                if(StringUtil.isEmpty(permission,true))
208                        throw new S3Exception("missing permission definition");
209                
210                permission=permission.toUpperCase().trim();
211                permission=AccessControl.removeWordDelimter(permission);
212                
213                if("FULLCONTROL".equals(permission))
214                        return "FULL_CONTROL";
215                else if("WRITEACP".equals(permission))
216                        return "WRITE_ACP";
217                else if("READACP".equals(permission))
218                        return "READ_ACP";
219                else if("WRITE".equals(permission))
220                        return "WRITE";
221                else if("READ".equals(permission))
222                        return "READ";
223                else
224                        throw new S3Exception("invalid permission definition ["+permission+"], valid permissions are [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]");
225        }
226        
227
228        public static String groupToURI(Object oGroup) throws S3Exception {
229                if(!StringUtil.isEmpty(oGroup)) {
230                        String group=Caster.toString(oGroup,null);
231                        if(group==null)
232                                throw new S3Exception("invalid object type for group definition");
233            
234                        group=removeWordDelimter(group);
235                        if("all".equalsIgnoreCase(group))
236                return "http://acs.amazonaws.com/groups/global/AllUsers";
237                        if("authenticated".equalsIgnoreCase(group) || "AuthenticatedUser".equalsIgnoreCase(group) || "AuthenticatedUsers".equalsIgnoreCase(group))
238                return "http://acs.amazonaws.com/groups/global/AuthenticatedUsers";
239                        if("logdelivery".equalsIgnoreCase(group))
240                return "http://acs.amazonaws.com/groups/s3/LogDelivery";
241                        throw new S3Exception("invalid group definition ["+group+"], valid group defintions are are [all,authenticated,log_delivery]");
242                
243        }
244                return null;
245        }
246        
247
248        public static String toType(short type) throws S3Exception {
249                String rtn = toType(type, null);
250                if(rtn!=null) return rtn;
251                throw new S3Exception("invalid type defintion");
252        }
253        
254        public static String toType(short type, String defaultValue) {
255                switch(type){
256                case TYPE_EMAIL: return "AmazonCustomerByEmail";
257                case TYPE_GROUP: return "Group";
258                case TYPE_CANONICAL_USER: return "CanonicalUser";
259                }
260                return defaultValue;
261        }
262
263        public static short toType(String type) throws S3Exception {
264                short rtn = toType(type, (short)-1);
265                if(rtn!=-1) return rtn;
266                
267                throw new S3Exception("invalid type defintion ["+type+"], valid types are [Email,Group,CanonicalUser]");
268        }
269        
270        public static short toType(String type, short defaultValue) {
271                type=removeWordDelimter(type);
272                if("Email".equalsIgnoreCase(type)) return TYPE_EMAIL;
273                if("AmazonCustomerByEmail".equalsIgnoreCase(type)) return TYPE_EMAIL;
274                if("CanonicalUser".equalsIgnoreCase(type)) return TYPE_CANONICAL_USER;
275                if("Group".equalsIgnoreCase(type)) return TYPE_GROUP;
276                
277                return defaultValue;
278        }
279        
280
281        
282        private static String removeWordDelimter(String str) {
283                str=StringUtil.replace(str,"_", "", false);
284                str=StringUtil.replace(str,"-", "", false);
285                str=StringUtil.replace(str," ", "", false);
286                return str;
287        }
288}