1 // 2 // The Antville Project 3 // http://code.google.com/p/antville 4 // 5 // Copyright 2001-2007 by The Antville People 6 // 7 // Licensed under the Apache License, Version 2.0 (the ``License''); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an ``AS IS'' BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 // 19 // $Revision:3329 $ 20 // $LastChangedBy:piefke3000 $ 21 // $LastChangedDate:2007-09-14 15:18:09 +0200 (Fri, 14 Sep 2007) $ 22 // $URL$ 23 // 24 25 /** 26 * @fileOverview Defines the Members prototype. 27 */ 28 29 markgettext("Members"); 30 markgettext("members"); 31 32 /** 33 * @name Members 34 * @constructor 35 * @property {Membership[]} _children 36 * @property {Membership[]} contributors 37 * @property {Membership[]} managers 38 * @property {Membership[]} owners 39 * @property {Membership[]} subscribers 40 * @extends HopObject 41 */ 42 43 /** 44 * 45 * @param {String} action 46 * @returns {Boolean} 47 */ 48 Members.prototype.getPermission = function(action) { 49 switch (action) { 50 case "login": 51 case "logout": 52 case "register": 53 case "reset": 54 case "salt.js": 55 return true; 56 } 57 58 if (!this._parent.getPermission("main")) { 59 return false; 60 } 61 62 switch (action) { 63 case "edit": 64 case "privileges": 65 case "subscriptions": 66 case "updated": 67 return !!session.user; 68 69 case ".": 70 case "main": 71 case "add": 72 case "owners": 73 case "managers": 74 case "contributors": 75 case "subscribers": 76 return Membership.require(Membership.OWNER) || 77 User.require(User.PRIVILEGED); 78 } 79 return false; 80 } 81 82 Members.prototype.main_action = function() { 83 res.data.title = gettext("Site Members"); 84 res.data.list = renderList(this, "$Membership#member", 85 10, req.queryParams.page); 86 res.data.pager = renderPager(this, this.href(req.action), 87 10, req.queryParams.page); 88 res.data.body = this.renderSkinAsString("$Members#main"); 89 res.handlers.site.renderSkin("Site#page"); 90 return; 91 } 92 93 Members.prototype.register_action = function() { 94 if (req.postParams.register) { 95 try { 96 var title = res.handlers.site.title; 97 var user = User.register(req.postParams); 98 var membership = new Membership(user, Membership.SUBSCRIBER); 99 this.add(membership); 100 membership.notify(req.action, user.email, 101 gettext('[{0}] Welcome to {1}!', root.title, title)); 102 res.message = gettext('Welcome to “{0}”, {1}. Have fun!', 103 title, user.name); 104 res.redirect(User.getLocation() || this._parent.href()); 105 } catch (ex) { 106 res.message = ex; 107 } 108 } 109 110 session.data.token = User.getSalt(); 111 res.data.action = this.href(req.action); 112 res.data.title = gettext("Register"); 113 res.data.body = this.renderSkinAsString("$Members#register"); 114 this._parent.renderSkin("Site#page"); 115 return; 116 } 117 118 Members.prototype.reset_action = function() { 119 if (req.postParams.reset) { 120 try { 121 if (!req.postParams.name || !req.postParams.email) { 122 throw Error(gettext("Please enter a user name and e-mail address.")); 123 } 124 var user = User.getByName(req.postParams.name); 125 if (!user || user.email !== req.postParams.email) { 126 throw Error(gettext("User name and e-mail address do not match.")) 127 } 128 var token = User.getSalt(); 129 user.metadata.set("resetToken", token); 130 sendMail(user.email, gettext("[{0}] Password reset confirmation", 131 root.title), user.renderSkinAsString("$User#notify_reset", { 132 href: this.href("reset"), 133 token: token 134 })); 135 res.message = gettext("A confirmation mail was sent to your e-mail address."); 136 res.redirect(this._parent.href()); 137 } catch(ex) { 138 res.message = ex; 139 } 140 } else if (req.data.user && req.data.token) { 141 var user = User.getById(req.data.user); 142 if (user) { 143 var token = user.metadata.get("resetToken"); 144 if (token) { 145 session.login(user); 146 if (req.postParams.save) { 147 var password = req.postParams.password; 148 if (!password) { 149 res.message = gettext("Please enter a new password."); 150 } else if (password !== req.postParams.passwordConfirm) { 151 res.message = gettext("The passwords do not match."); 152 } else { 153 user.hash = (password + user.salt).md5(); 154 user.metadata.remove("resetToken"); 155 res.message = gettext("Your password was changed."); 156 res.redirect(this._parent.href()); 157 } 158 } 159 res.data.title = gettext("Reset Password"); 160 res.data.body = this.renderSkinAsString("$Members#password"); 161 this._parent.renderSkin("Site#page"); 162 return; 163 } 164 } 165 res.message = gettext("This URL is not valid for resetting your password."); 166 res.redirect(this.href(req.action)); 167 } 168 res.data.action = this.href(req.action); 169 res.data.title = gettext("Request Password Reset"); 170 res.data.body = this.renderSkinAsString("$Members#reset"); 171 this._parent.renderSkin("Site#page"); 172 return; 173 } 174 175 Members.prototype.login_action = function() { 176 if (req.postParams.login) { 177 try { 178 var user = User.login(req.postParams); 179 res.message = gettext('Welcome to {0}, {1}. Have fun!', 180 res.handlers.site.getTitle(), user.name); 181 res.redirect(User.getLocation() || this._parent.href()); 182 } catch (ex) { 183 res.message = ex; 184 } 185 } 186 session.data.token = User.getSalt(); 187 res.data.action = this.href(req.action); 188 res.data.title = gettext("Login"); 189 res.data.body = this.renderSkinAsString("$Members#login"); 190 this._parent.renderSkin("Site#page"); 191 return; 192 } 193 194 Members.prototype.logout_action = function() { 195 if (session.user) { 196 res.message = gettext("Good bye, {0}! Looking forward to seeing you again!", 197 session.user.name); 198 User.logout(); 199 } 200 res.redirect(this._parent.href()); 201 return; 202 } 203 204 Members.prototype.edit_action = function() { 205 if (req.postParams.save) { 206 try { 207 session.user.update(req.postParams); 208 res.message = gettext("The changes were saved successfully."); 209 res.redirect(this._parent.href()); 210 } catch (err) { 211 res.message = err.toString(); 212 } 213 } 214 215 session.data.token = User.getSalt(); 216 session.data.salt = session.user.salt; // FIXME 217 res.data.title = gettext("User Profile"); 218 res.data.body = session.user.renderSkinAsString("$User#edit"); 219 this._parent.renderSkin("Site#page"); 220 return; 221 } 222 223 Members.prototype.salt_js_action = function() { 224 res.contentType = "text/javascript"; 225 var user; 226 if (user = User.getByName(req.queryParams.user)) { 227 res.write((user.salt || String.EMPTY).toSource()); 228 } 229 return; 230 } 231 232 Members.prototype.owners_action = function() { 233 res.data.title = gettext("Site Owners"); 234 res.data.list = renderList(this.owners, 235 "$Membership#member", 10, req.queryParams.page); 236 res.data.pager = renderPager(this.owners, 237 this.href(req.action), 10, req.queryParams.page); 238 res.data.body = this.renderSkinAsString("$Members#main"); 239 res.handlers.site.renderSkin("Site#page"); 240 return; 241 } 242 243 Members.prototype.managers_action = function() { 244 res.data.title = gettext("Site Managers"); 245 res.data.list = renderList(this.managers, 246 "$Membership#member", 10, req.queryParams.page); 247 res.data.pager = renderPager(this.managers, 248 this.href(req.action), 10, req.queryParams.page); 249 res.data.body = this.renderSkinAsString("$Members#main"); 250 res.handlers.site.renderSkin("Site#page"); 251 return; 252 } 253 254 Members.prototype.contributors_action = function() { 255 res.data.title = gettext("Site Contributors"); 256 res.data.list = renderList(this.contributors, 257 "$Membership#member", 10, req.queryParams.page); 258 res.data.pager = renderPager(this.contributors, 259 this.href(req.action), 10, req.data.page); 260 res.data.body = this.renderSkinAsString("$Members#main"); 261 res.handlers.site.renderSkin("Site#page"); 262 return; 263 } 264 265 Members.prototype.subscribers_action = function() { 266 res.data.title = gettext("Site Subscribers"); 267 res.data.list = renderList(this.subscribers, 268 "$Membership#member", 10, req.queryParams.page); 269 res.data.pager = renderPager(this.subscribers, 270 this.href(req.action), 10, req.queryParams.page); 271 res.data.body = this.renderSkinAsString("$Members#main"); 272 res.handlers.site.renderSkin("Site#page"); 273 return; 274 } 275 276 Members.prototype.updated_action = function() { 277 res.data.title = gettext("Updates"); 278 res.data.list = session.user.renderSkinAsString("$User#sites"); 279 res.data.body = session.user.renderSkinAsString("$User#subscriptions"); 280 res.handlers.site.renderSkin("Site#page"); 281 return; 282 } 283 284 Members.prototype.privileges_action = function() { 285 var site = res.handlers.site; 286 res.data.title = gettext("Privileges"); 287 res.data.list = renderList(session.user.memberships, function(item) { 288 res.handlers.subscription = item.site; 289 item.renderSkin("$Membership#subscription"); 290 return; 291 }); 292 res.handlers.site = site; 293 res.data.body = session.user.renderSkinAsString("$User#subscriptions"); 294 res.handlers.site.renderSkin("Site#page"); 295 return; 296 } 297 298 Members.prototype.subscriptions_action = function() { 299 var site = res.handlers.site; 300 res.data.title = gettext("Subscriptions"); 301 res.data.list = renderList(session.user.subscriptions, function(item) { 302 res.handlers.subscription = item.site; 303 item.renderSkin("$Membership#subscription"); 304 return; 305 }); 306 res.handlers.site = site; 307 res.data.body = session.user.renderSkinAsString("$User#subscriptions"); 308 res.handlers.site.renderSkin("Site#page"); 309 return; 310 } 311 312 Members.prototype.add_action = function() { 313 if (req.postParams.term) { 314 try { 315 var result = this.search(req.postParams.term); 316 if (result.length < 1) { 317 res.message = gettext("No user found to add as member."); 318 } else { 319 if (result.length >= 100) { 320 res.message = gettext("Too many users found, displaying the first {0} matches only.", 321 result.length); 322 } else { 323 res.message = ngettext("One user found.", "{0} users found.", 324 result.length); 325 } 326 res.data.result = this.renderSkinAsString("$Members#results", result); 327 } 328 } catch (ex) { 329 res.message = ex; 330 app.log(ex); 331 } 332 } else if (req.postParams.add) { 333 try { 334 var membership = this.addMembership(req.postParams); 335 membership.notify(req.action, membership.creator.email, 336 gettext('[{0}] Notification of membership change', root.title)); 337 res.message = gettext("Successfully added {0} to the list of members.", 338 req.postParams.name); 339 res.redirect(membership.href("edit")); 340 } catch (ex) { 341 res.message = ex; 342 app.log(ex); 343 } 344 res.redirect(this.href()); 345 } 346 res.data.action = this.href(req.action); 347 res.data.title = gettext('Add Member'); 348 res.data.body = this.renderSkinAsString("$Members#add"); 349 res.handlers.site.renderSkin("Site#page"); 350 return; 351 } 352 353 /** 354 * 355 * @param {String} searchString 356 * @returns {Object} 357 */ 358 Members.prototype.search = function(searchString) { 359 var self = this; 360 var mode = "="; 361 if (searchString.contains("*")) { 362 searchString = searchString.replace(/\*/g, "%"); 363 mode = "like"; 364 } 365 var sql = new Sql; 366 sql.retrieve(Sql.MEMBERSEARCH, mode, searchString, 100); 367 var counter = 0, name; 368 res.push(); 369 sql.traverse(function() { 370 // Check if the user is not already a member 371 if (!self.get(this.name)) { 372 self.renderSkin("$Members#result", {name: this.name}); 373 counter += 1; 374 } 375 }); 376 return { 377 result: res.pop(), 378 length: counter 379 }; 380 } 381 382 /** 383 * 384 * @param {Object} data 385 * @returns {Membership} 386 */ 387 Members.prototype.addMembership = function(data) { 388 var user = root.users.get(data.name); 389 if (!user) { 390 throw Error(gettext("Sorry, your input did not match any registered user.")); 391 } else if (this.get(data.name)) { 392 throw Error(gettext("This user is already a member of this site.")); 393 } 394 var membership = new Membership(user, Membership.SUBSCRIBER); 395 this.add(membership); 396 return membership; 397 } 398