/* Copyright (c) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gdata.client.appsforyourdomain.audit;
import com.google.gdata.client.appsforyourdomain.AppsPropertyService;
import com.google.gdata.data.appsforyourdomain.AppsForYourDomainErrorCode;
import com.google.gdata.data.appsforyourdomain.AppsForYourDomainException;
import com.google.gdata.data.appsforyourdomain.generic.GenericEntry;
import com.google.gdata.data.appsforyourdomain.generic.GenericFeed;
import com.google.gdata.model.atom.Link;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* AuditService allows Google Apps administrators to audit user's emails, email
* drafts, and archived chats.
*
*
*
*/
public class AuditService extends AppsPropertyService {
/*
* Service URL of the API.
*/
public static final String BASE_URL =
"https://apps-apis.google.com/a/feeds/compliance/audit/";
private String domain = null;
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd%20hh:mm");
static {
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
DATE_FORMAT.setLenient(false);
}
private static Logger LOGGER = Logger.getLogger(AuditService.class.toString());
/**
* Parameterized constructor for AuditService.
*
* @param adminEmail email id of the administrator
* @param adminPassword password for the administrator account
* @param domain the domain to be monitored
* @param applicationName application name for e.g audit-mycompany
* @throws AuthenticationException if an authentication related error occurs.
*/
public AuditService(String adminEmail, String adminPassword, String domain,
String applicationName) throws AuthenticationException {
this(domain, applicationName);
setUserCredentials(adminEmail, adminPassword);
}
/**
* Parameterized constructor to setup a Service object which can be used to
* initialize the service without obtaining a token. The user should
* explicitly authorize the service by calling either {@code
* setUserCredentials} or {@code setUserToken} when using this constructor.
*
* @param domain Domain being configured
* @param applicationName Application name consuming the API
* @throws AuthenticationException If an authentication error occurs
*/
public AuditService(String domain, String applicationName) throws AuthenticationException {
super(applicationName);
this.domain = domain;
}
/**
* Creates a new monitoring task to begin an audit.
*
* Note: The number of daily requests are limited per domain, and can include
* requests from several administrators during the day
*
* @param sourceUser is the user who receives or sends messages that are being
* audited.
* @param mailMonitor a POJO with details of the monitoring task
* @return a GenericEntry with details of the task created
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericEntry createMailMonitor(String sourceUser, MailMonitor mailMonitor)
throws AppsForYourDomainException, MalformedURLException, IOException, ServiceException {
GenericEntry entry = mailMonitor.toGenericEntry();
return insert(new URL(BASE_URL + "mail/monitor/" + domain + "/" + sourceUser), entry);
}
/**
* Retrieves all the monitors of a given user.
*
* @param sourceUser user whose monitors are to be retrieved
* @return a GenericFeed object with details of monitors created.
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericFeed retrieveMonitors(String sourceUser) throws AppsForYourDomainException,
MalformedURLException, IOException, ServiceException {
return getFeed(new URL(BASE_URL + "mail/monitor/" + domain + "/" + sourceUser),
GenericFeed.class);
}
/**
* Removes the monitor configured for the given source and destination user.
*
* Note: The number of daily requests are limited per domain, and can include
* requests from several administrators during the day
*
* @param sourceUser the user who is being monitored
* @param destUser this user is the auditor who receives the audited email
* messages as blind carbon copies (Bcc).
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public void deleteMonitor(String sourceUser, String destUser) throws AppsForYourDomainException,
MalformedURLException, IOException, ServiceException {
delete(new URL(BASE_URL + "mail/monitor/" + domain + "/" + sourceUser + "/" + destUser));
}
/**
* Upload a public key for signing mailbox dump archives. This public
* encryption key should be a PGP format ascii-encoded RSA key. Before
* uploading the public key, convert the key to a base64 encoded string
*
* @param base64encodedKey a Base64 encoded, PGP format ASCII read RSA key
* @return a GenericEntry instance with the inserted entry.
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericEntry uploadPublicKey(String base64encodedKey) throws AppsForYourDomainException,
MalformedURLException, IOException, ServiceException {
GenericEntry entry = new GenericEntry();
entry.addProperty("publicKey", base64encodedKey);
return insert(new URL(BASE_URL + "publickey/" + domain), entry);
}
/**
* Creates a new request for obtaining a user mailbox dump. The mailbox files
* are encrypted using the key uploaded {@code uploadPublicKey} and are
* available in <a href="http://en.wikipedia.org/wiki/Mbox">mbox format</a>
*
* @param mailBoxDumpRequest a POJO with request details.
* @return the inserted entry
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericEntry createMailboxDumpRequest(MailBoxDumpRequest mailBoxDumpRequest)
throws AppsForYourDomainException, MalformedURLException, IOException, ServiceException {
String user = mailBoxDumpRequest.getUserEmailAddress().split("@")[0];
URL url = new URL(BASE_URL + "mail/export/" + domain + "/" + user);
return insert(url, mailBoxDumpRequest.toGenericEntry());
}
/**
* Retrieves all mailbox dump requests from the given start date.
*
* @param fromDate optional date in the format 'yyyy-MM-dd hh:mm' in UTC. Pass
* <code>null</code> to retrieve without date filter.
* @return a List of all mailbox dump request entries for the domain
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public List<GenericEntry> retrieveAllMailboxDumpRequests(Date fromDate)
throws AppsForYourDomainException, MalformedURLException, IOException, ServiceException {
String url = BASE_URL + "mail/export/" + domain;
if (fromDate != null) {
url += "?fromDate=" + DATE_FORMAT.format(fromDate);
}
return getAllPages(new URL(url), GenericFeed.class);
}
/**
* Retrieves a page of mailbox dump requests from the given start date.
*
* @param fromDate optional date in the format 'yyyy-MM-dd hh:mm' in UTC. Pass
* <code>null</code> to retrieve without date filter
* @return a page of mailbox dump request entries for the domain
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericFeed retrievePageOfMailboxDumpRequests(Date fromDate)
throws AppsForYourDomainException, MalformedURLException, IOException, ServiceException {
String url = BASE_URL + "mail/export/" + domain;
if (fromDate != null) {
url += "?fromDate=" + DATE_FORMAT.format(fromDate);
}
return getFeed(new URL(url), GenericFeed.class);
}
/**
* Retrieves the next page of mailbox dump requests by following the atom next
* link.
*
* @param next The feed link for next page
* @return a page of mailbox dump request entries for the domain
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericFeed retrieveNextPageOfMailboxDumpRequests(Link next)
throws AppsForYourDomainException, MalformedURLException, IOException, ServiceException {
return getFeed(new URL(next.getHref()), GenericFeed.class);
}
/**
* Retrieves the mailbox dump request for the given ID and user.
*
* @param user the user whose dump requests need to be retrieved
* @param id the requestId of the mailbox dump request
* @return a GenericEntry instance of the requested dump request
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericEntry retrieveMailboxDumpRequest(String user, String id)
throws AppsForYourDomainException, MalformedURLException, IOException, ServiceException {
return getEntry(new URL(BASE_URL + "mail/export/" + domain + "/" + user + "/" + id),
GenericEntry.class);
}
/**
* Deletes the mailbox dump request for the given ID and user.
*
* @param user the user whose dump requests need to be deleted.
* @param id the requestId of the mailbox dump request.
* @return true, if delete succeeds.
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public boolean deleteMailboxDumpRequest(String user, String id)
throws AppsForYourDomainException, MalformedURLException, IOException, ServiceException {
try {
delete(new URL(BASE_URL + "mail/export/" + domain + "/" + user + "/" + id));
return true;
} catch (AppsForYourDomainException ex) {
if (ex.getErrorCode() == AppsForYourDomainErrorCode.InvalidValue) {
LOGGER.log(Level.INFO, "The request should either have status COMPLETED or"
+ "MARKED_DELETE before being deleted");
}
}
return false;
}
/**
* Creates a new Account Information request. When completed, the account
* info is available for download.
*
* @param user the domain user whose account information is to be audited
* @return GenericEntry with request details.
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericEntry createAccountInfoRequest(String user) throws AppsForYourDomainException,
IOException, ServiceException {
URL url = new URL(BASE_URL + "account/" + domain + "/" + user);
return insert(url, new GenericEntry());
}
/**
* Retrieves a previously created account/services related information request
* for the given user.
*
* @param user the user whose account info is being retrieved
* @param requestId the unique requestId identifying the request
* @return a GenericEntry instance with request details
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericEntry retrieveAccountInfoRequest(String user, String requestId)
throws AppsForYourDomainException, IOException, ServiceException {
URL url = new URL(BASE_URL + "account/" + domain + "/" + user + "/" + requestId);
return getEntry(url, GenericEntry.class);
}
/**
* Retrieve all the Account info requests from the given start date.
*
* @param fromDate optional date in the format 'yyyy-MM-dd hh:mm' in UTC. Pass
* <code>null</code> to retrieve without date filter.
* @return Entries created starting the requested date
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public List<GenericEntry> retrieveAllAccountInfoRequests(Date fromDate)
throws AppsForYourDomainException, IOException, ServiceException {
String url = BASE_URL + "account/" + domain;
if (fromDate != null) {
url += "?fromDate=" + DATE_FORMAT.format(fromDate);
}
return getAllPages(new URL(url), GenericFeed.class);
}
/**
* Retrieves a page of account info requests from the given optional start
* date. Pass <code>null</code> for date to retrieve requests without date
* filter.
*
* @param fromDate optional date in the format 'yyyy-MM-dd hh:mm' in UTC. Pass
* <code>null</code> to retrieve without date filter
* @return a page of account info request entries for the domain
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericFeed retrievePageOfAccountInfoRequests(Date fromDate)
throws AppsForYourDomainException, MalformedURLException, IOException, ServiceException {
String url = BASE_URL + "account/" + domain;
if (fromDate != null) {
url += "?fromDate=" + DATE_FORMAT.format(fromDate);
}
return getFeed(new URL(url), GenericFeed.class);
}
/**
* Retrieves the next page of account info requests by following the atom next
* link.
*
* @param next The feed link for next page
* @return a page of account info request entries for the domain
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws MalformedURLException If a URL related error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public GenericFeed retrieveNextPageOfAccountInfoRequests(Link next)
throws AppsForYourDomainException, MalformedURLException, IOException, ServiceException {
return getFeed(new URL(next.getHref()), GenericFeed.class);
}
/**
* Deletes the account info request for the given user
*
* @param user the user whose request is to be deleted
* @param requestId the unique id of the request
* @throws AppsForYourDomainException If an Audit API error occurs
* @throws IOException If a network I/O related error occurs
* @throws ServiceException If the API service fails
*/
public void deleteAccountInfoRequest(String user, String requestId)
throws AppsForYourDomainException, IOException, ServiceException {
URL url = new URL(BASE_URL + "account/" + domain + "/" + user + "/" + requestId);
delete(url);
}
}