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   */
54  public class GoogleApps {
55  
56      public GoogleApps(long companyId) {
57          try {
58              _companyId = companyId;
59  
60              init(true);
61          }
62          catch (Exception e) {
63              _log.error(e, e);
64          }
65      }
66  
67      public void addNickname(long userId, String nickname) throws Exception {
68          Document document = SAXReaderUtil.createDocument();
69  
70          Element atomEntry = _addAtomEntry(document);
71  
72          _addAtomCategory(atomEntry, "nickname");
73  
74          Element appsLogin = atomEntry.addElement("apps:login");
75  
76          appsLogin.addAttribute("userName", String.valueOf(userId));
77  
78          Element appsNickname = atomEntry.addElement("apps:nickname");
79  
80          appsNickname.addAttribute("name", nickname);
81  
82          Http.Options options = _getOptions();
83  
84          options.setBody(
85              document.formattedString(), ContentTypes.APPLICATION_ATOM_XML,
86              StringPool.UTF8);
87          options.setLocation(_getNicknameURL());
88          options.setPost(true);
89  
90          HttpUtil.URLtoString(options);
91      }
92  
93      public void addSendAs(long userId, String fullName, String emailAddress)
94          throws Exception {
95  
96          Document document = SAXReaderUtil.createDocument();
97  
98          Element atomEntry = _addAtomEntry(document);
99  
100         _addAppsProperty(atomEntry, "name", fullName);
101         _addAppsProperty(atomEntry, "address", emailAddress);
102         _addAppsProperty(atomEntry, "makeDefault", Boolean.TRUE.toString());
103 
104         Http.Options options = _getOptions();
105 
106         options.setBody(
107             document.formattedString(), ContentTypes.APPLICATION_ATOM_XML,
108             StringPool.UTF8);
109         options.setLocation(
110             _URL + "emailsettings/2.0/" + _domain + "/" + userId + "/sendas");
111         options.setPost(true);
112 
113         HttpUtil.URLtoString(options);
114     }
115 
116     public void addUser(
117             long userId, String password, String firstName, String lastName)
118         throws Exception {
119 
120         Document document = SAXReaderUtil.createDocument();
121 
122         Element atomEntry = _addAtomEntry(document);
123 
124         _addAtomCategory(atomEntry, "user");
125 
126         Element appsLogin = atomEntry.addElement("apps:login");
127 
128         appsLogin.addAttribute("password", password);
129         appsLogin.addAttribute("userName", String.valueOf(userId));
130 
131         Element appsName = atomEntry.addElement("apps:name");
132 
133         appsName.addAttribute("familyName", lastName);
134         appsName.addAttribute("givenName", firstName);
135 
136         Http.Options options = _getOptions();
137 
138         options.setBody(
139             document.formattedString(), ContentTypes.APPLICATION_ATOM_XML,
140             StringPool.UTF8);
141         options.setLocation(_getUserURL());
142         options.setPost(true);
143 
144         HttpUtil.URLtoString(options);
145     }
146 
147     public void deleteNickname(String nickname) throws Exception {
148         Http.Options options = _getOptions();
149 
150         options.setDelete(true);
151         options.setLocation(_getNicknameURL(nickname));
152 
153         HttpUtil.URLtoString(options);
154     }
155 
156     public void deleteUser(long userId) throws Exception {
157         Http.Options options = _getOptions();
158 
159         options.setDelete(true);
160         options.setLocation(_getUserURL(userId));
161 
162         HttpUtil.URLtoString(options);
163     }
164 
165     public void init(boolean manual) throws Exception {
166         if (manual || _isStale()) {
167             _init();
168         }
169     }
170 
171     public void updatePassword(long userId, String password) throws Exception {
172         String userXML = _getUserXML(userId);
173 
174         Document document = SAXReaderUtil.read(new StringReader(userXML));
175 
176         Element atomEntry = document.getRootElement();
177 
178         Element appsLogin = atomEntry.element(_getAppsQName("login"));
179 
180         appsLogin.addAttribute("password", password);
181 
182         Http.Options options = _getOptions();
183 
184         options.setBody(
185             document.formattedString(), ContentTypes.APPLICATION_ATOM_XML,
186             StringPool.UTF8);
187         options.setLocation(_getUserURL(userId));
188         options.setPut(true);
189 
190         HttpUtil.URLtoString(options);
191     }
192 
193     private Element _addAppsProperty(
194         Element parentElement, String name, String value) {
195 
196         Element element = parentElement.addElement("apps:property");
197 
198         element.addAttribute("name", name);
199         element.addAttribute("value", value);
200 
201         return element;
202     }
203 
204     private Element _addAtomCategory(Element parentElement, String type) {
205         Element element = parentElement.addElement("atom:category");
206 
207         element.addAttribute("scheme", "http://schemas.google.com/g/2005#kind");
208         element.addAttribute(
209             "term", "http://schemas.google.com/apps/2006#" + type);
210 
211         return element;
212     }
213 
214     private Element _addAtomEntry(Document document) {
215         Element element = document.addElement("atom:entry");
216 
217         element.add(_getAppsNamespace());
218         element.add(_getAtomNamespace());
219 
220         return element;
221     }
222 
223     private Namespace _getAppsNamespace() {
224         return SAXReaderUtil.createNamespace(_APPS_PREFIX, _APPS_URI);
225     }
226 
227     private QName _getAppsQName(String localName) {
228         return SAXReaderUtil.createQName(localName, _getAppsNamespace());
229     }
230 
231     private Namespace _getAtomNamespace() {
232         return SAXReaderUtil.createNamespace(_ATOM_PREFIX, _ATOM_URI);
233     }
234 
235     private String _getNicknameURL() {
236         return _URL + _domain + "/nickname/2.0";
237     }
238 
239     private String _getNicknameURL(String nickname) {
240         return _getNicknameURL() + StringPool.SLASH + nickname;
241     }
242 
243     private Http.Options _getOptions() {
244         Http.Options options = new Http.Options();
245 
246         options.addHeader(
247             HttpHeaders.AUTHORIZATION,
248             "GoogleLogin auth=" + _authenticationToken);
249 
250         return options;
251     }
252 
253     private String _getUserURL() {
254         return _URL + _domain + "/user/2.0";
255     }
256 
257     private String _getUserURL(long userId) {
258         return _getUserURL() + StringPool.SLASH + userId;
259     }
260 
261     private String _getUserXML(long userId) throws Exception {
262         Http.Options options = _getOptions();
263 
264         options.setLocation(_getUserURL(userId));
265 
266         return HttpUtil.URLtoString(options);
267     }
268 
269     private void _init() throws Exception {
270         Company company = CompanyLocalServiceUtil.getCompany(_companyId);
271 
272         _domain = company.getMx();
273         _userName = PrefsPropsUtil.getString(
274             _companyId, PropsKeys.GOOGLE_APPS_USERNAME);
275         _password = PrefsPropsUtil.getString(
276             _companyId, PropsKeys.GOOGLE_APPS_PASSWORD);
277 
278         if (!_userName.contains(StringPool.AT)) {
279             _userName += StringPool.AT + _domain;
280         }
281 
282         Http.Options options = new Http.Options();
283 
284         options.addPart("Email", _userName);
285         options.addPart("Passwd", _password);
286         options.addPart("accountType", "HOSTED");
287         options.addPart("service", "apps");
288         options.setLocation("https://www.google.com/accounts/ClientLogin");
289         options.setPost(true);
290 
291         String content = HttpUtil.URLtoString(options);
292 
293         Properties properties = PropertiesUtil.load(content);
294 
295         _authenticationToken = properties.getProperty("Auth");
296 
297         _initTime = System.currentTimeMillis();
298     }
299 
300     private boolean _isStale() {
301         if ((_initTime + (Time.HOUR * 23)) > System.currentTimeMillis()) {
302             return false;
303         }
304         else {
305             return true;
306         }
307     }
308 
309     private static final String _APPS_PREFIX = "apps";
310 
311     private static final String _APPS_URI =
312         "http://schemas.google.com/apps/2006";
313 
314     private static final String _ATOM_PREFIX = "atom";
315 
316     private static final String _ATOM_URI = "http://www.w3.org/2005/Atom";
317 
318     private static final String _URL = "https://apps-apis.google.com/a/feeds/";
319 
320     private static Log _log = LogFactoryUtil.getLog(GoogleApps.class);
321 
322     private String _authenticationToken;
323     private long _companyId;
324     private String _domain;
325     private long _initTime;
326     private String _password;
327     private String _userName;
328 
329 }