001/* 002 * (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.platform.login.deputy.management; 023 024import java.io.Serializable; 025import java.util.ArrayList; 026import java.util.Calendar; 027import java.util.HashMap; 028import java.util.List; 029import java.util.Map; 030 031import org.nuxeo.ecm.core.api.DataModel; 032import org.nuxeo.ecm.core.api.DocumentModel; 033import org.nuxeo.ecm.core.api.DocumentModelList; 034import org.nuxeo.ecm.core.api.NuxeoException; 035import org.nuxeo.ecm.core.api.impl.DataModelImpl; 036import org.nuxeo.ecm.core.api.impl.DocumentModelImpl; 037import org.nuxeo.ecm.directory.DirectoryException; 038import org.nuxeo.ecm.directory.Session; 039import org.nuxeo.ecm.directory.api.DirectoryService; 040import org.nuxeo.runtime.api.Framework; 041 042public class DeputyManagementStorageService implements DeputyManager { 043 044 private static final String DIR_NAME = "deputies"; 045 046 private static final String DIR_COL_ID = "id"; 047 048 private static final String DIR_COL_USERID = "userid"; 049 050 private static final String DIR_COL_DEPUTY = "deputy"; 051 052 private static final String DIR_COL_VALIDATE_DATE = "validateDate"; 053 054 private static final String DIR_COL_START_VALIDITY = "validityStartDate"; 055 056 private static final String DIR_COL_END_VALIDITY = "validityEndDate"; 057 058 private DirectoryService directoryService; 059 060 private Session dirSession; 061 062 private String directorySchema; 063 064 @Override 065 public String getDeputySchemaName() { 066 return directorySchema; 067 } 068 069 protected void initPersistentService() { 070 if (directoryService == null) { 071 directoryService = Framework.getService(DirectoryService.class); 072 } 073 dirSession = directoryService.open(DIR_NAME); 074 directorySchema = directoryService.getDirectorySchema(DIR_NAME); 075 } 076 077 private void releasePersistenceService() { 078 // for now directory sessions are lost during passivation of the 079 // DirectoryFacade 080 // this can't be tested on the client side 081 // => release directorySession after each call ... 082 083 if (directoryService == null) { 084 dirSession = null; 085 return; 086 } 087 if (dirSession != null) { 088 try { 089 dirSession.close(); 090 } catch (DirectoryException e) { 091 // do nothing 092 } 093 } 094 dirSession = null; 095 } 096 097 public void resetDeputies() { 098 initPersistentService(); 099 100 try { 101 DocumentModelList allEntries = dirSession.getEntries(); 102 List<String> ids = new ArrayList<String>(); 103 for (DocumentModel entry : allEntries) { 104 ids.add(entry.getId()); 105 } 106 for (String id : ids) { 107 dirSession.deleteEntry(id); 108 } 109 110 } finally { 111 releasePersistenceService(); 112 } 113 114 } 115 116 @Override 117 public List<String> getPossiblesAlternateLogins(String userName) { 118 List<String> users = new ArrayList<String>(); 119 List<String> outdatedEntriesId = new ArrayList<String>(); 120 121 initPersistentService(); 122 123 try { 124 Map<String, Serializable> filter = new HashMap<String, Serializable>(); 125 filter.put(DIR_COL_DEPUTY, userName); 126 127 DocumentModelList entries = null; 128 129 entries = dirSession.query(filter); 130 131 long currentTime = System.currentTimeMillis(); 132 for (DocumentModel entry : entries) { 133 134 String alternateId = (String) entry.getProperty(directorySchema, DIR_COL_USERID); 135 Calendar startDate = (Calendar) entry.getProperty(directorySchema, DIR_COL_START_VALIDITY); 136 Calendar endDate = (Calendar) entry.getProperty(directorySchema, DIR_COL_END_VALIDITY); 137 138 boolean validateDate = (Boolean) entry.getProperty(directorySchema, DIR_COL_VALIDATE_DATE); 139 boolean valid = true; 140 if (validateDate && (startDate != null) && (startDate.getTimeInMillis() > currentTime)) { 141 valid = false; 142 } 143 if (validateDate && (endDate != null) && (endDate.getTimeInMillis() < currentTime)) { 144 valid = false; 145 } 146 147 if (valid) { 148 users.add(alternateId); 149 } else { 150 outdatedEntriesId.add(entry.getId()); 151 } 152 } 153 154 for (String outDatedId : outdatedEntriesId) { 155 dirSession.deleteEntry(outDatedId); 156 } 157 158 return users; 159 } finally { 160 161 releasePersistenceService(); 162 } 163 } 164 165 @Override 166 public List<String> getAvalaibleDeputyIds(String userName) { 167 List<String> deputies = new ArrayList<String>(); 168 169 for (DocumentModel entry : getAvalaibleMandates(userName)) { 170 String alternateId = (String) entry.getProperty(directorySchema, DIR_COL_DEPUTY); 171 deputies.add(alternateId); 172 } 173 174 return deputies; 175 } 176 177 @Override 178 public List<DocumentModel> getAvalaibleMandates(String userName) { 179 List<DocumentModel> deputies = new ArrayList<DocumentModel>(); 180 181 initPersistentService(); 182 183 try { 184 Map<String, Serializable> filter = new HashMap<String, Serializable>(); 185 filter.put(DIR_COL_USERID, userName); 186 return dirSession.query(filter); 187 } catch (DirectoryException e) { 188 return deputies; 189 } finally { 190 releasePersistenceService(); 191 } 192 193 } 194 195 @Override 196 public DocumentModel newMandate(String username, String deputy) { 197 198 initPersistentService(); 199 200 try { 201 DocumentModel entry = newEntry(username, deputy); 202 Calendar cal = Calendar.getInstance(); 203 entry.setProperty(directorySchema, DIR_COL_VALIDATE_DATE, new Boolean(false)); 204 entry.setProperty(directorySchema, DIR_COL_START_VALIDITY, cal); 205 entry.setProperty(directorySchema, DIR_COL_END_VALIDITY, cal); 206 return entry; 207 } finally { 208 releasePersistenceService(); 209 } 210 } 211 212 protected DocumentModel newEntry(String username, String deputy) { 213 DataModel data = new DataModelImpl(directorySchema, new HashMap<String, Object>()); 214 DocumentModelImpl entry = new DocumentModelImpl(null, directorySchema, "0", null, null, null, null, 215 new String[] { directorySchema }, null, null, null); 216 entry.addDataModel(data); 217 entry.setProperty(directorySchema, DIR_COL_ID, id(username, deputy)); 218 entry.setProperty(directorySchema, DIR_COL_USERID, username); 219 entry.setProperty(directorySchema, DIR_COL_DEPUTY, deputy); 220 return entry; 221 } 222 223 @Override 224 public DocumentModel newMandate(String username, String deputy, Calendar start, Calendar end) 225 { 226 227 initPersistentService(); 228 229 try { 230 DocumentModel entry = newEntry(username, deputy); 231 entry.setProperty(directorySchema, DIR_COL_VALIDATE_DATE, new Boolean(true)); 232 entry.setProperty(directorySchema, DIR_COL_START_VALIDITY, start); 233 entry.setProperty(directorySchema, DIR_COL_END_VALIDITY, end); 234 return entry; 235 } finally { 236 releasePersistenceService(); 237 } 238 } 239 240 @Override 241 public void addMandate(DocumentModel entry) { 242 243 initPersistentService(); 244 245 try { 246 String id = id(entry); 247 248 if (dirSession.getEntry(id) != null) { 249 // first remove entry 250 dirSession.deleteEntry(id); 251 } 252 253 entry.setProperty(directorySchema, DIR_COL_ID, id); 254 255 dirSession.createEntry(entry); 256 257 } catch (DirectoryException e) { 258 throw new NuxeoException(e); 259 } finally { 260 releasePersistenceService(); 261 } 262 return; 263 } 264 265 @Override 266 public void removeMandate(String username, String deputy) { 267 268 initPersistentService(); 269 270 try { 271 String id = id(username, deputy); 272 dirSession.deleteEntry(id); 273 } finally { 274 releasePersistenceService(); 275 } 276 } 277 278 protected String id(DocumentModel entry) { 279 return id((String) entry.getProperty(directorySchema, "userid"), 280 (String) entry.getProperty(directorySchema, "deputy")); 281 } 282 283 protected String id(String username, String deputy) { 284 return username + ":" + deputy; 285 } 286 287}