def __call__(self, **kwargs): self.identity_current_user = api.user.get_current() self.email = self.identity_current_user.getProperty('email') self.came_from = self.request.cookies.get( "login_came_from", self.request.form.get('came_from', None) ) if not self.came_from: self.came_from = self.context.absolute_url() self.membrane_type, self.membrane_role, self.use_uuid_as_userid = \ self.membrane_settings try: self.userID = self.getUserId(True) except AttributeError: IStatusMessage(self.request).addStatusMessage( _(u"Please note, only non-superusers are allowed to have " u"a profile on this site"), "error" ) self.request.response.redirect(self.came_from) return self.providers = utils.getProvidersForUser(self.identity_current_user) self.membranes = get_brains_for_email(self.context, self.email) logger.info("Redirecting to {}".format(self.came_from)) if len(self.membranes) > 0: self.apply_identity_membrane() return return super(MemberRegistrationForm, self).__call__(**kwargs)
def render(self): sfconn = getUtility(ISalesforceUtility).get_connection() soql = "select Id, Email from Contact where Online_Fundraising_User__c = True" # FIXME: Handle paginated query in case the number of contacts is > 200 res = sfconn.query(soql) num_person_updated = 0 num_member_updated = 0 num_skipped = 0 mtool = getToolByName(self.context, 'portal_membership') for contact in res['records']: person_res = get_brains_for_email(self.context, contact['Email']) if not person_res: num_skipped += 1 continue person = person_res[0].getObject() if person.sf_object_id != contact['Id']: num_person_updated += 1 person.sf_object_id = contact['Id'] person.reindexObject(idxs=['sf_object_id']) member = mtool.getMemberById(person.email) if not member: continue if member.getProperty('sf_object_id') != person.sf_object_id: num_member_updated = 0 member.setMemberProperties( {'sf_object_id': person.sf_object_id}) return "Updated %s Person objects, %s Member objects, and skipped %s non-existing Contacts" % (num_person_updated, num_member_updated, num_skipped)
def render(self): sfconn = getUtility(ISalesforceUtility).get_connection() soql = "select Id, Email from Contact where Online_Fundraising_User__c = True" # FIXME: Handle paginated query in case the number of contacts is > 200 res = sfconn.query(soql) num_person_updated = 0 num_member_updated = 0 num_skipped = 0 mtool = getToolByName(self.context, 'portal_membership') for contact in res['records']: person_res = get_brains_for_email(self.context, contact['Email']) if not person_res: num_skipped += 1 continue person = person_res[0].getObject() if person.sf_object_id != contact['Id']: num_person_updated += 1 person.sf_object_id = contact['Id'] person.reindexObject(idxs=['sf_object_id']) member = mtool.getMemberById(person.email) if not member: continue if member.getProperty('sf_object_id') != person.sf_object_id: num_member_updated = 0 member.setMemberProperties({'sf_object_id': person.sf_object_id}) return "Updated %s Person objects, %s Member objects, and skipped %s non-existing Contacts" % (num_person_updated, num_member_updated, num_skipped)
def handleOk(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return email = data['email'] site = getSite() membership = getToolByName(site, 'portal_membership') member = membership.getMemberById(email) # Like mailPassword() in CMFPlone.RegistrationTool, render # and send the message ourselves to avoid tripping over security. reset_tool = getToolByName(site, 'portal_password_reset') reset = reset_tool.requestReset(member.getId()) encoding = site.getProperty('email_charset', 'utf-8') mail_text = site.mail_password_template(site, self.request, member=member, reset=reset, password=member.getPassword(), charset=encoding) # The mail headers are not properly encoded, so we need to extract # them and let MailHost manage the encoding. if isinstance(mail_text, unicode): mail_text = mail_text.encode(encoding) message_obj = message_from_string(mail_text.strip()) subject = message_obj['Subject'] m_to = message_obj['To'] m_from = message_obj['From'] host = getToolByName(site, 'MailHost') host.send(mail_text, m_to, m_from, subject=subject, charset=encoding, immediate=False) brains = get_brains_for_email(site, email) if brains is not None: person = brains[0].getObject() # person.registered must be set in order for the user # to log in with a password. person.registered = True self.request.response.redirect(self.context.absolute_url() + '/mail_password_response')
def person(self): """provide access to the logged-in user """ if self._person and self._person is not _marker: return self._person mtool = getToolByName(self.context, 'portal_membership') if mtool.isAnonymousUser(): self._person = None return self._person member = mtool.getAuthenticatedMember() res = get_brains_for_email(self.context, member.id) if not res: return self._person self._person = res[0].getObject() return self._person
def validateEmail(value): site = getSite() res = get_brains_for_email(site, value) if not res: raise Invalid(_(u"No existing user account found to set password. Please use the registration form to create an account.")) # Auto log in the user # NOTE: This is to allow the current anon user access to the user profile. If there is an error, you MUST log the user out before raising an exception mtool = getToolByName(site, 'portal_membership') acl = getToolByName(site, 'acl_users') newSecurityManager(None, acl.getUser(value)) mtool.loginUser() person = res[0].getObject() if person.registered == True: mtool.logoutUser() raise Invalid(_(u"This account already has a password set. If you have forgotten the password, please use the forgot password link to reset your password."))
def handleOk(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return email = data['email'] site = getSite() membership = getToolByName(site, 'portal_membership') member = membership.getMemberById(email) # Like mailPassword() in CMFPlone.RegistrationTool, render # and send the message ourselves to avoid tripping over security. reset_tool = getToolByName(site, 'portal_password_reset') reset = reset_tool.requestReset(member.getId()) encoding = site.getProperty('email_charset', 'utf-8') mail_text = site.mail_password_template( site, self.request, member=member, reset=reset, password=member.getPassword(), charset=encoding) # The mail headers are not properly encoded, so we need to extract # them and let MailHost manage the encoding. if isinstance(mail_text, unicode): mail_text = mail_text.encode(encoding) message_obj = message_from_string(mail_text.strip()) subject = message_obj['Subject'] m_to = message_obj['To'] m_from = message_obj['From'] host = getToolByName(site, 'MailHost') host.send(mail_text, m_to, m_from, subject=subject, charset=encoding, immediate=False) brains = get_brains_for_email(site, email) if brains is not None: person = brains[0].getObject() # person.registered must be set in order for the user # to log in with a password. person.registered = True self.request.response.redirect( self.context.absolute_url() + '/mail_password_response')
def validateEmail(value): site = getSite() res = get_brains_for_email(site, value) if res: membership = getToolByName(site, 'portal_membership') member = membership.getMemberById(value) else: member = None if member is None: raise Invalid(_(u"No existing user account found to set password. " " Please use the registration form to create an" "account.")) person = res[0].getObject() if person.registered: raise Invalid(_(u"This account already has a password set. If you " "have forgotten the password, please use the forgot " "password link to reset your password."))
def validateEmail(value): site = getSite() res = get_brains_for_email(site, value) if res: membership = getToolByName(site, 'portal_membership') member = membership.getMemberById(value) else: member = None if member is None: raise Invalid( _(u"No existing user account found to set password. " " Please use the registration form to create an" "account.")) person = res[0].getObject() if person.registered: raise Invalid( _(u"This account already has a password set. If you " "have forgotten the password, please use the forgot " "password link to reset your password."))
def handleOk(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return # NOTE: The validator on email should have already checked if the password can be set and auto logged the user in res = get_brains_for_email(self.context, data['email'], self.request) person = res[0].getObject() person.password = pw_encrypt(data['password']) person.registered = True # See if came_from was passed # fix odd bug where came_from is a list of two values came_from = data.get('came_from', None) if came_from and isinstance(came_from, (list, tuple)): came_from = came_from[0] self.request.form['came_from'] = came_from # merge in with standard plone login process. login_next = self.context.restrictedTraverse('login_next') login_next()
def get_user_category(self, email): """ Returns either registered, social, donor_only, or None """ res = get_brains_for_email(self.context, email) if not res: return None mtool = getToolByName(self.context, 'portal_membership') acl = getToolByName(self.context, 'acl_users') newSecurityManager(None, acl.getUser(email)) mtool.loginUser() category = 'donor_only' person = res[0].getObject() if person.social_signin: category = 'social' if person.registered: category = 'registered' mtool.logoutUser() return category
def render(self): # Get the api key from registry settings = get_settings() # workaround for http://bugs.python.org/issue5285, # map unicode to strings janrain_api_key = str(settings.janrain_api_key) if not janrain_api_key: return 'No Janrain API key configured' # Get the token token = self.request.form.get('token', None) if not token: return 'No token passed in request' # Get the user profile from Janrain auth_info_url = '%s/auth_info?apiKey=%s&token=%s' % ( JANRAIN_API_BASE_URL, janrain_api_key, token, ) if settings.janrain_use_extended_profile: auth_info_url = auth_info_url + '&extended=true' resp = urllib2.urlopen(auth_info_url) auth_info = simplejson.loads(resp.read()) # This is for Plone's built in member management instead of membrane # See if a user already exists for the profile's email # email = auth_info['profile']['email'] # member = None # if email: # member = mtool.getMemberById(email) # See if user already exists using dexterity.membrane profile = auth_info.get('profile', {}) email = profile.get('verifiedEmail', None) # NB: Do NOT accept the 'email' attribute as an alternative # to 'verifiedEmail'. The 'email' attribute can be entered by # users and therefore would be a security hole. if not email: raise AttributeError( 'No email provided from social profile, unable to create ' 'account') email = email.lower() res = get_brains_for_email(self.context, email, self.request) if not res: # create new Person if no existing Person was found # with the same email name = profile.get('name', {}) address = profile.get('address', {}) if not address: addresses = profile.get('addresses', []) if addresses: address = addresses[0] data = { 'first_name': name.get('givenName', None), 'last_name': name.get('familyName', None), 'email': email, 'street_address': address.get('streetAddress', None), 'city': address.get('locality', None), 'state': address.get('region', None), 'zip': address.get('postalCode', None), 'country': address.get('country', None), # 'gender': profile.get('gender', None), 'social_signin': True, } # Create the user people_container = getattr(getSite(), 'people') person = createContentInContainer( people_container, 'collective.salesforce.fundraising.person', checkConstraints=False, **data) # Authenticate the user mtool = getToolByName(self.context, 'portal_membership') acl = getToolByName(self.context, 'acl_users') newSecurityManager(None, acl.getUser(email)) mtool.loginUser() # or use the existing Person if found else: # Authenticate the user mtool = getToolByName(self.context, 'portal_membership') acl = getToolByName(self.context, 'acl_users') newSecurityManager(None, acl.getUser(email)) mtool.loginUser() person = res[0].getObject() if not person.social_signin: person.social_signin = True # Set the photo photo = profile.get('photo', None) if not photo: photos = profile.get('photos', []) if photos: photo = photos[0] if photo and (not person.portrait or not person.portrait.size): img_data = urllib2.urlopen(photo).read() person.portrait = NamedBlobImage(img_data) # See if came_from was passed came_from = self.request.form.get('came_from', None) # fix odd bug where came_from is a list of two values if came_from and isinstance(came_from, (list, tuple)): came_from = came_from[0] if came_from: return self.request.response.redirect(came_from) # merge in with standard plone login process. login_next = self.context.restrictedTraverse('login_next') login_next()
def handleApply(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return if not self.identity_current_user: IStatusMessage(self.request).addStatusMessage( _(u"Please login before continuing"), "error" ) contextURL = "{}/login".format(self.context.absolute_url()) self.request.response.redirect(contextURL) return "redirecting" password = data.get("password") success = True if not self.membranes: first_name = data.get("first_name") last_name = data.get("last_name") self.email = data.get('email', self.email) name = "{}-{}".format( first_name, last_name ) if not first_name or not last_name: fullname = self.identity_current_user.getProperty('fullname') if not fullname: first_name = self.email.split("@")[0] last_name = "" name = first_name else: fullname = fullname.split(' ') first_name = fullname[0] last_name = fullname[-1] name = "{}-{}".format( first_name, last_name ) with api.env.adopt_roles('Manager'): context = api.content.get(path='/profiles') base_path = 'profiles/' if not context: context = self.context base_path = '' if not self.use_uuid_as_userid: name = self.userID try: user_profile = api.content.create( type=self.membrane_type, container=context, id=name, first_name=first_name, last_name=last_name, email=self.email, password=password, safe_id=True, **{ "_plone.uuid": self.getUserId() } ) api.content.transition( user_profile, transition='approve' ) api.user.grant_roles( user=self.identity_current_user, roles=tuple(set(('Member', self.membrane_role))) ) self.membranes = \ get_brains_for_email(self.context, self.email) except: success = False if success: self.apply_identity_membrane() else: IStatusMessage(self.request).addStatusMessage( _(u"Something went wrong"), "error" )
def has_membrane(self): current_user = api.user.get_current() email = current_user.getProperty('email') membranes = get_brains_for_email(self.context, self.email) return len(membranes) > 0
def render(self): # Get the api key from registry settings = get_settings() # workaround for http://bugs.python.org/issue5285, # map unicode to strings janrain_api_key = str(settings.janrain_api_key) if not janrain_api_key: return "No Janrain API key configured" # Get the token token = self.request.form.get("token", None) if not token: return "No token passed in request" # Get the user profile from Janrain auth_info_url = "%s/auth_info?apiKey=%s&token=%s" % (JANRAIN_API_BASE_URL, janrain_api_key, token) if settings.janrain_use_extended_profile: auth_info_url = auth_info_url + "&extended=true" resp = urllib2.urlopen(auth_info_url) auth_info = simplejson.loads(resp.read()) # This is for Plone's built in member management instead of membrane # See if a user already exists for the profile's email # email = auth_info['profile']['email'] # member = None # if email: # member = mtool.getMemberById(email) # See if user already exists using dexterity.membrane profile = auth_info.get("profile", {}) email = profile.get("verifiedEmail", None) # NB: Do NOT accept the 'email' attribute as an alternative # to 'verifiedEmail'. The 'email' attribute can be entered by # users and therefore would be a security hole. if not email: raise AttributeError("No email provided from social profile, unable to create " "account") email = email.lower() res = get_brains_for_email(self.context, email, self.request) if not res: # create new Person if no existing Person was found # with the same email name = profile.get("name", {}) address = profile.get("address", {}) if not address: addresses = profile.get("addresses", []) if addresses: address = addresses[0] data = { "first_name": name.get("givenName", None), "last_name": name.get("familyName", None), "email": email, "street_address": address.get("streetAddress", None), "city": address.get("locality", None), "state": address.get("region", None), "zip": address.get("postalCode", None), "country": address.get("country", None), # 'gender': profile.get('gender', None), "social_signin": True, } # Create the user people_container = getattr(getSite(), "people") person = createContentInContainer( people_container, "collective.salesforce.fundraising.person", checkConstraints=False, **data ) # Authenticate the user mtool = getToolByName(self.context, "portal_membership") acl = getToolByName(self.context, "acl_users") newSecurityManager(None, acl.getUser(email)) mtool.loginUser() # or use the existing Person if found else: # Authenticate the user mtool = getToolByName(self.context, "portal_membership") acl = getToolByName(self.context, "acl_users") newSecurityManager(None, acl.getUser(email)) mtool.loginUser() person = res[0].getObject() if not person.social_signin: person.social_signin = True # Set the photo photo = profile.get("photo", None) if not photo: photos = profile.get("photos", []) if photos: photo = photos[0] if photo and (not person.portrait or not person.portrait.size): img_data = urllib2.urlopen(photo).read() person.portrait = NamedBlobImage(img_data) # See if came_from was passed came_from = self.request.form.get("came_from", None) # fix odd bug where came_from is a list of two values if came_from and isinstance(came_from, (list, tuple)): came_from = came_from[0] if came_from: return self.request.response.redirect(came_from) # merge in with standard plone login process. login_next = self.context.restrictedTraverse("login_next") login_next()
def handleOk(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return # Don't allow creation of a personal page if one already exists existing_personal_campaign = \ self.context.get_personal_fundraising_campaign_url() if existing_personal_campaign: messages = IStatusMessage(self.request) messages.add("You can't create more than one " "personal page per campaign.") self.request.response.redirect(self.context.absolute_url()) return # Add a personal campaign within the current context, # using the data from the form. parent_campaign = self.context campaign = createContentInContainer( parent_campaign, 'collective.salesforce.fundraising.personalcampaignpage', checkConstraints=False, **data) mtool = getToolByName(self.context, 'portal_membership') member = mtool.getAuthenticatedMember() person_res = get_brains_for_email(self.context, member.getProperty('email')) person = None contact_id = None if person_res: person = person_res[0].getObject() contact_id = person.sf_object_id settings = get_settings() # Add the campaign in Salesforce sfconn = getUtility(ISalesforceUtility).get_connection() data = { 'Type': 'Personal Fundraising', 'ParentId': parent_campaign.sf_object_id, 'Name': data['title'], 'Description': data['description'], 'Public_Name__c': data['title'], 'ExpectedRevenue': data['goal'], 'Personal_Campaign_Contact__c': contact_id, 'IsActive': True, 'Status': 'In Progress', } if settings.sf_campaign_record_type_personal: data['RecordTypeID'] = settings.sf_campaign_record_type_personal res = sfconn.Campaign.create(data) if not res['success']: raise Exception(res['errors'][0]) # Save the Id of the new campaign so it can be updated later. campaign.parent_sf_id = parent_campaign.sf_object_id campaign.sf_object_id = res['id'] campaign.contact_sf_id = contact_id campaign.reindexObject() # Send email confirmation and links. try: campaign.send_email_personal_page_created() except HTTPRequestException as e: failure = { 'func_name': 'MemorialEmailView', 'func': '', 'args': '', 'kwargs': '', 'portal_path': '', 'context_path': repr(self.context), 'userfolder_path': '', 'user_id': '', 'tb': e, } email_failure_from_portal(self.context, failure) # Send the user to their new campaign. IStatusMessage(self.request).add(u'Welcome to your fundraising page!') self.request.response.redirect(campaign.absolute_url())
def handleOk(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return # Don't allow creation of a personal page if one already exists existing_personal_campaign = \ self.context.get_personal_fundraising_campaign_url() if existing_personal_campaign: messages = IStatusMessage(self.request) messages.add("You can't create more than one " "personal page per campaign.") self.request.response.redirect(self.context.absolute_url()) return # Add a personal campaign within the current context, # using the data from the form. parent_campaign = self.context campaign = createContentInContainer( parent_campaign, 'collective.salesforce.fundraising.personalcampaignpage', checkConstraints=False, **data ) mtool = getToolByName(self.context, 'portal_membership') member = mtool.getAuthenticatedMember() person_res = get_brains_for_email( self.context, member.getProperty('email') ) person = None contact_id = None if person_res: person = person_res[0].getObject() contact_id = person.sf_object_id settings = get_settings() # Add the campaign in Salesforce sfconn = getUtility(ISalesforceUtility).get_connection() data = { 'Type': 'Personal Fundraising', 'ParentId': parent_campaign.sf_object_id, 'Name': data['title'], 'Description': data['description'], 'Public_Name__c': data['title'], 'ExpectedRevenue': data['goal'], 'Personal_Campaign_Contact__c': contact_id, 'IsActive': True, 'Status': 'In Progress', } if settings.sf_campaign_record_type_personal: data['RecordTypeID'] = settings.sf_campaign_record_type_personal res = sfconn.Campaign.create(data) if not res['success']: raise Exception(res['errors'][0]) # Save the Id of the new campaign so it can be updated later. campaign.parent_sf_id = parent_campaign.sf_object_id campaign.sf_object_id = res['id'] campaign.contact_sf_id = contact_id campaign.reindexObject() # Send email confirmation and links. try: campaign.send_email_personal_page_created() except HTTPRequestException as e: failure = { 'func_name': 'MemorialEmailView', 'func': '', 'args': '', 'kwargs': '', 'portal_path': '', 'context_path': repr(self.context), 'userfolder_path': '', 'user_id': '', 'tb': e, } email_failure_from_portal(self.context, failure) # Send the user to their new campaign. IStatusMessage(self.request).add(u'Welcome to your fundraising page!') self.request.response.redirect(campaign.absolute_url())
def render(self): # Get the api key from registry settings = get_settings() # workaround for http://bugs.python.org/issue5285, map unicode to strings janrain_api_key = str(settings.janrain_api_key) if not janrain_api_key: return 'No Janrain API key configured' # Get the token token = self.request.form.get('token', None) if not token: return 'No token passed in request' # Get the user profile from Janrain auth_info_url = '%s/auth_info?apiKey=%s&token=%s' % ( JANRAIN_API_BASE_URL, janrain_api_key, token, ) if settings.janrain_use_extended_profile: auth_info_url = auth_info_url + '&extended=true' resp = urllib2.urlopen(auth_info_url) auth_info = simplejson.loads(resp.read()) # This is for Plone's built in member management instead of membrane # See if a user already exists for the profile's email #email = auth_info['profile']['email'] #member = None #if email: #member = mtool.getMemberById(email) # See if user already exists using dexterity.membrane profile = auth_info.get('profile',{}) email = profile.get('verifiedEmail', None) if not email: email = profile.get('email', None) if not email: raise AttributeError('No email provided from social profile, unable to create account') email = email.lower() res = get_brains_for_email(self.context, email, self.request) if not res: # create new Person if no existing Person was found with the same email name = profile.get('name',{}) address = profile.get('address',{}) if not address: addresses = profile.get('addresses', []) if addresses: address = addresses[0] data = { 'first_name': name.get('givenName', None), 'last_name': name.get('familyName', None), 'email': email, 'street_address': address.get('streetAddress', None), 'city': address.get('locality', None), 'state': address.get('region', None), 'zip': address.get('postalCode', None), 'country': address.get('country', None), #'gender': profile.get('gender', None), 'social_signin': True, } # Create the user people_container = getattr(getSite(), 'people') person = createContentInContainer( people_container, 'collective.salesforce.fundraising.person', checkConstraints=False, **data ) # Authenticate the user mtool = getToolByName(self.context, 'portal_membership') acl = getToolByName(self.context, 'acl_users') newSecurityManager(None, acl.getUser(email)) mtool.loginUser() # or use the existing Person if found else: # Authenticate the user mtool = getToolByName(self.context, 'portal_membership') acl = getToolByName(self.context, 'acl_users') newSecurityManager(None, acl.getUser(email)) mtool.loginUser() person = res[0].getObject() if person.social_signin == False: person.social_signin = True # Set the photo photo = profile.get('photo', None) if not photo: photos = profile.get('photos',[]) if photos: photo = photos[0] if photo and (not person.portrait or not person.portrait.size): img_data = urllib2.urlopen(photo).read() person.portrait = NamedBlobImage(img_data) # See if came_from was passed came_from = self.request.form.get('came_from', None) # fix odd bug where came_from is a list of two values if came_from and isinstance(came_from, (list, tuple)): came_from = came_from[0] if came_from: return self.request.response.redirect(came_from) # merge in with standard plone login process. login_next = self.context.restrictedTraverse('login_next') login_next()