001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.upgrade.v6_1_0;
016    
017    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
018    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
019    import com.liferay.portal.kernel.util.ArrayUtil;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.model.GroupConstants;
022    import com.liferay.portal.model.ResourceConstants;
023    import com.liferay.portal.security.permission.ActionKeys;
024    import com.liferay.portal.util.PortalInstances;
025    import com.liferay.portal.util.PortletKeys;
026    import com.liferay.portal.util.PropsValues;
027    
028    import java.sql.Connection;
029    import java.sql.PreparedStatement;
030    import java.sql.ResultSet;
031    
032    import java.util.ArrayList;
033    import java.util.List;
034    
035    /**
036     * @author Juan Fernández
037     */
038    public class UpgradeAdminPortlets extends UpgradeProcess {
039    
040            protected void addResource(long resourceId, long codeId, String primKey)
041                    throws Exception {
042    
043                    Connection con = null;
044                    PreparedStatement ps = null;
045    
046                    try {
047                            con = DataAccess.getConnection();
048    
049                            ps = con.prepareStatement(
050                                    "insert into Resource_ (resourceId, codeId, primKey) values " +
051                                            "(?, ?, ?)");
052    
053                            ps.setLong(1, resourceId);
054                            ps.setLong(2, codeId);
055                            ps.setString(3, primKey);
056    
057                            ps.executeUpdate();
058                    }
059                    finally {
060                            DataAccess.cleanUp(con, ps);
061                    }
062            }
063    
064            protected long[] addResourceIds(long companyId, String name)
065                    throws Exception {
066    
067                    long[] resourceIds = new long[2];
068    
069                    // Company scope
070    
071                    long codeId = increment();
072    
073                    runSQL(
074                            "insert into ResourceCode (codeId, companyId, name, scope) values" +
075                                    " (" + codeId + ", " + companyId + ", '" + name + "', " +
076                                            ResourceConstants.SCOPE_COMPANY + ")");
077    
078                    long resourceId = increment();
079    
080                    addResource(resourceId, codeId, String.valueOf(companyId));
081    
082                    resourceIds[0] = resourceId;
083    
084                    // Individual scope
085    
086                    codeId = increment();
087    
088                    runSQL(
089                            "insert into ResourceCode (codeId, companyId, name, scope) values" +
090                                    " (" + codeId + ", " + companyId + ", '" + name + "', " +
091                                            ResourceConstants.SCOPE_INDIVIDUAL + ")");
092    
093                    resourceId = increment();
094    
095                    long controlPanelGroupId = getControlPanelGroupId();
096    
097                    addResource(resourceId, codeId, String.valueOf(controlPanelGroupId));
098    
099                    resourceIds[1] = resourceId;
100    
101                    return resourceIds;
102            }
103    
104            protected void addResourcePermission(
105                            long resourcePermissionId, long companyId, String name, long scope,
106                            String primKey, long roleId, long actionIds)
107                    throws Exception {
108    
109                    Connection con = null;
110                    PreparedStatement ps = null;
111    
112                    try {
113                            con = DataAccess.getConnection();
114    
115                            ps = con.prepareStatement(
116                                    "insert into ResourcePermission (resourcePermissionId, " +
117                                            "companyId, name, scope, primKey, roleId, actionIds) " +
118                                                    "values (?, ?, ?, ?, ?, ?, ?)");
119    
120                            ps.setLong(1, resourcePermissionId);
121                            ps.setLong(2, companyId);
122                            ps.setString(3, name);
123                            ps.setLong(4, scope);
124                            ps.setString(5, primKey);
125                            ps.setLong(6, roleId);
126                            ps.setLong(7, actionIds);
127    
128                            ps.executeUpdate();
129                    }
130                    finally {
131                            DataAccess.cleanUp(con, ps);
132                    }
133            }
134    
135            @Override
136            protected void doUpgrade() throws Exception {
137                    if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
138                            updateAccessInControlPanelPermission_5(
139                                    PortletKeys.BLOGS, PortletKeys.BLOGS_ADMIN);
140    
141                            updateAccessInControlPanelPermission_5(
142                                    PortletKeys.MESSAGE_BOARDS, PortletKeys.MESSAGE_BOARDS_ADMIN);
143                    }
144                    else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
145                            updateAccessInControlPanelPermission_6(
146                                    PortletKeys.BLOGS, PortletKeys.BLOGS_ADMIN);
147    
148                            updateAccessInControlPanelPermission_6(
149                                    PortletKeys.MESSAGE_BOARDS, PortletKeys.MESSAGE_BOARDS_ADMIN);
150                    }
151            }
152    
153            protected long getBitwiseValue(String name, String actionId)
154                    throws Exception {
155    
156                    Connection con = null;
157                    PreparedStatement ps = null;
158                    ResultSet rs = null;
159    
160                    try {
161                            con = DataAccess.getConnection();
162    
163                            ps = con.prepareStatement(
164                                    "select bitwiseValue from ResourceAction where name = ? and " +
165                                            "actionId = ?");
166    
167                            ps.setString(1, name);
168                            ps.setString(2, actionId);
169    
170                            rs = ps.executeQuery();
171    
172                            if (rs.next()) {
173                                    return rs.getLong("bitwiseValue");
174                            }
175    
176                            return 0;
177                    }
178                    finally {
179                            DataAccess.cleanUp(con, ps, rs);
180                    }
181            }
182    
183            protected long getControlPanelGroupId() throws Exception {
184                    Connection con = null;
185                    PreparedStatement ps = null;
186                    ResultSet rs = null;
187    
188                    try {
189                            con = DataAccess.getConnection();
190    
191                            ps = con.prepareStatement(
192                                    "select groupId from Group_ where name = '" +
193                                            GroupConstants.CONTROL_PANEL + "'");
194    
195                            rs = ps.executeQuery();
196    
197                            if (rs.next()) {
198                                    return rs.getLong("groupId");
199                            }
200    
201                            return 0;
202                    }
203                    finally {
204                            DataAccess.cleanUp(con, ps, rs);
205                    }
206            }
207    
208            protected long[] getOldResourceIds(String name) throws Exception {
209                    Connection con = null;
210                    PreparedStatement ps = null;
211                    ResultSet rs = null;
212    
213                    try {
214                            con = DataAccess.getConnection();
215    
216                            StringBundler sb = new StringBundler(8);
217    
218                            sb.append("select Permission_.resourceId from Permission_ ");
219                            sb.append("inner join Resource_ on Permission_.resourceId = ");
220                            sb.append("Resource_.resourceId and Permission_.actionId = ");
221                            sb.append("'ACCESS_IN_CONTROL_PANEL' inner join ResourceCode on ");
222                            sb.append("ResourceCode.codeId = Resource_.codeId and ");
223                            sb.append("ResourceCode.name = '");
224                            sb.append(name);
225                            sb.append("'");
226    
227                            String sql = sb.toString();
228    
229                            ps = con.prepareStatement(sql);
230    
231                            rs = ps.executeQuery();
232    
233                            List<Long> resourceIds = new ArrayList<Long>();
234    
235                            while (rs.next()) {
236                                    long resourceId = rs.getLong("resourceId");
237    
238                                    resourceIds.add(resourceId);
239                            }
240    
241                            return ArrayUtil.toArray(
242                                    resourceIds.toArray(new Long[resourceIds.size()]));
243                    }
244                    finally {
245                            DataAccess.cleanUp(con, ps, rs);
246                    }
247            }
248    
249            protected void updateAccessInControlPanelPermission_5(
250                            String portletFrom, String portletTo)
251                    throws Exception {
252    
253                    long[] companyIds = PortalInstances.getCompanyIdsBySQL();
254    
255                    if (companyIds.length == 0) {
256                            return;
257                    }
258    
259                    for (long companyId : companyIds) {
260                            long[] newResourceIds = addResourceIds(companyId, portletTo);
261                            long[] oldResourceIds = getOldResourceIds(portletFrom);
262    
263                            updatePermission(oldResourceIds, newResourceIds);
264                    }
265            }
266    
267            protected void updateAccessInControlPanelPermission_6(
268                            String portletFrom, String portletTo)
269                    throws Exception {
270    
271                    long bitwiseValue = getBitwiseValue(
272                            portletFrom, ActionKeys.ACCESS_IN_CONTROL_PANEL);
273    
274                    Connection con = null;
275                    PreparedStatement ps = null;
276                    ResultSet rs = null;
277    
278                    try {
279                            con = DataAccess.getConnection();
280    
281                            ps = con.prepareStatement(
282                                    "select * from ResourcePermission where name = ?");
283    
284                            ps.setString(1, portletFrom);
285    
286                            rs = ps.executeQuery();
287    
288                            while (rs.next()) {
289                                    long resourcePermissionId = rs.getLong("resourcePermissionId");
290                                    long actionIds = rs.getLong("actionIds");
291    
292                                    if ((actionIds & bitwiseValue) != 0) {
293                                            actionIds = actionIds & (~bitwiseValue);
294    
295                                            runSQL(
296                                                    "update ResourcePermission set actionIds = " +
297                                                            actionIds + " where resourcePermissionId = " +
298                                                                    resourcePermissionId);
299    
300                                            resourcePermissionId = increment();
301    
302                                            long companyId = rs.getLong("companyId");
303                                            long scope = rs.getLong("scope");
304                                            String primKey = rs.getString("primKey");
305                                            long roleId = rs.getLong("roleId");
306    
307                                            actionIds = rs.getLong("actionIds");
308    
309                                            actionIds |= bitwiseValue;
310    
311                                            addResourcePermission(
312                                                    resourcePermissionId, companyId, portletTo, scope,
313                                                    primKey, roleId, actionIds);
314                                    }
315                            }
316                    }
317                    finally {
318                            DataAccess.cleanUp(con, ps, rs);
319                    }
320            }
321    
322            protected void updatePermission(
323                            long[] oldResourceIds, long[] newResourceIds)
324                    throws Exception {
325    
326                    for (int i = 0; i < newResourceIds.length; i++) {
327                            try {
328                                    long newResourceId = newResourceIds[i];
329                                    long oldResourceId = oldResourceIds[i];
330    
331                                    runSQL(
332                                            "update Permission_ set resourceId = " + newResourceId +
333                                                    " where actionId = 'ACCESS_IN_CONTROL_PANEL' and " +
334                                                            "resourceId = " + oldResourceId);
335                            }
336                            catch (ArrayIndexOutOfBoundsException aioobe) {
337                                    return;
338                            }
339                    }
340            }
341    
342    }