001package org.apache.archiva.metadata.model.facets; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.archiva.metadata.model.MetadataFacet; 023 024import java.text.ParseException; 025import java.text.SimpleDateFormat; 026import java.util.Calendar; 027import java.util.Date; 028import java.util.HashMap; 029import java.util.Map; 030import java.util.TimeZone; 031 032/** 033 * AuditEvent 034 * 035 * 036 */ 037public class AuditEvent 038 implements MetadataFacet 039{ 040 public static final String TIMESTAMP_FORMAT = "yyyy/MM/dd/HHmmss.SSS"; 041 042 public static final String CREATE_DIR = "Created Directory"; 043 044 public static final String CREATE_FILE = "Created File"; 045 046 public static final String REMOVE_DIR = "Removed Directory"; 047 048 public static final String REMOVE_FILE = "Removed File"; 049 050 public static final String MODIFY_FILE = "Modified File"; 051 052 public static final String MOVE_FILE = "Moved File"; 053 054 public static final String MOVE_DIRECTORY = "Moved Directory"; 055 056 public static final String COPY_DIRECTORY = "Copied Directory"; 057 058 public static final String COPY_FILE = "Copied File"; 059 060 public static final String UPLOAD_FILE = "Uploaded File"; 061 062 public static final String ADD_LEGACY_PATH = "Added Legacy Artifact Path"; 063 064 public static final String REMOVE_LEGACY_PATH = "Removed Legacy Artifact Path"; 065 066 public static final String PURGE_ARTIFACT = "Purged Artifact"; 067 068 public static final String PURGE_FILE = "Purged Support File"; 069 070 public static final String REMOVE_SCANNED = "Removed in Filesystem"; 071 072 public static final String MERGING_REPOSITORIES = "Merged Artifact"; 073 074 // configuration events 075 076 public static final String ADD_MANAGED_REPO = "Added Managed Repository"; 077 078 public static final String MODIFY_MANAGED_REPO = "Updated Managed Repository"; 079 080 public static final String DELETE_MANAGED_REPO = "Deleted Managed Repository"; 081 082 public static final String ADD_REMOTE_REPO = "Added Remote Repository"; 083 084 public static final String MODIFY_REMOTE_REPO = "Updated Remote Repository"; 085 086 public static final String DELETE_REMOTE_REPO = "Deleted Remote Repository"; 087 088 public static final String ADD_REPO_GROUP = "Added Repository Group"; 089 090 public static final String DELETE_REPO_GROUP = "Deleted Repository Group"; 091 092 public static final String MODIFY_REPO_GROUP = "Modify Repository Group"; 093 094 public static final String ADD_REPO_TO_GROUP = "Added Repository to Group"; 095 096 public static final String DELETE_REPO_FROM_GROUP = "Deleted Repository from Group"; 097 098 public static final String ENABLE_REPO_CONSUMER = "Enabled Content Consumer"; 099 100 public static final String DISABLE_REPO_CONSUMER = "Disabled Content Consumer"; 101 102 public static final String ADD_PATTERN = "Added File Type Pattern"; 103 104 public static final String REMOVE_PATTERN = "Removed File Type Pattern"; 105 106 public static final String MERGE_REPO_REMOTE = "Merged Staging Repository Triggered Remotely"; 107 108 public static final String ADD_PROXY_CONNECTOR = "Added Proxy Connector"; 109 110 public static final String DELETE_PROXY_CONNECTOR = "Deleted Proxy Connector"; 111 112 public static final String MODIFY_PROXY_CONNECTOR = "Updated Proxy Connector"; 113 114 public static final String ADD_NETWORK_PROXY = "Added Network Proxy"; 115 116 public static final String DELETE_NETWORK_PROXY = "Deleted Network Proxy"; 117 118 public static final String MODIFY_NETWORK_PROXY = "Updated Network Proxy"; 119 120 private String repositoryId; 121 122 private String userId; 123 124 private String remoteIP; 125 126 // TODO: change to artifact reference? does it ever refer to just a path? 127 128 private String resource; 129 130 private String action; 131 132 private Date timestamp; 133 134 public static final String FACET_ID = "org.apache.archiva.audit"; 135 136 private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" ); 137 138 private static final int TS_LENGTH = TIMESTAMP_FORMAT.length(); 139 140 public AuditEvent() 141 { 142 /* do nothing */ 143 } 144 145 public AuditEvent( String name, String repositoryId ) 146 { 147 String ts = name.substring( 0, TS_LENGTH ); 148 try 149 { 150 timestamp = createNameFormat().parse( ts ); 151 } 152 catch ( ParseException e ) 153 { 154 throw new IllegalArgumentException( "Improperly formatted timestamp for audit log event: " + ts, e); 155 } 156 157 if ( name.length() > TS_LENGTH ) 158 { 159 if ( name.charAt( TS_LENGTH ) != '/' ) 160 { 161 throw new IllegalArgumentException( 162 "Improperly formatted name for audit log event, no / separator between timestamp and resource: " + 163 name ); 164 } 165 } 166 167 this.repositoryId = repositoryId; 168 } 169 170 public AuditEvent( String repoId, String user, String resource, String action ) 171 { 172 this.repositoryId = repoId; 173 this.userId = user; 174 this.resource = resource; 175 this.action = action; 176 this.timestamp = Calendar.getInstance().getTime(); 177 } 178 179 public String getRepositoryId() 180 { 181 return repositoryId; 182 } 183 184 public void setRepositoryId( String repositoryId ) 185 { 186 this.repositoryId = repositoryId; 187 } 188 189 public String getUserId() 190 { 191 return userId; 192 } 193 194 public void setUserId( String userId ) 195 { 196 this.userId = userId; 197 } 198 199 public String getResource() 200 { 201 return resource; 202 } 203 204 public void setResource( String resource ) 205 { 206 this.resource = resource; 207 } 208 209 public String getAction() 210 { 211 return action; 212 } 213 214 public void setAction( String action ) 215 { 216 this.action = action; 217 } 218 219 public String getRemoteIP() 220 { 221 return remoteIP; 222 } 223 224 public void setRemoteIP( String remoteIP ) 225 { 226 this.remoteIP = remoteIP; 227 } 228 229 public Date getTimestamp() 230 { 231 return timestamp; 232 } 233 234 public void setTimestamp( Date timestamp ) 235 { 236 this.timestamp = timestamp; 237 } 238 239 @Override 240 public String getFacetId() 241 { 242 return FACET_ID; 243 } 244 245 @Override 246 public String getName() 247 { 248 // use the hashCode here to make it unique if multiple events occur at a certain timestamp. None of the other 249 // fields is unique on its own 250 return createNameFormat().format( timestamp ) + "/" + Integer.toHexString( hashCode() ); 251 // TODO: a simple incremental counter might be better since it will retain ordering, but then we need to do a 252 // bit of locking... 253 } 254 255 private static SimpleDateFormat createNameFormat() 256 { 257 SimpleDateFormat fmt = new SimpleDateFormat( TIMESTAMP_FORMAT ); 258 fmt.setTimeZone( UTC_TIME_ZONE ); 259 return fmt; 260 } 261 262 @Override 263 public Map<String, String> toProperties() 264 { 265 Map<String, String> properties = new HashMap<>(); 266 properties.put( "action", this.action ); 267 if ( this.userId != null ) 268 { 269 properties.put( "user", this.userId ); 270 } 271 if ( this.remoteIP != null ) 272 { 273 properties.put( "remoteIP", this.remoteIP ); 274 } 275 if ( this.resource != null ) 276 { 277 properties.put( "resource", this.resource ); 278 } 279 return properties; 280 } 281 282 @Override 283 public void fromProperties( Map<String, String> properties ) 284 { 285 this.action = properties.get( "action" ); 286 this.remoteIP = properties.get( "remoteIP" ); 287 this.userId = properties.get( "user" ); 288 this.resource = properties.get( "resource" ); 289 } 290 291 @Override 292 public boolean equals( Object o ) 293 { 294 if ( this == o ) 295 { 296 return true; 297 } 298 if ( o == null || getClass() != o.getClass() ) 299 { 300 return false; 301 } 302 303 AuditEvent that = (AuditEvent) o; 304 305 if ( !action.equals( that.action ) ) 306 { 307 return false; 308 } 309 if ( remoteIP != null ? !remoteIP.equals( that.remoteIP ) : that.remoteIP != null ) 310 { 311 return false; 312 } 313 if ( repositoryId != null ? !repositoryId.equals( that.repositoryId ) : that.repositoryId != null ) 314 { 315 return false; 316 } 317 if ( resource != null ? !resource.equals( that.resource ) : that.resource != null ) 318 { 319 return false; 320 } 321 if ( !timestamp.equals( that.timestamp ) ) 322 { 323 return false; 324 } 325 if ( userId != null ? !userId.equals( that.userId ) : that.userId != null ) 326 { 327 return false; 328 } 329 330 return true; 331 } 332 333 @Override 334 public int hashCode() 335 { 336 int result = repositoryId != null ? repositoryId.hashCode() : 0; 337 result = 31 * result + ( userId != null ? userId.hashCode() : 0 ); 338 result = 31 * result + ( remoteIP != null ? remoteIP.hashCode() : 0 ); 339 result = 31 * result + ( resource != null ? resource.hashCode() : 0 ); 340 result = 31 * result + action.hashCode(); 341 result = 31 * result + timestamp.hashCode(); 342 return result; 343 } 344 345 @Override 346 public String toString() 347 { 348 final StringBuilder sb = new StringBuilder(); 349 sb.append( "AuditEvent" ); 350 sb.append( "{repositoryId='" ).append( repositoryId ).append( '\'' ); 351 sb.append( ", userId='" ).append( userId ).append( '\'' ); 352 sb.append( ", remoteIP='" ).append( remoteIP ).append( '\'' ); 353 sb.append( ", resource='" ).append( resource ).append( '\'' ); 354 sb.append( ", action='" ).append( action ).append( '\'' ); 355 sb.append( ", timestamp=" ).append( timestamp ); 356 sb.append( '}' ); 357 return sb.toString(); 358 } 359 360 361}