1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.googleapps;
16  
17  import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
18  import com.liferay.portal.kernel.log.Log;
19  import com.liferay.portal.kernel.log.LogFactoryUtil;
20  import com.liferay.portal.kernel.servlet.HttpHeaders;
21  import com.liferay.portal.kernel.util.ContentTypes;
22  import com.liferay.portal.kernel.util.Http;
23  import com.liferay.portal.kernel.util.HttpUtil;
24  import com.liferay.portal.kernel.util.PropertiesUtil;
25  import com.liferay.portal.kernel.util.PropsKeys;
26  import com.liferay.portal.kernel.util.StringPool;
27  import com.liferay.portal.kernel.util.Time;
28  import com.liferay.portal.kernel.xml.Document;
29  import com.liferay.portal.kernel.xml.Element;
30  import com.liferay.portal.kernel.xml.Namespace;
31  import com.liferay.portal.kernel.xml.QName;
32  import com.liferay.portal.kernel.xml.SAXReaderUtil;
33  import com.liferay.portal.model.Company;
34  import com.liferay.portal.service.CompanyLocalServiceUtil;
35  import com.liferay.portal.util.PrefsPropsUtil;
36  
37  import java.util.Properties;
38  
39  /**
40   * <a href="GoogleApps.java.html"><b><i>View Source</i></b></a>
41   *
42   * @author Brian Wing Shun Chan
43   */
44  public class GoogleApps {
45  
46      public GoogleApps(long companyId) {
47          try {
48              _companyId = companyId;
49  
50              init(true);
51          }
52          catch (Exception e) {
53              _log.error(e, e);
54          }
55      }
56  
57      public void addNickname(long userId, String nickname) throws Exception {
58          Document document = SAXReaderUtil.createDocument();
59  
60          Element atomEntry = _addAtomEntry(document);
61  
62          _addAtomCategory(atomEntry, "nickname");
63  
64          Element appsLogin = atomEntry.addElement("apps:login");
65  
66          appsLogin.addAttribute("userName", String.valueOf(userId));
67  
68          Element appsNickname = atomEntry.addElement("apps:nickname");
69  
70          appsNickname.addAttribute("name", nickname);
71  
72          Http.Options options = _getOptions();
73  
74          options.setBody(
75              document.formattedString(), ContentTypes.APPLICATION_ATOM_XML,
76              StringPool.UTF8);
77          options.setLocation(_getNicknameURL());
78          options.setPost(true);
79  
80          HttpUtil.URLtoString(options);
81      }
82  
83      public void addSendAs(long userId, String fullName, String emailAddress)
84          throws Exception {
85  
86          Document document = SAXReaderUtil.createDocument();
87  
88          Element atomEntry = _addAtomEntry(document);
89  
90          _addAppsProperty(atomEntry, "name", fullName);
91          _addAppsProperty(atomEntry, "address", emailAddress);
92          _addAppsProperty(atomEntry, "makeDefault", Boolean.TRUE.toString());
93  
94          Http.Options options = _getOptions();
95  
96          options.setBody(
97              document.formattedString(), ContentTypes.APPLICATION_ATOM_XML,
98              StringPool.UTF8);
99          options.setLocation(
100             _URL + "emailsettings/2.0/" + _domain + "/" + userId + "/sendas");
101         options.setPost(true);
102 
103         HttpUtil.URLtoString(options);
104     }
105 
106     public void addUser(
107             long userId, String password, String firstName, String lastName)
108         throws Exception {
109 
110         Document document = SAXReaderUtil.createDocument();
111 
112         Element atomEntry = _addAtomEntry(document);
113 
114         _addAtomCategory(atomEntry, "user");
115 
116         Element appsLogin = atomEntry.addElement("apps:login");
117 
118         appsLogin.addAttribute("password", password);
119         appsLogin.addAttribute("userName", String.valueOf(userId));
120 
121         Element appsName = atomEntry.addElement("apps:name");
122 
123         appsName.addAttribute("familyName", lastName);
124         appsName.addAttribute("givenName", firstName);
125 
126         Http.Options options = _getOptions();
127 
128         options.setBody(
129             document.formattedString(), ContentTypes.APPLICATION_ATOM_XML,
130             StringPool.UTF8);
131         options.setLocation(_getUserURL());
132         options.setPost(true);
133 
134         HttpUtil.URLtoString(options);
135     }
136 
137     public void deleteNickname(String nickname) throws Exception {
138         Http.Options options = _getOptions();
139 
140         options.setDelete(true);
141         options.setLocation(_getNicknameURL(nickname));
142 
143         HttpUtil.URLtoString(options);
144     }
145 
146     public void deleteUser(long userId) throws Exception {
147         Http.Options options = _getOptions();
148 
149         options.setDelete(true);
150         options.setLocation(_getUserURL(userId));
151 
152         HttpUtil.URLtoString(options);
153     }
154 
155     public void init(boolean manual) throws Exception {
156         if (manual || _isStale()) {
157             _init();
158         }
159     }
160 
161     public void updatePassword(long userId, String password) throws Exception {
162         String userXML = _getUserXML(userId);
163 
164         Document document = SAXReaderUtil.read(new UnsyncStringReader(userXML));
165 
166         Element atomEntry = document.getRootElement();
167 
168         Element appsLogin = atomEntry.element(_getAppsQName("login"));
169 
170         appsLogin.addAttribute("password", password);
171 
172         Http.Options options = _getOptions();
173 
174         options.setBody(
175             document.formattedString(), ContentTypes.APPLICATION_ATOM_XML,
176             StringPool.UTF8);
177         options.setLocation(_getUserURL(userId));
178         options.setPut(true);
179 
180         HttpUtil.URLtoString(options);
181     }
182 
183     private Element _addAppsProperty(
184         Element parentElement, String name, String value) {
185 
186         Element element = parentElement.addElement("apps:property");
187 
188         element.addAttribute("name", name);
189         element.addAttribute("value", value);
190 
191         return element;
192     }
193 
194     private Element _addAtomCategory(Element parentElement, String type) {
195         Element element = parentElement.addElement("atom:category");
196 
197         element.addAttribute("scheme", "http://schemas.google.com/g/2005#kind");
198         element.addAttribute(
199             "term", "http://schemas.google.com/apps/2006#" + type);
200 
201         return element;
202     }
203 
204     private Element _addAtomEntry(Document document) {
205         Element element = document.addElement("atom:entry");
206 
207         element.add(_getAppsNamespace());
208         element.add(_getAtomNamespace());
209 
210         return element;
211     }
212 
213     private Namespace _getAppsNamespace() {
214         return SAXReaderUtil.createNamespace(_APPS_PREFIX, _APPS_URI);
215     }
216 
217     private QName _getAppsQName(String localName) {
218         return SAXReaderUtil.createQName(localName, _getAppsNamespace());
219     }
220 
221     private Namespace _getAtomNamespace() {
222         return SAXReaderUtil.createNamespace(_ATOM_PREFIX, _ATOM_URI);
223     }
224 
225     private String _getNicknameURL() {
226         return _URL + _domain + "/nickname/2.0";
227     }
228 
229     private String _getNicknameURL(String nickname) {
230         return _getNicknameURL() + StringPool.SLASH + nickname;
231     }
232 
233     private Http.Options _getOptions() {
234         Http.Options options = new Http.Options();
235 
236         options.addHeader(
237             HttpHeaders.AUTHORIZATION,
238             "GoogleLogin auth=" + _authenticationToken);
239 
240         return options;
241     }
242 
243     private String _getUserURL() {
244         return _URL + _domain + "/user/2.0";
245     }
246 
247     private String _getUserURL(long userId) {
248         return _getUserURL() + StringPool.SLASH + userId;
249     }
250 
251     private String _getUserXML(long userId) throws Exception {
252         Http.Options options = _getOptions();
253 
254         options.setLocation(_getUserURL(userId));
255 
256         return HttpUtil.URLtoString(options);
257     }
258 
259     private void _init() throws Exception {
260         Company company = CompanyLocalServiceUtil.getCompany(_companyId);
261 
262         _domain = company.getMx();
263         _userName = PrefsPropsUtil.getString(
264             _companyId, PropsKeys.GOOGLE_APPS_USERNAME);
265         _password = PrefsPropsUtil.getString(
266             _companyId, PropsKeys.GOOGLE_APPS_PASSWORD);
267 
268         if (!_userName.contains(StringPool.AT)) {
269             _userName += StringPool.AT + _domain;
270         }
271 
272         Http.Options options = new Http.Options();
273 
274         options.addPart("Email", _userName);
275         options.addPart("Passwd", _password);
276         options.addPart("accountType", "HOSTED");
277         options.addPart("service", "apps");
278         options.setLocation("https://www.google.com/accounts/ClientLogin");
279         options.setPost(true);
280 
281         String content = HttpUtil.URLtoString(options);
282 
283         Properties properties = PropertiesUtil.load(content);
284 
285         _authenticationToken = properties.getProperty("Auth");
286 
287         _initTime = System.currentTimeMillis();
288     }
289 
290     private boolean _isStale() {
291         if ((_initTime + (Time.HOUR * 23)) > System.currentTimeMillis()) {
292             return false;
293         }
294         else {
295             return true;
296         }
297     }
298 
299     private static final String _APPS_PREFIX = "apps";
300 
301     private static final String _APPS_URI =
302         "http://schemas.google.com/apps/2006";
303 
304     private static final String _ATOM_PREFIX = "atom";
305 
306     private static final String _ATOM_URI = "http://www.w3.org/2005/Atom";
307 
308     private static final String _URL = "https://apps-apis.google.com/a/feeds/";
309 
310     private static Log _log = LogFactoryUtil.getLog(GoogleApps.class);
311 
312     private String _authenticationToken;
313     private long _companyId;
314     private String _domain;
315     private long _initTime;
316     private String _password;
317     private String _userName;
318 
319 }