def remind_email_invites(self, targets=None, fields=None): """ Sends an email reminder to the specified email invitees. """ # perform reminder invites = self.request.get('email-invites').split(",") addresses = [urllib.unquote(t).strip() for t in invites] sender = _email_sender(self) project_title = self.context.Title() proj_id = self.context.getId() for address in addresses: key = self.invite_util.getInvitesByEmailAddress(address).key msg_subs = dict(join_url=self.join_url(address, key, proj_id), #FIXME: spam-check this user_message=self.request.get('message', ''), subject=self.request.get('subject', ''), project_title=self.context.Title(), project_noun=self.project_noun, site_contact_url=self.portal.absolute_url() + "/contact-site-admin", ) msg = sender.constructMailMessage( mship_messages.email_invite_static_body, mfrom=self.loggedinmember.id, **msg_subs) if email_confirmation(): sender.sendMail(address, msg=msg, **msg_subs) else: log.info(msg) plural = len(addresses) != 1 msg = "Reminder%s sent: %s" % (plural and 's' or '',', '.join(addresses)) self.add_status_message(msg) self.redirect('manage-team')
def remove_email_invites(self, targets, fields=None): """ Retracts invitations sent to email addresses. Should send notifiers. """ addresses = [urllib.unquote(t).strip() for t in targets] sender = _email_sender(self) msg_subs = { 'project_title': self.context.title, 'project_noun': self.project_noun, } msg = sender.constructMailMessage(mship_messages.invitation_retracted, **msg_subs) msg_subject = sender.constructMailMessage( mship_messages.invitation_retracted_subject, **msg_subs) invite_util = getUtility(IEmailInvites, context=self.portal) proj_id = self.context.getId() for address in addresses: invite_util.removeInvitation(address, proj_id) if email_confirmation(): sender.sendMail(address, msg=msg, subject=msg_subject) plural = len(addresses) != 1 msg = u'Email invitation%s removed: %s' % (plural and 's' or '',', '.join(addresses)) self.add_status_message(msg) ret = dict([(target, {'action': 'delete'}) for target in targets]) return ret
def handle_request(self): userid_or_email = self.request.get("__ac_name") if not userid_or_email: self.addPortalStatusMessage(_(u'psm_enter_username_email', u"Please enter your username or email address.")) return False site_url = getToolByName(self.context, 'portal_url')() brain = self.brain_for_userid_or_email(userid_or_email) if brain is not None: userid = brain.getId if self.is_pending(getUserName=userid): self.redirect('%s/resend-confirmation?member=%s' % (site_url, userid)) return False reset_url = site_url + self.reset_url(userid) if email_confirmation(): self._mailPassword(brain.getEmail, reset_url) self.addPortalStatusMessage(_(u'psm_forgot_login', u'Your username is ${user_id}. If you would like to reset your password, please check your email account for further instructions.', mapping={u'user_id': userid})) else: self.redirect(reset_url) return True # else the user isn't found self.addPortalStatusMessage(u"We can't find your account.") return False
def remove_invitations(self, targets, fields=None): """ Deletes (or deactivates, if there's history to preserve) the membership objects. Should send notifiers. """ mem_ids = targets wftool = self.get_tool('portal_workflow') pwft = getToolByName(self, 'portal_placeful_workflow') deletes = [] sender = _email_sender(self) msg_subs = { 'project_title': self.context.title, 'project_noun': self.project_noun, } msg = sender.constructMailMessage(mship_messages.invitation_retracted, **msg_subs) msg_subject = sender.constructMailMessage( mship_messages.invitation_retracted_subject, **msg_subs) ret = {} for mem_id in mem_ids: mship = self.team.getMembershipByMemberId(mem_id) config = get_workflow_policy_config(self.team) if config is not None: wf_ids = config.getPlacefulChainFor('OpenMembership') wf_id = wf_ids[0] else: wf_id = 'openplans_team_membership_workflow' status = wftool.getStatusOf(wf_id, mship) if status.get('action') == 'reinvite': # deactivate wftool.doActionFor(mship, 'deactivate') else: # delete deletes.append(mem_id) ret[mem_id] = {'action': 'delete'} if email_confirmation(): sender.sendMail(mem_id, msg=msg, subject=msg_subject) if deletes: self.team.manage_delObjects(ids=deletes) plural = len(mem_ids) != 1 msg = u'Invitation%s removed: %s' % (plural and 's' or '', ', '.join(mem_ids)) self.add_status_message(msg) return ret
def _create_member(self, targets=None, fields=None, confirmed=False): """ tries to create a member object based on the request. returns the newly created member, or an error dictionary on failure. """ factory = ICreateMembers(self.portal) self.errors = factory.validate(self.request) viewlet_mgr = getMultiAdapter((self.context, self.request, self), name='opencore.create_account') if not hasattr(viewlet_mgr, 'viewlets'): # This means it hasn't had update() called yet. only do that once. viewlet_mgr.update() for viewlet in viewlet_mgr.viewlets: if hasattr(viewlet, 'validate'): self.errors.update(viewlet.validate()) if self.errors: # XXX let's raise something instead of returning. # it's ugly to overload function return values to signal errors. return self.errors for viewlet in viewlet_mgr.viewlets: if hasattr(viewlet, 'save'): viewlet.save() mem = factory.create(self.request.form) mem_name = mem.getFullname() or mem.getId() url = self._confirmation_url(mem) if utils.email_confirmation(): if not confirmed: self._send_mail_to_pending_user(user_name=mem_name, email=self.request.get('email'), url=url) self.addPortalStatusMessage(_(u'psm_thankyou_for_joining', u'Thanks for joining ${portal_title}, ${mem_id}!<br/>\nA confirmation email has been sent to you with instructions on activating your account.', mapping={u'mem_id':mem.getId(), u'portal_title':self.portal_title()})) portal_url = getToolByName(self.context, 'portal_url')() self.redirect(portal_url + '/message') return mem self.redirect(url) return mem
def do_nonmember_invitation_email(self, addy, proj_id): # perform invitation key = self.invite_util.addInvitation(addy, proj_id) msg_subs = dict(join_url=self.join_url(addy, key, proj_id), #FIXME: spam-check this user_message=self.request.get('message', ''), subject=self.request.get('subject', ''), project_title=self.context.Title(), project_noun=self.project_noun, site_contact_url=self.portal.absolute_url() + "/contact-site-admin", ) if email_confirmation(): _email_sender(self).sendMail( addy, msg=mship_messages.email_invite_static_body, mfrom=self.loggedinmember.id, **msg_subs) else: msg = _email_sender(self).constructMailMessage( mship_messages.email_invite_static_body, **msg_subs) log.info(msg) return key
def _add_email_invites(self, invites): """ Invite non-site-members to join the site and this project. Sends an email to the address, records the action so they'll be automatically added to this project upon joining the site. If the email address is already that of a site member, then that member will be invited to join the project, as per usual. Email addresses are in the 'email-invites' form field. If any of them fail validation as an email address then an error is returned and the entire operation is aborted. """ bad = self.validate_email_invites(invites) if bad: plural = len(bad) != 1 try: psm = (u"Poorly formed email address%s, please correct: %s" % (plural and 'es' or '', ', '.join(bad))) except UnicodeDecodeError: portal_url = getToolByName(self.context, 'portal_url')() contact_link = '<a href="%s/contact-site-admin">contact</a>' % portal_url psm = (u"An invalid email address was entered. If you believe this is incorrect, please %s us" % contact_link) self.add_status_message(psm) return # don't do anything, just re-render the form proj_id = self.context.getId() proj_title = self.context.title mbtool = self.membranetool uSR = mbtool.unrestrictedSearchResults mem_invites = [] mem_failures = [] mem_already_member = [] email_invites = [] already_invited = [] for addy in invites: # first check to see if we're already a site member addy = addy.strip() if not addy: continue match = uSR(getEmail=addy) if match: # member already has this address brain = match[0] mem_id = brain.getId invited = self._doInviteMember(mem_id) if invited: acct_url = self._getAccountURLForMember(mem_id) logged_in_mem = self.loggedinmember logged_in_mem_name = logged_in_mem.getFullname() or logged_in_mem.id mdtool = getToolByName(self.context, 'portal_memberdata') mdtoolpath = '/'.join(mdtool.getPhysicalPath()) mem_path = '%s/%s' % (mdtoolpath, mem_id) mem_metadata = self.catalog.getMetadataForUID(mem_path) mem_user_name = mem_metadata['getFullname'] or mem_metadata['id'] msg_subs = { 'project_title': proj_title, 'account_url': acct_url, 'user_name': mem_user_name, 'inviter_name': logged_in_mem_name, 'portal_name': self.portal.title, 'portal_url': self.portal.absolute_url(), } if email_confirmation(): if mem_metadata['review_state'] == 'pending': mem = mdtool.get(mem_id) msg_subs['conf_url'] = self._confirmation_url(mem) _email_sender(self).sendMail( mem_id, msg=mship_messages.invite_pending_member, subject=mship_messages.invite_pending_member_subject, **msg_subs) else: _email_sender(self).sendMail( mem_id, msg=mship_messages.invite_member, subject=mship_messages.invite_member_subject, **msg_subs) mem_invites.append(mem_id) else: # invitation attempt failed if mem_id not in self.context.projectMemberIds(): mem_failures.append(mem_id) else: mem_already_member.append(mem_id) else: # not a member if addy in self.invite_util.getInvitesByProject(proj_id): already_invited.append(addy) else: self.do_nonmember_invitation_email(addy, proj_id) email_invites.append(addy) return dict(mem_invites=mem_invites, mem_failures=mem_failures, email_invites=email_invites, already_invited=already_invited, mem_already_member=mem_already_member)