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