001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.verify;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.ListUtil;
020    import com.liferay.portal.kernel.util.PropsKeys;
021    import com.liferay.portal.kernel.util.StreamUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.StringUtil;
024    import com.liferay.portal.kernel.util.SystemProperties;
025    import com.liferay.portal.kernel.util.UnicodeProperties;
026    import com.liferay.portal.security.ldap.LDAPSettingsUtil;
027    import com.liferay.portal.service.CompanyLocalServiceUtil;
028    import com.liferay.portal.util.PortalInstances;
029    import com.liferay.portal.util.PrefsPropsUtil;
030    import com.liferay.portal.util.PropsUtil;
031    import com.liferay.portlet.documentlibrary.store.StoreFactory;
032    
033    import java.io.File;
034    import java.io.FileInputStream;
035    import java.io.FileNotFoundException;
036    import java.io.IOException;
037    import java.io.InputStream;
038    
039    import java.util.List;
040    import java.util.Properties;
041    
042    /**
043     * @author Brian Wing Shun Chan
044     */
045    public class VerifyProperties extends VerifyProcess {
046    
047            @Override
048            protected void doVerify() throws Exception {
049    
050                    // system.properties
051    
052                    for (String[] keys : _MIGRATED_SYSTEM_KEYS) {
053                            String oldKey = keys[0];
054                            String newKey = keys[1];
055    
056                            verifyMigratedSystemProperty(oldKey, newKey);
057                    }
058    
059                    for (String[] keys : _RENAMED_SYSTEM_KEYS) {
060                            String oldKey = keys[0];
061                            String newKey = keys[1];
062    
063                            verifyRenamedSystemProperty(oldKey, newKey);
064                    }
065    
066                    for (String key : _OBSOLETE_SYSTEM_KEYS) {
067                            verifyObsoleteSystemProperty(key);
068                    }
069    
070                    // portal.properties
071    
072                    Properties portalProperties = loadPortalProperties();
073    
074                    for (String[] keys : _MIGRATED_PORTAL_KEYS) {
075                            String oldKey = keys[0];
076                            String newKey = keys[1];
077    
078                            verifyMigratedPortalProperty(portalProperties, oldKey, newKey);
079                    }
080    
081                    for (String[] keys : _RENAMED_PORTAL_KEYS) {
082                            String oldKey = keys[0];
083                            String newKey = keys[1];
084    
085                            verifyRenamedPortalProperty(portalProperties, oldKey, newKey);
086                    }
087    
088                    for (String key : _OBSOLETE_PORTAL_KEYS) {
089                            verifyObsoletePortalProperty(portalProperties, key);
090                    }
091    
092                    // Document library
093    
094                    StoreFactory.checkProperties();
095    
096                    // LDAP
097    
098                    verifyLDAPProperties();
099            }
100    
101            protected InputStream getPropertiesResourceAsStream(String resourceName)
102                    throws FileNotFoundException {
103    
104                    File propertyFile = new File(resourceName);
105    
106                    if (propertyFile.exists()) {
107                            return new FileInputStream(propertyFile);
108                    }
109    
110                    ClassLoader classLoader = VerifyProperties.class.getClassLoader();
111    
112                    return classLoader.getResourceAsStream(resourceName);
113            }
114    
115            protected Properties loadPortalProperties() {
116                    Properties properties = new Properties();
117    
118                    List<String> propertiesResourceNames = ListUtil.fromArray(
119                            PropsUtil.getArray("include-and-override"));
120    
121                    propertiesResourceNames.add(0, "portal.properties");
122    
123                    for (String propertyResourceName : propertiesResourceNames) {
124                            InputStream inputStream = null;
125    
126                            try {
127                                    inputStream = getPropertiesResourceAsStream(
128                                            propertyResourceName);
129    
130                                    if (inputStream != null) {
131                                            properties.load(inputStream);
132                                    }
133                            }
134                            catch (IOException ioe) {
135                                    _log.error(
136                                            "Unable to load property " + propertyResourceName, ioe);
137                            }
138                            finally {
139                                    StreamUtil.cleanUp(inputStream);
140                            }
141                    }
142    
143                    return properties;
144            }
145    
146            protected void verifyLDAPProperties() throws Exception {
147                    long[] companyIds = PortalInstances.getCompanyIdsBySQL();
148    
149                    for (long companyId : companyIds) {
150                            UnicodeProperties properties = new UnicodeProperties();
151    
152                            long[] ldapServerIds = StringUtil.split(
153                                    PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
154    
155                            for (long ldapServerId : ldapServerIds) {
156                                    String postfix = LDAPSettingsUtil.getPropertyPostfix(
157                                            ldapServerId);
158    
159                                    for (String key : _LDAP_KEYS) {
160                                            String value = PrefsPropsUtil.getString(
161                                                    companyId, key + postfix, null);
162    
163                                            if (value == null) {
164                                                    properties.put(key + postfix, StringPool.BLANK);
165                                            }
166                                    }
167                            }
168    
169                            if (!properties.isEmpty()) {
170                                    CompanyLocalServiceUtil.updatePreferences(
171                                            companyId, properties);
172                            }
173                    }
174            }
175    
176            protected void verifyMigratedPortalProperty(
177                            Properties portalProperties, String oldKey, String newKey)
178                    throws Exception {
179    
180                    if (portalProperties.containsKey(oldKey)) {
181                            _log.error(
182                                    "Portal property \"" + oldKey +
183                                            "\" was migrated to the system property \"" + newKey +
184                                                    "\"");
185                    }
186            }
187    
188            protected void verifyMigratedSystemProperty(String oldKey, String newKey)
189                    throws Exception {
190    
191                    String value = SystemProperties.get(oldKey);
192    
193                    if (value != null) {
194                            _log.error(
195                                    "System property \"" + oldKey +
196                                            "\" was migrated to the portal property \"" + newKey +
197                                                    "\"");
198                    }
199            }
200    
201            protected void verifyObsoletePortalProperty(
202                            Properties portalProperties, String key)
203                    throws Exception {
204    
205                    if (portalProperties.containsKey(key)) {
206                            _log.error("Portal property \"" + key + "\" is obsolete");
207                    }
208            }
209    
210            protected void verifyObsoleteSystemProperty(String key) throws Exception {
211                    String value = SystemProperties.get(key);
212    
213                    if (value != null) {
214                            _log.error("System property \"" + key + "\" is obsolete");
215                    }
216            }
217    
218            protected void verifyRenamedPortalProperty(
219                            Properties portalProperties, String oldKey, String newKey)
220                    throws Exception {
221    
222                    if (portalProperties.containsKey(oldKey)) {
223                            _log.error(
224                                    "Portal property \"" + oldKey + "\" was renamed to \"" +
225                                            newKey + "\"");
226                    }
227            }
228    
229            protected void verifyRenamedSystemProperty(String oldKey, String newKey)
230                    throws Exception {
231    
232                    String value = SystemProperties.get(oldKey);
233    
234                    if (value != null) {
235                            _log.error(
236                                    "System property \"" + oldKey + "\" was renamed to \"" +
237                                            newKey + "\"");
238                    }
239            }
240    
241            private static final String[] _LDAP_KEYS = {
242                    PropsKeys.LDAP_CONTACT_CUSTOM_MAPPINGS, PropsKeys.LDAP_CONTACT_MAPPINGS,
243                    PropsKeys.LDAP_USER_CUSTOM_MAPPINGS
244            };
245    
246            private static final String[][] _MIGRATED_PORTAL_KEYS = new String[][] {
247                    new String[] {
248                            "cookie.http.only.names.excludes", "cookie.http.only.names.excludes"
249                    },
250                    new String[] {
251                            "finalize.manager.thread.enabled",
252                            "com.liferay.portal.kernel.memory.FinalizeManager.thread.enabled"
253                    },
254                    new String[] {
255                            "http.header.secure.x.content.type.options",
256                            "http.header.secure.x.content.type.options"
257                    },
258                    new String[] {
259                            "http.header.secure.x.content.type.options.urls.excludes",
260                            "http.header.secure.x.content.type.options.urls.excludes"
261                    },
262                    new String[] {
263                            "http.header.secure.x.frame.options",
264                            "http.header.secure.x.frame.options"
265                    },
266                    new String[] {
267                            "http.header.secure.x.frame.options.255",
268                            "http.header.secure.x.frame.options.255"
269                    },
270                    new String[] {
271                            "http.header.secure.x.xss.protection",
272                            "http.header.secure.x.xss.protection"
273                    }
274            };
275    
276            private static final String[][] _MIGRATED_SYSTEM_KEYS = new String[][] {
277                    new String[] {
278                            "com.liferay.filters.compression.CompressionFilter",
279                            "com.liferay.portal.servlet.filters.gzip.GZipFilter"
280                    },
281                    new String[] {
282                            "com.liferay.filters.strip.StripFilter",
283                            "com.liferay.portal.servlet.filters.strip.StripFilter"
284                    },
285                    new String[] {
286                            "com.liferay.util.Http.max.connections.per.host",
287                            "com.liferay.portal.util.HttpImpl.max.connections.per.host"
288                    },
289                    new String[] {
290                            "com.liferay.util.Http.max.total.connections",
291                            "com.liferay.portal.util.HttpImpl.max.total.connections"
292                    },
293                    new String[] {
294                            "com.liferay.util.Http.proxy.auth.type",
295                            "com.liferay.portal.util.HttpImpl.proxy.auth.type"
296                    },
297                    new String[] {
298                            "com.liferay.util.Http.proxy.ntlm.domain",
299                            "com.liferay.portal.util.HttpImpl.proxy.ntlm.domain"
300                    },
301                    new String[] {
302                            "com.liferay.util.Http.proxy.ntlm.host",
303                            "com.liferay.portal.util.HttpImpl.proxy.ntlm.host"
304                    },
305                    new String[] {
306                            "com.liferay.util.Http.proxy.password",
307                            "com.liferay.portal.util.HttpImpl.proxy.password"
308                    },
309                    new String[] {
310                            "com.liferay.util.Http.proxy.username",
311                            "com.liferay.portal.util.HttpImpl.proxy.username"
312                    },
313                    new String[] {
314                            "com.liferay.util.Http.timeout",
315                            "com.liferay.portal.util.HttpImpl.timeout"
316                    },
317                    new String[] {
318                            "com.liferay.util.format.PhoneNumberFormat",
319                            "phone.number.format.impl"
320                    },
321                    new String[] {
322                            "com.liferay.util.servlet.UploadServletRequest.max.size",
323                            "com.liferay.portal.upload.UploadServletRequestImpl.max.size"
324                    },
325                    new String[] {
326                            "com.liferay.util.servlet.UploadServletRequest.temp.dir",
327                            "com.liferay.portal.upload.UploadServletRequestImpl.temp.dir"
328                    },
329                    new String[] {
330                            "com.liferay.util.servlet.fileupload.LiferayFileItem." +
331                                    "threshold.size",
332                            "com.liferay.portal.upload.LiferayFileItem.threshold.size"
333                    },
334                    new String[] {
335                            "com.liferay.util.servlet.fileupload.LiferayInputStream." +
336                                    "threshold.size",
337                            "com.liferay.portal.upload.LiferayInputStream.threshold.size"
338                    }
339            };
340    
341            private static final String[] _OBSOLETE_PORTAL_KEYS = new String[] {
342                    "asset.entry.increment.view.counter.enabled", "auth.max.failures.limit",
343                    "buffered.increment.parallel.queue.size",
344                    "buffered.increment.serial.queue.size", "cas.validate.url",
345                    "cluster.executor.heartbeat.interval",
346                    "com.liferay.filters.doubleclick.DoubleClickFilter",
347                    "com.liferay.portal.servlet.filters.doubleclick.DoubleClickFilter",
348                    "commons.pool.enabled", "dl.file.entry.read.count.enabled",
349                    "dynamic.data.lists.template.language.parser[ftl]",
350                    "dynamic.data.lists.template.language.parser[vm]",
351                    "dynamic.data.lists.template.language.parser[xsl]",
352                    "dynamic.data.mapping.template.language.types",
353                    "ehcache.statistics.enabled", "jbi.workflow.url",
354                    "journal.template.language.parser[css]",
355                    "journal.template.language.parser[ftl]",
356                    "journal.template.language.parser[vm]",
357                    "journal.template.language.parser[xsl]",
358                    "journal.template.language.types", "lucene.analyzer",
359                    "lucene.store.jdbc.auto.clean.up",
360                    "lucene.store.jdbc.auto.clean.up.enabled",
361                    "lucene.store.jdbc.auto.clean.up.interval",
362                    "lucene.store.jdbc.dialect.db2", "lucene.store.jdbc.dialect.derby",
363                    "lucene.store.jdbc.dialect.hsqldb", "lucene.store.jdbc.dialect.jtds",
364                    "lucene.store.jdbc.dialect.microsoft",
365                    "lucene.store.jdbc.dialect.mysql", "lucene.store.jdbc.dialect.oracle",
366                    "lucene.store.jdbc.dialect.postgresql",
367                    "index.dump.process.documents.enabled",
368                    "memory.cluster.scheduler.lock.cache.enabled",
369                    "message.boards.thread.locking.enabled", "portal.ctx",
370                    "portal.security.manager.enable", "permissions.user.check.algorithm",
371                    "scheduler.classes", "schema.run.minimal", "shard.available.names",
372                    "table.mapper.cacheless.mapping.table.names",
373                    "velocity.engine.resource.manager",
374                    "velocity.engine.resource.manager.cache.enabled",
375                    "webdav.storage.class", "webdav.storage.show.edit.url",
376                    "webdav.storage.show.view.url", "webdav.storage.tokens", "xss.allow"
377            };
378    
379            private static final String[] _OBSOLETE_SYSTEM_KEYS = new String[] {
380                    "com.liferay.util.Http.proxy.host", "com.liferay.util.Http.proxy.port",
381                    "com.liferay.util.XSSUtil.regexp.pattern"
382            };
383    
384            private static final String[][] _RENAMED_PORTAL_KEYS = new String[][] {
385                    new String[] {
386                            "amazon.license.0", "amazon.access.key.id"
387                    },
388                    new String[] {
389                            "amazon.license.1", "amazon.access.key.id"
390                    },
391                    new String[] {
392                            "amazon.license.2", "amazon.access.key.id"
393                    },
394                    new String[] {
395                            "amazon.license.3", "amazon.access.key.id"
396                    },
397                    new String[] {
398                            "cdn.host", "cdn.host.http"
399                    },
400                    new String[] {
401                            "com.liferay.portal.servlet.filters.compression.CompressionFilter",
402                            "com.liferay.portal.servlet.filters.gzip.GZipFilter"
403                    },
404                    new String[] {
405                            "default.guest.friendly.url",
406                            "default.guest.public.layout.friendly.url"
407                    },
408                    new String[] {
409                            "default.guest.layout.column", "default.guest.public.layout.column"
410                    },
411                    new String[] {
412                            "default.guest.layout.name", "default.guest.public.layout.name"
413                    },
414                    new String[] {
415                            "default.guest.layout.template.id",
416                            "default.guest.public.layout.template.id"
417                    },
418                    new String[] {
419                            "default.user.layout.column", "default.user.public.layout.column"
420                    },
421                    new String[] {
422                            "default.user.layout.name", "default.user.public.layout.name"
423                    },
424                    new String[] {
425                            "default.user.layout.template.id",
426                            "default.user.public.layout.template.id"
427                    },
428                    new String[] {
429                            "default.user.private.layout.lar",
430                            "default.user.private.layouts.lar"
431                    },
432                    new String[] {
433                            "default.user.public.layout.lar", "default.user.public.layouts.lar"
434                    },
435                    new String[] {
436                            "dl.hook.cmis.credentials.password",
437                            "dl.store.cmis.credentials.password"
438                    },
439                    new String[] {
440                            "dl.hook.cmis.credentials.username",
441                            "dl.store.cmis.credentials.username"
442                    },
443                    new String[] {
444                            "dl.hook.cmis.repository.url", "dl.store.cmis.repository.url"
445                    },
446                    new String[] {
447                            "dl.hook.cmis.system.root.dir", "dl.store.cmis.system.root.dir"
448                    },
449                    new String[] {
450                            "dl.hook.file.system.root.dir", "dl.store.file.system.root.dir"
451                    },
452                    new String[] {
453                            "dl.hook.impl", "dl.store.impl"
454                    },
455                    new String[] {
456                            "dl.hook.jcr.fetch.delay", "dl.store.jcr.fetch.delay"
457                    },
458                    new String[] {
459                            "dl.hook.jcr.fetch.max.failures", "dl.store.jcr.fetch.max.failures"
460                    },
461                    new String[] {
462                            "dl.hook.jcr.move.version.labels",
463                            "dl.store.jcr.move.version.labels"
464                    },
465                    new String[] {
466                            "dl.hook.s3.access.key", "dl.store.s3.access.key"
467                    },
468                    new String[] {
469                            "dl.hook.s3.bucket.name", "dl.store.s3.bucket.name"
470                    },
471                    new String[] {
472                            "dl.hook.s3.secret.key", "dl.store.s3.secret.key"
473                    },
474                    new String[] {
475                            "editor.wysiwyg.portal-web.docroot.html.portlet.calendar." +
476                                    "edit_configuration.jsp",
477                            "editor.wysiwyg.portal-web.docroot.html.portlet.calendar." +
478                                    "configuration.jsp"
479                    },
480                    new String[] {
481                            "editor.wysiwyg.portal-web.docroot.html.portlet.invitation." +
482                                    "edit_configuration.jsp",
483                            "editor.wysiwyg.portal-web.docroot.html.portlet.invitation." +
484                                    "configuration.jsp"
485                    },
486                    new String[] {
487                            "editor.wysiwyg.portal-web.docroot.html.portlet.journal." +
488                                    "edit_configuration.jsp",
489                            "editor.wysiwyg.portal-web.docroot.html.portlet.journal." +
490                                    "configuration.jsp"
491                    },
492                    new String[] {
493                            "editor.wysiwyg.portal-web.docroot.html.portlet.message_boards." +
494                                    "edit_configuration.jsp",
495                            "editor.wysiwyg.portal-web.docroot.html.portlet.message_boards." +
496                                    "configuration.jsp"
497                    },
498                    new String[] {
499                            "editor.wysiwyg.portal-web.docroot.html.portlet.shopping." +
500                                    "edit_configuration.jsp",
501                            "editor.wysiwyg.portal-web.docroot.html.portlet.shopping." +
502                                    "configuration.jsp"
503                    },
504                    new String[] {
505                            "field.editable.com.liferay.portal.model.User.emailAddress",
506                            "field.editable.user.types"
507                    },
508                    new String[] {
509                            "field.editable.com.liferay.portal.model.User.screenName",
510                            "field.editable.user.types"
511                    },
512                    new String[] {
513                            "journal.error.template.freemarker", "journal.error.template[ftl]"
514                    },
515                    new String[] {
516                            "journal.error.template.velocity", "journal.error.template[vm]"
517                    },
518                    new String[] {
519                            "journal.error.template.xsl", "journal.error.template[xsl]"
520                    },
521                    new String[] {
522                            "journal.template.freemarker.restricted.variables",
523                            "freemarker.engine.restricted.variables"
524                    },
525                    new String[] {
526                            "journal.template.velocity.restricted.variables",
527                            "velocity.engine.restricted.variables"
528                    },
529                    new String[] {
530                            "passwords.passwordpolicytoolkit.charset.lowercase",
531                            "passwords.passwordpolicytoolkit.validator.charset.lowercase"
532                    },
533                    new String[] {
534                            "passwords.passwordpolicytoolkit.charset.numbers",
535                            "passwords.passwordpolicytoolkit.validator.charset.numbers"
536                    },
537                    new String[] {
538                            "passwords.passwordpolicytoolkit.charset.symbols",
539                            "passwords.passwordpolicytoolkit.validator.charset.symbols"
540                    },
541                    new String[] {
542                            "passwords.passwordpolicytoolkit.charset.uppercase",
543                            "passwords.passwordpolicytoolkit.validator.charset.uppercase"
544                    },
545                    new String[] {
546                            "referer.url.domains.allowed", "redirect.url.domains.allowed"
547                    },
548                    new String[] {
549                            "referer.url.ips.allowed", "redirect.url.ips.allowed"
550                    },
551                    new String[] {
552                            "referer.url.security.mode", "redirect.url.security.mode"
553                    },
554                    new String[] {
555                            "tags.asset.increment.view.counter.enabled",
556                            "asset.entry.increment.view.counter.enabled"
557                    }
558            };
559    
560            private static final String[][] _RENAMED_SYSTEM_KEYS = new String[][] {
561                    new String[] {
562                            "com.liferay.portal.kernel.util.StringBundler.unsafe.create." +
563                                    "threshold",
564                            "com.liferay.portal.kernel.util.StringBundler.threadlocal.buffer." +
565                                    "limit",
566                    }
567            };
568    
569            private static Log _log = LogFactoryUtil.getLog(VerifyProperties.class);
570    
571    }