def setUpWidgets(self, ignore_request=False): message = _( 'request-message-default', 'Hello,\n\nI would like to join ${groupName}. I think I should be allowed to ' 'become a member because...', mapping={'groupName': self.groupInfo.name}) if self.userInfo.anonymous: fromAddr = '' else: emailUser = EmailUser(self.context, self.userInfo) addrs = emailUser.get_delivery_addresses() if addrs: fromAddr = addrs[0] else: fromAddr = '' data = {'message': translate(message), 'fromAddress': fromAddr} self.widgets = form.setUpWidgets(self.form_fields, self.prefix, self.context, self.request, form=self, data=data, ignore_request=ignore_request)
def __init__(self, userInfo, address): self.userInfo = userInfo self.addr = address.strip() eu = EmailUser(userInfo.user, userInfo) userAddrs = [l.lower() for l in eu.get_addresses()] assert address.lower() in userAddrs, '%s not in %s' % \ (address.lower(), userAddrs)
def get_addrs(self, toAddr): notifiedUser = IGSNotifyUser(self.userInfo) try: addrs = notifiedUser.get_addresses() except AssertionError: addrs = [toAddr.strip()] addrs = [a for a in addrs if a] ### BEGIN(hack) ### TODO: Remove this hack ### ### --=mpj17=-- UGLY HACK --=mpj17=-- ### ### Sometimes a person is invited who has an existing profile ### but all his or her email addresses are unverified. If this ### is the case we will send the invitation anyway. With **luck** ### the user will only have **one** (un, uno, I, 1) address, ### which will get verified when he or she joins. Otherwise the ### gs.profile.invite.initialresponse.InitialResponseForm may ### verify the **wrong** address. ### ### See <https://projects.iopen.net/groupserver/ticket/514> ### if not addrs: eu = EmailUser(self.context, self.userInfo) addrs = eu.get_addresses() ### END(hack) (* Modula-2 Geek *) assert type(addrs) == list,\ 'Returning a %s, rather than a list' % type(addrs) return addrs
def get_addrs(self, toAddr): notifiedUser = IGSNotifyUser(self.userInfo) try: addrs = notifiedUser.get_addresses() except AssertionError: addrs = [toAddr.strip()] addrs = [a for a in addrs if a] ### BEGIN(hack) ### TODO: Remove this hack ### ### --=mpj17=-- UGLY HACK --=mpj17=-- ### ### Sometimes a person is invited who has an existing profile ### but all his or her email addresses are unverified. If this ### is the case we will send the invitation anyway. With **luck** ### the user will only have **one** (un, uno, I, 1) address, ### which will get verified when he or she joins. Otherwise the ### gs.profile.invite.initialresponse.InitialResponseForm may ### verify the **wrong** address. ### ### See <https://projects.iopen.net/groupserver/ticket/514> ### if not addrs: eu = EmailUser(self.context, self.userInfo) addrs = eu.get_addresses() ### END(hack) (* Modula-2 Geek *) assert type(addrs) == list,\ 'Returning a %s, rather than a list' % type(addrs) return addrs
def bounceHistory(self): retval = {} query = BounceHistoryQuery(self.context) eu = EmailUser(self.context, self.userInfo) emailAddresses = eu.get_addresses() for email in emailAddresses: retval[email] = [self.munge_event(e) for e in query.bounce_events(email)] return retval
def subsetIds(self): retval = set() for uId in self.memberIds: userInfo = createObject('groupserver.UserFromId', self.group, uId) emailUser = EmailUser(self.group, userInfo) if emailUser.get_verified_addresses(): retval.add(userInfo.id) return retval
def subsetIds(self): retval = set() for uId in self.memberIds: userInfo = createObject('groupserver.UserFromId', self.group, uId) emailUser = EmailUser(self.group, userInfo) if emailUser.get_verified_addresses(): retval.add(userInfo.id) return retval
def verify_email_address(self): # There better be only one email address. emailUser = EmailUser(self.context, self.userInfo) email = emailUser.get_addresses()[0] # Assuming this will work ;) vid = '%s_accept' % self.invitationId eu = EmailVerificationUser(self.groupInfo.groupObj, self.userInfo, email) eu.add_verification_id(vid) eu.verify_email(vid)
def verify_email_address(self): # There better be only one email address. emailUser = EmailUser(self.context, self.userInfo) email = emailUser.get_addresses()[0] # Assuming this will work ;) vid = '%s_accept' % self.invitationId eu = EmailVerificationUser(self.groupInfo.groupObj, self.userInfo, email) eu.add_verification_id(vid) eu.verify_email(vid)
def get_unverified_group_users(context, groupId, excludeGroup=''): # AM: To be removed when the new Manage Members code is deployed # and the old admin pages removed. unverifiedUsers = [] group_users = get_group_users(context, groupId, excludeGroup) for u in group_users: eu = EmailUser(context, u) if not eu.get_verified_addresses(): unverifiedUsers.append(u) retval = unverifiedUsers assert type(retval) == list return retval
def get_unverified_group_users(context, groupId, excludeGroup=''): # AM: To be removed when the new Manage Members code is deployed # and the old admin pages removed. unverifiedUsers = [] group_users = get_group_users(context, groupId, excludeGroup) for u in group_users: eu = EmailUser(context, u) if not eu.get_verified_addresses(): unverifiedUsers.append(u) retval = unverifiedUsers assert type(retval) == list return retval
def __init__(self, context): self.context = context # the context we are passed might already be a userinfo if IGSUserInfo.providedBy(context): self.userInfo = context else: self.userInfo = createObject('groupserver.LoggedInUser', context) emailUser = EmailUser(self.userInfo.user, self.userInfo) defaultAddresses = emailUser.get_delivery_addresses() self.defaultAddress = '' if defaultAddresses: self.defaultAddress = defaultAddresses[0]
def __init__(self, context): self.context = context # the context we are passed might already be a userinfo if IGSUserInfo.providedBy(context): self.userInfo = context else: self.userInfo = createObject('groupserver.LoggedInUser', context) emailUser = EmailUser(self.userInfo.user, self.userInfo) defaultAddresses = emailUser.get_delivery_addresses() self.defaultAddress = '' if defaultAddresses: self.defaultAddress = defaultAddresses[0]
def create_user_from_email(context, email): if not context: m = 'Context is "{0}"'.format(context) raise ValueError(m) if type(email) not in (str, unicode): m = 'Email is a "{0}", not a string'.format(type(email)) raise TypeError(m) if not email: m = 'The email address is "{0}"'.format(email) raise ValueError(m) if '@' not in email: m = 'No "@" in the email "{0}"'.format(email) raise ValueError(m) m = 'utils.create_user_from_email: Creating a new user for the '\ 'address <%s>' % email log.info(m) userNum = long(new_md5(asctime() + email).hexdigest(), 16) userId = str(convert_int2b62(userNum)) # Ensure that the user ID is unique. There is also a race # condition, and the loop is non-deterministic. acl_users = __get_acl_users_for_context(context) while (acl_users.getUserById(userId)): userNum = long(new_md5(asctime() + email).hexdigest(), 16) userId = str(convert_int2b62(userNum)) displayName = email.split('@')[0] user = acl_users.simple_register_user(email, userId, displayName) userInfo = IGSUserInfo(user) emailUser = EmailUser(context, userInfo) emailUser.set_delivery(email) # --=mpj17=-- Ensure that the user's profile is owned by the user, and # *only* the user. p = '/'.join(acl_users.getPhysicalPath()).encode('ascii', 'ignore') assign_ownership(user, user.getId(), recursive=0, acl_user_path=p) user.manage_delLocalRoles( [uid for uid in user.users_with_local_role('Owner') if uid != userId]) m = 'utils.create_user_from_email: Created a new user {name} ({id})' msg = m.format(name=user.getProperty('fn', ''), id=user.getId()) log.info(msg) assert user assert isinstance(user, CustomUser) return user
def user_has_preferred_email_addresses(self): '''Does the user have at least one preferred (alias default delivery) email address to post. This is mostly a safety catch to ensure that the user has verified the email addresses. ''' emailUser = EmailUser(self.groupInfo.groupObj, self.userInfo) preferredEmailAddresses = emailUser.get_delivery_addresses() retval = len(preferredEmailAddresses) >= 1 if retval: self.__status = u'preferred email addresses' else: self.__status = u'no preferred email addresses' self.__statusNum = 4 assert type(self.__status) == unicode assert type(retval) == bool return retval
def unverifiedMembers(self): emailUsers = [EmailUser(self.context, m) for m in self.members] members = [ e.userInfo for e in emailUsers if not (e.get_verified_addresses()) ] retval = members return retval
def notify(self, adminInfo, userInfo): subject = _('new-member-subject', '${userName} has joined ${groupName}', mapping={ 'userName': userInfo.name, 'groupName': self.groupInfo.name }) translatedSubject = translate(subject) emailUser = EmailUser(userInfo.user, userInfo) text = self.textTemplate(adminInfo=adminInfo, userInfo=userInfo, userEmail=emailUser) html = self.htmlTemplate(adminInfo=adminInfo, userInfo=userInfo, userEmail=emailUser) ms = MessageSender(self.context, adminInfo) try: ms.send_message(translatedSubject, text, html) except ValueError: m = 'Could not send a "New member" notification to %s (%s) in the group %s (%s) on '\ '%s (%s) because they lack a verified email address. Skipping the notification.' log.warn(m, adminInfo.name, adminInfo.id, self.groupInfo.name, self.groupInfo.id, self.groupInfo.siteInfo.name, self.groupInfo.siteInfo.id) self.reset_content_type()
def user_has_preferred_email_addresses(self): '''Does the user have at least one preferred (alias default delivery) email address to post. This is mostly a safety catch to ensure that the user has verified the email addresses. ''' emailUser = EmailUser(self.groupInfo.groupObj, self.userInfo) preferredEmailAddresses = emailUser.get_delivery_addresses() retval = len(preferredEmailAddresses) >= 1 if retval: self.__status = u'preferred email addresses' else: self.__status = u'no preferred email addresses' self.__statusNum = 4 assert type(self.__status) == unicode assert type(retval) == bool return retval
def check(self): if not self.s['checked']: emailUser = EmailUser(self.groupInfo.groupObj, self.userInfo) preferredEmailAddresses = emailUser.get_delivery_addresses() if (len(preferredEmailAddresses) >= 1): self.s['canPost'] = True self.s['status'] = u'a person with working email address.' self.s['statusNum'] = 0 else: self.s['canPost'] = False self.s['status'] = u'no working email address.' self.s['statusNum'] = self.weight self.s['checked'] = True assert self.s['checked'] assert type(self.s['canPost']) == bool assert type(self.s['status']) == unicode assert type(self.s['statusNum']) == int
def check(self): if not self.s['checked']: emailUser = EmailUser(self.groupInfo.groupObj, self.userInfo) preferredEmailAddresses = emailUser.get_delivery_addresses() if (len(preferredEmailAddresses) >= 1): self.s['canPost'] = True self.s['status'] = u'a person with working email address.' self.s['statusNum'] = 0 else: self.s['canPost'] = False self.s['status'] = u'no working email address.' self.s['statusNum'] = self.weight self.s['checked'] = True assert self.s['checked'] assert type(self.s['canPost']) == bool assert type(self.s['status']) == unicode assert type(self.s['statusNum']) == int
def notify(self, userInfo): subject = _('welcome-subject', 'Welcome to ${groupName}', mapping={'groupName': self.groupInfo.name}) translatedSubject = translate(subject) emailUser = EmailUser(userInfo.user, userInfo) text = self.textTemplate(userInfo=userInfo, userEmail=emailUser) html = self.htmlTemplate(userInfo=userInfo, userEmail=emailUser) ms = MessageSender(self.context, userInfo) ms.send_message(translatedSubject, text, html) self.reset_content_type()
def setUpWidgets(self, ignore_request=False): message = _('request-message-default', 'Hello,\n\nI would like to join ${groupName}. I think I should be allowed to ' 'become a member because...', mapping={'groupName': self.groupInfo.name}) if self.userInfo.anonymous: fromAddr = '' else: emailUser = EmailUser(self.context, self.userInfo) addrs = emailUser.get_delivery_addresses() if addrs: fromAddr = addrs[0] else: fromAddr = '' data = {'message': translate(message), 'fromAddress': fromAddr} self.widgets = form.setUpWidgets( self.form_fields, self.prefix, self.context, self.request, form=self, data=data, ignore_request=ignore_request)
def setUpWidgets(self, ignore_request=True): self.adapters = {} if self.userInfo.anonymous: fromAddr = '' else: emailUser = EmailUser(self.context, self.userInfo) addrs = emailUser.get_delivery_addresses() if addrs: fromAddr = addrs[0] else: fromAddr = '' data = { 'fromAddress': fromAddr, 'message': '', 'inReplyTo': self.lastPostId, } self.widgets = form.setUpWidgets( self.form_fields, self.prefix, self.context, self.request, form=self, data=data, ignore_request=ignore_request) assert self.widgets
def nonMembers(self): '''Get the members of the current site that are not a member of the group, and who have an email address.''' # OPTIMIZE: This could *mostly* be done with lists of IDs retval = [ EmailUser(self.context, ui) for ui in self.siteMembers.members if ((not user_member_of_group(ui, self.groupInfo)) and self.has_addr(ui)) ] retval.sort(key=lambda eu: eu.userInfo.name) assert type(retval) == list return retval
def __call__(self, context, verificationId): queries = VerificationQuery() s = queries.verificationId_status(verificationId) if s == queries.NOT_FOUND: raise VerificationIdNotFoundError(verificationId) userId = queries.get_userId_from_verificationId(verificationId) aclUsers = context.site_root().acl_users user = aclUsers.getUser(userId) if not user: m = 'No user for the verification ID "{0}"' msg = m.format(verificationId) raise NoUserForVerificationId(msg) userInfo = IGSUserInfo(user) emailUser = EmailUser(context, userInfo) email = queries.get_email_from_verificationId(verificationId) assert email in emailUser.get_addresses(), \ 'Address %s does not belong to %s (%s)' %\ (email, userInfo.name, userInfo.id) return EmailVerificationUser(context, userInfo, email)
def __call__(self, context, verificationId): queries = VerificationQuery() s = queries.verificationId_status(verificationId) if s == queries.NOT_FOUND: raise VerificationIdNotFoundError(verificationId) userId = queries.get_userId_from_verificationId(verificationId) aclUsers = context.site_root().acl_users user = aclUsers.getUser(userId) if not user: m = 'No user for the verification ID "{0}"' msg = m.format(verificationId) raise NoUserForVerificationId(msg) userInfo = IGSUserInfo(user) emailUser = EmailUser(context, userInfo) email = queries.get_email_from_verificationId(verificationId) assert email in emailUser.get_addresses(), \ 'Address %s does not belong to %s (%s)' %\ (email, userInfo.name, userInfo.id) return EmailVerificationUser(context, userInfo, email)
def setUpWidgets(self, ignore_request=True): self.adapters = {} if self.userInfo.anonymous: fromAddr = '' else: emailUser = EmailUser(self.context, self.userInfo) addrs = emailUser.get_delivery_addresses() if addrs: fromAddr = addrs[0] else: fromAddr = '' data = { 'fromAddress': fromAddr, 'message': '', 'inReplyTo': self.lastPostId, } self.widgets = form.setUpWidgets(self.form_fields, self.prefix, self.context, self.request, form=self, data=data, ignore_request=ignore_request) assert self.widgets
class SetPasswordForm(SiteForm): form_fields = form.Fields(IGSSetPasswordRegister) label = _('set-password-label', 'Set password') pageTemplateFileName = 'browser/templates/setpassword.pt' template = ZopeTwoPageTemplateFile(pageTemplateFileName) def __init__(self, context, request): SiteForm.__init__(self, context, request) self.userInfo = GSUserInfo(context) self.emailUser = EmailUser(context, self.userInfo) @form.action(label=_('set-password-button', 'Set'), name='set', failure='handle_set_action_failure') def handle_set(self, action, data): assert self.context assert self.form_fields assert action assert data pu = IGSPasswordUser(self.userInfo) pu.set_password(data['password1']) userInfo = createObject('groupserver.LoggedInUser', self.context) uri = '%s/registration_profile.html' % userInfo.url cf = str(data.get('came_from')) if cf == 'None': cf = '' gid = str(data.get('groupId')) if gid == 'None': gid = '' uri = '%s?form.joinable_groups:list=%s&form.came_from=%s' %\ (uri, gid, cf) return self.request.RESPONSE.redirect(uri) def handle_set_action_failure(self, action, data, errors): if len(errors) == 1: s = _('single-error', 'There is an error:') else: s = _('multiple-errors', 'There are errors:') self.status = '<p>{0}</p>'.format(s) @property def userEmail(self): retval = self.emailUser.get_addresses() assert retval return retval
class SetPasswordForm(SiteForm): form_fields = form.Fields(IGSSetPasswordRegister) label = _('set-password-label', 'Set password') pageTemplateFileName = 'browser/templates/setpassword.pt' template = ZopeTwoPageTemplateFile(pageTemplateFileName) def __init__(self, context, request): SiteForm.__init__(self, context, request) self.userInfo = GSUserInfo(context) self.emailUser = EmailUser(context, self.userInfo) @form.action(label=_('set-password-button', 'Set'), name='set', failure='handle_set_action_failure') def handle_set(self, action, data): assert self.context assert self.form_fields assert action assert data pu = IGSPasswordUser(self.userInfo) pu.set_password(data['password1']) userInfo = createObject('groupserver.LoggedInUser', self.context) uri = '%s/registration_profile.html' % userInfo.url cf = str(data.get('came_from')) if cf == 'None': cf = '' gid = str(data.get('groupId')) if gid == 'None': gid = '' uri = '%s?form.joinable_groups:list=%s&form.came_from=%s' %\ (uri, gid, cf) return self.request.RESPONSE.redirect(uri) def handle_set_action_failure(self, action, data, errors): if len(errors) == 1: s = _('single-error', 'There is an error:') else: s = _('multiple-errors', 'There are errors:') self.status = '<p>{0}</p>'.format(s) @property def userEmail(self): retval = self.emailUser.get_addresses() assert retval return retval
def has_addr(self, ui): return bool(EmailUser(self.context, ui).get_delivery_addresses())
def __init__(self, context, request): SiteForm.__init__(self, context, request) self.userInfo = GSUserInfo(context) self.emailUser = EmailUser(context, self.userInfo)
def get_email_user(self, userId): ui = createObject('groupserver.UserFromId', self.context, userId) retval = EmailUser(self.context, ui) if not (ui.anonymous) else None return retval
def __init__(self, context, request): SiteForm.__init__(self, context, request) self.userInfo = GSUserInfo(context) self.emailUser = EmailUser(context, self.userInfo)
def emailUser(self): userInfo = IGSUserInfo(self.user) retval = EmailUser(self.user, userInfo) return retval
def emailUser(self): retval = EmailUser(self.context, self.toUserInfo) assert retval, 'Could not create the email-user' return retval
def hasEmail(self): eu = EmailUser(self.context, self.loggedInUser) retval = (len(eu.get_verified_addresses()) > 0) return retval
def emailUser(self): retval = EmailUser(self.context, self.userInfo) return retval
def emailUser(self): retval = EmailUser(self.ctx, self.userInfo) return retval
def userEmailInfo(self): # Used by some (E-Democracy.org) to allow group administrators to # contact or introduce new members. userInfo = self.loggedInUserInfo emailUser = EmailUser(userInfo.user, userInfo) return emailUser
def defaultFromEmail(self): emailUser = EmailUser(self.context, self.adminInfo) retval = emailUser.get_delivery_addresses()[0] return retval
def hasEmail(self): eu = EmailUser(self.context, self.loggedInUser) retval = (len(eu.get_verified_addresses()) > 0) return retval
def userEmailInfo(self): # possibly this should be called something like testUserEmailInfo, # because it is really only used in the test case userInfo = self.loggedInUserInfo emailUser = EmailUser(userInfo.user, userInfo) return emailUser
def __call__(self): if len(self.traverse_subpath) == 1: invitationId = self.traverse_subpath[0] if (invitationId == 'example'): userInfo = createObject('groupserver.LoggedInUser', self.ctx) ref = self.request.get('HTTP_REFERER', '') assert ref, 'This page only works if you follow the link '\ 'from the invitation preview.' path = urlparse(ref)[2] groupId = path.split('/')[2] uri = '%s/initial_response.html?form.invitationId=example&'\ 'form.groupId=%s' % (userInfo.url, groupId) else: # Not an example invitation = Invitation(self.ctx, invitationId) try: hadResponse = \ invitation.invite['response_date'] is not None invitationWithdrawn = \ invitation.invite['withdrawn_date'] is not None except KeyError: hadResponse = inviteExists = invitationWithdrawn = False else: inviteExists = True if inviteExists and hadResponse: uri = '/invitation-responded.html?form.invitationId=%s' %\ (invitationId) elif (inviteExists and not(hadResponse) and not(invitationWithdrawn)): assert not invitation.userInfo.anonymous,\ 'An invitation to an anonymous user. Let us '\ 'hope you are on a development platform where '\ 'such things happen, otherwise something has '\ 'gone seriously wrong and you should contact '\ 'support.' # --=mpj17=-- Only ever log in when responding login(self.ctx, invitation.userInfo.user) # I used to use the "initial_invite" column, but now # it is unused. emailUser = EmailUser(self.ctx, invitation.userInfo) initial = bool(emailUser.get_verified_addresses()) if not(initial): # Go to the initial response page, so # the new user can set a password (and verify # his or her email address). uri = '%s/initial_response.html?form.invitationId=%s' %\ (invitation.userInfo.url, invitationId) else: # If the user is already a member of a group # (any group on any site) then we should go to # the normal Response page. uri = '%s/invitations_respond.html' % \ (invitation.userInfo.url) elif inviteExists and invitationWithdrawn: # The invitation has been withdrawn uri = '/invitation-withdrawn.html?form.invitationId=%s' %\ (invitationId) else: # Invitation does not exist uri = '/invite-not-found.html?form.invitationId=%s' %\ (invitationId) else: # Verification ID not specified uri = '/invite-no-id.html' assert uri assert type(uri) == str return self.request.RESPONSE.redirect(uri)