def retrieve_voter_following_org_status(self, voter_id, voter_we_vote_id, organization_id, organization_we_vote_id): """ Retrieve one follow entry so we can see if a voter is following or ignoring a particular org """ if not positive_value_exists(voter_id) and positive_value_exists(voter_we_vote_id): # We need voter_id to call retrieve_follow_organization voter_manager = VoterManager() voter_id = voter_manager.fetch_local_id_from_we_vote_id(voter_we_vote_id) if not positive_value_exists(voter_id) and \ not (positive_value_exists(organization_id) or positive_value_exists(organization_we_vote_id)): results = { 'status': 'RETRIEVE_VOTER_FOLLOWING_MISSING_VARIABLES', 'success': False, 'follow_organization_found': False, 'follow_organization_id': 0, 'follow_organization': FollowOrganization(), 'is_following': False, 'is_not_following': True, 'is_ignoring': False, 'error_result': True, 'DoesNotExist': False, 'MultipleObjectsReturned': False, } return results return self.retrieve_follow_organization(0, voter_id, organization_id, organization_we_vote_id)
def retrieve_voter_following_org_status(self, voter_id, voter_we_vote_id, organization_id, organization_we_vote_id): """ Retrieve one follow entry so we can see if a voter is following or ignoring a particular org """ if not positive_value_exists(voter_id) and positive_value_exists( voter_we_vote_id): # We need voter_id to call retrieve_follow_organization voter_manager = VoterManager() voter_id = voter_manager.fetch_local_id_from_we_vote_id( voter_we_vote_id) if not positive_value_exists(voter_id) and \ not (positive_value_exists(organization_id) or positive_value_exists(organization_we_vote_id)): results = { 'status': 'RETRIEVE_VOTER_FOLLOWING_MISSING_VARIABLES', 'success': False, 'follow_organization_found': False, 'follow_organization_id': 0, 'follow_organization': FollowOrganization(), 'is_following': False, 'is_not_following': True, 'is_ignoring': False, 'error_result': True, 'DoesNotExist': False, 'MultipleObjectsReturned': False, } return results return self.retrieve_follow_organization(0, voter_id, organization_id, organization_we_vote_id)
def social_user(backend, uid, details, user=None, *args, **kwargs): voter_manager = VoterManager() provider = backend.name social = backend.strategy.storage.user.get_social_auth(provider, uid) if backend.name == 'twitter': # Twitter: Check to see if we have a voter with a matching twitter_id local_user_matches = user and user.twitter_id == uid else: local_user_matches = user and user.email != details.get('email') switch_user = not local_user_matches if switch_user: # Logout the current Django user logout(backend.strategy.request) user = None voter_that_matches_auth = None voter_found_that_matches_auth = False if social: if social.user: if backend.name == 'twitter': if social.user.twitter_id == uid: voter_that_matches_auth = social.user voter_found_that_matches_auth = True else: pass if not voter_found_that_matches_auth: # Find the voter account that actually matches this twitter_id results = voter_manager.retrieve_voter_by_twitter_id(uid) if results['voter_found']: voter_that_matches_auth = results['voter'] voter_found_that_matches_auth = True if voter_found_that_matches_auth: user = voter_that_matches_auth else: # No other account matches this, so we want to save basic information in social.user if backend.name == 'twitter': if social and social.user: twitter_user_dict = { 'id': uid, 'profile_image_url_https': kwargs['response']['profile_image_url_https'], 'screen_name': kwargs['response']['screen_name'] } results = voter_manager.save_twitter_user_values_from_dict(social.user, twitter_user_dict) if results['success']: social.user = results['voter'] user = results['voter'] return {'social': social, 'user': user, 'is_new': user is None, 'switch_user': True, 'new_association': False}
def voter_create(voter_device_id): results = is_voter_device_id_valid(voter_device_id) if not results['success']: return HttpResponse(json.dumps(results['json_data']), content_type='application/json') voter_id = 0 # Make sure a voter record hasn't already been created for this existing_voter_id = fetch_voter_id_from_voter_device_link(voter_device_id) if existing_voter_id: json_data = { 'status': "VOTER_ALREADY_EXISTS", 'success': False, 'voter_device_id': voter_device_id, } return HttpResponse(json.dumps(json_data), content_type='application/json') # Create a new voter and return the id voter_manager = VoterManager() results = voter_manager.create_voter() if results['voter_created']: voter = results['voter'] # Now save the voter_device_link voter_device_link_manager = VoterDeviceLinkManager() results = voter_device_link_manager.save_new_voter_device_link( voter_device_id, voter.id) if results['voter_device_link_created']: voter_device_link = results['voter_device_link'] voter_id_found = True if voter_device_link.voter_id > 0 else False if voter_id_found: voter_id = voter_device_link.voter_id if voter_id: json_data = { 'status': "VOTER_CREATED", 'success': False, 'voter_device_id': voter_device_id, 'voter_id': voter_id, # We may want to remove this after initial testing } return HttpResponse(json.dumps(json_data), content_type='application/json') else: json_data = { 'status': "VOTER_NOT_CREATED", 'success': False, 'voter_device_id': voter_device_id, } return HttpResponse(json.dumps(json_data), content_type='application/json')
def process_sign_in_response_view(request): oauth_token = request.GET.get('oauth_token', '') oauth_verifier = request.GET.get('oauth_verifier', '') if not positive_value_exists(oauth_token) or not positive_value_exists(oauth_verifier): # Redirect back to ReactJS so we can display failure message return HttpResponseRedirect('http://localhost:3001/twitter/missing_variables') # TODO Convert to env variable voter_manager = VoterManager() # Look in the Voter table for a matching request_token, placed by the API endpoint twitterSignInStart results = voter_manager.retrieve_voter_by_twitter_request_token(oauth_token) if not results['voter_found']: # Redirect back to ReactJS so we can display failure message if the token wasn't found return HttpResponseRedirect('http://localhost:3001/twitter/token_missing') # TODO Convert to env variable voter = results['voter'] # Fetch the access token try: # Set up a tweepy auth handler auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) auth.request_token = {'oauth_token': voter.twitter_request_token, 'oauth_token_secret': voter.twitter_request_secret} auth.get_access_token(oauth_verifier) if not positive_value_exists(auth.access_token) or not positive_value_exists(auth.access_token_secret): # Redirect back with error return HttpResponseRedirect('http://localhost:3001/twitter/access_token_missing') # TODO Convert to env var voter.twitter_access_token = auth.access_token voter.twitter_access_secret = auth.access_token_secret voter.save() # Next use the access_token and access_secret to retrieve Twitter user info api = tweepy.API(auth) tweepy_user_object = api.me() voter_manager.save_twitter_user_values(voter, tweepy_user_object) except tweepy.RateLimitError: success = False status = 'TWITTER_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = '' error_tuple = error_instance.args for error_dict in error_tuple: for one_error in error_dict: status += '[' + one_error['message'] + '] ' # Redirect back, success return HttpResponseRedirect('http://localhost:3001/ballot') # TODO Convert to env var
def authenticate_associate_by_email(**kwargs): try: # Find the voter account that actually matches this twitter_id twitter_id = kwargs['uid'] voter_manager = VoterManager() results = voter_manager.retrieve_voter_by_twitter_id(twitter_id) if results['voter_found']: kwargs['user'] = results['voter'] else: kwargs['user'] = None except: pass return kwargs
def voter_create(voter_device_id): results = is_voter_device_id_valid(voter_device_id) if not results['success']: return HttpResponse(json.dumps(results['json_data']), content_type='application/json') voter_id = 0 # Make sure a voter record hasn't already been created for this existing_voter_id = fetch_voter_id_from_voter_device_link(voter_device_id) if existing_voter_id: json_data = { 'status': "VOTER_ALREADY_EXISTS", 'success': False, 'voter_device_id': voter_device_id, } return HttpResponse(json.dumps(json_data), content_type='application/json') # Create a new voter and return the id voter_manager = VoterManager() results = voter_manager.create_voter() if results['voter_created']: voter = results['voter'] # Now save the voter_device_link voter_device_link_manager = VoterDeviceLinkManager() results = voter_device_link_manager.save_new_voter_device_link(voter_device_id, voter.id) if results['voter_device_link_created']: voter_device_link = results['voter_device_link'] voter_id_found = True if voter_device_link.voter_id > 0 else False if voter_id_found: voter_id = voter_device_link.voter_id if voter_id: json_data = { 'status': "VOTER_CREATED", 'success': False, 'voter_device_id': voter_device_id, 'voter_id': voter_id, # We may want to remove this after initial testing } return HttpResponse(json.dumps(json_data), content_type='application/json') else: json_data = { 'status': "VOTER_NOT_CREATED", 'success': False, 'voter_device_id': voter_device_id, } return HttpResponse(json.dumps(json_data), content_type='application/json')
def facebook_disconnect_for_api(voter_device_id): # facebookDisconnect """ :param voter_device_id: :return: """ # Get voter_id from the voter_device_id results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id( voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'success': False, 'status': "VALID_VOTER_MISSING", 'voter_device_id': voter_device_id, } return results voter = results['voter'] facebook_id = 0 results = voter_manager.save_facebook_user_values(voter, facebook_id) status = results['status'] success = results['success'] if success: results = { 'success': True, 'status': status, 'voter_device_id': voter_device_id, } else: results = { 'success': False, 'status': status, 'voter_device_id': voter_device_id, } return results
def facebook_disconnect_for_api(voter_device_id): # facebookDisconnect """ :param voter_device_id: :return: """ # Get voter_id from the voter_device_id results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'success': False, 'status': "VALID_VOTER_MISSING", 'voter_device_id': voter_device_id, } return results voter = results['voter'] facebook_id = 0 results = voter_manager.save_facebook_user_values(voter, facebook_id) status = results['status'] success = results['success'] if success: results = { 'success': True, 'status': status, 'voter_device_id': voter_device_id, } else: results = { 'success': False, 'status': status, 'voter_device_id': voter_device_id, } return results
def my_ballot_view(request): generate_voter_device_id_if_needed = True voter_device_id = get_voter_device_id(request, generate_voter_device_id_if_needed) voter_id_found = False voter_device_link_manager = VoterDeviceLinkManager() results = voter_device_link_manager.retrieve_voter_device_link_from_voter_device_id( voter_device_id) if results['voter_device_link_found']: voter_device_link = results['voter_device_link'] voter_id_found = True if voter_device_link.voter_id > 0 else False # If existing voter not found, create a new voter if not voter_id_found: # Create a new voter and return the id voter_manager = VoterManager() results = voter_manager.create_voter() if results['voter_created']: voter = results['voter'] # Now save the voter_device_link results = voter_device_link_manager.save_new_voter_device_link( voter_device_id, voter.id) if results['voter_device_link_created']: voter_device_link = results['voter_device_link'] voter_id_found = True if voter_device_link.voter_id > 0 else False if not voter_id_found: print "Voter ID not found, nor generated. This should not be possible. (Cookies may be turned off?)" ballot_item_list = [] else: ballot_item_manager = BallotItemManager() results = ballot_item_manager.retrieve_all_ballot_items_for_voter( voter_device_link.voter_id) ballot_item_list = results['ballot_item_list'] template_values = { 'ballot_item_list': ballot_item_list, } response = render(request, 'ux_oak/my_ballot.html', template_values) set_voter_device_id(request, response, voter_device_id) return response
def voter_retrieve_list_for_api(voter_device_id): results = is_voter_device_id_valid(voter_device_id) if not results["success"]: results2 = {"success": False, "json_data": results["json_data"]} return results2 voter_id = fetch_voter_id_from_voter_device_link(voter_device_id) if voter_id > 0: voter_manager = VoterManager() results = voter_manager.retrieve_voter_by_id(voter_id) if results["voter_found"]: voter_id = results["voter_id"] else: # If we are here, the voter_id could not be found from the voter_device_id json_data = {"status": "VOTER_NOT_FOUND_FROM_DEVICE_ID", "success": False, "voter_device_id": voter_device_id} results = {"success": False, "json_data": json_data} return results if voter_id: voter_list = Voter.objects.all() voter_list = voter_list.filter(id=voter_id) if len(voter_list): results = {"success": True, "voter_list": voter_list} return results # Trying to mimic the Google Civic error codes scheme errors_list = [ { "domain": "TODO global", "reason": "TODO reason", "message": "TODO Error message here", "locationType": "TODO Error message here", "location": "TODO location", } ] error_package = {"errors": errors_list, "code": 400, "message": "Error message here"} json_data = { "error": error_package, "status": "VOTER_ID_COULD_NOT_BE_RETRIEVED", "success": False, "voter_device_id": voter_device_id, } results = {"success": False, "json_data": json_data} return results
def my_ballot_view(request): generate_voter_device_id_if_needed = True voter_device_id = get_voter_device_id(request, generate_voter_device_id_if_needed) voter_id_found = False voter_device_link_manager = VoterDeviceLinkManager() results = voter_device_link_manager.retrieve_voter_device_link_from_voter_device_id(voter_device_id) if results['voter_device_link_found']: voter_device_link = results['voter_device_link'] voter_id_found = True if voter_device_link.voter_id > 0 else False # If existing voter not found, create a new voter if not voter_id_found: # Create a new voter and return the id voter_manager = VoterManager() results = voter_manager.create_voter() if results['voter_created']: voter = results['voter'] # Now save the voter_device_link results = voter_device_link_manager.save_new_voter_device_link(voter_device_id, voter.id) if results['voter_device_link_created']: voter_device_link = results['voter_device_link'] voter_id_found = True if voter_device_link.voter_id > 0 else False if not voter_id_found: print "Voter ID not found, nor generated. This should not be possible. (Cookies may be turned off?)" ballot_item_list = [] else: ballot_item_manager = BallotItemManager() results = ballot_item_manager.retrieve_all_ballot_items_for_voter(voter_device_link.voter_id) ballot_item_list = results['ballot_item_list'] template_values = { 'ballot_item_list': ballot_item_list, } response = render(request, 'ux_birch/my_ballot.html', template_values) set_voter_device_id(request, response, voter_device_id) return response
def facebook_sign_in_for_api(voter_device_id, facebook_id=None, facebook_email=None): # facebookSignIn """ :param voter_device_id: :return: """ # Get voter_id from the voter_device_id so we can figure out which ballot_items to offer results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'success': False, 'status': "VALID_VOTER_MISSING", 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } return results voter = results['voter'] results_from_facebook_id = voter_manager.retrieve_voter_by_facebook_id(facebook_id) if positive_value_exists(results_from_facebook_id['voter_found']): voter_found_with_facebook_id = results_from_facebook_id['voter'] if voter_found_with_facebook_id.id == voter.id: # If here, the owner of the facebook_id is the current primary voter status = "FACEBOOK_SIGN_IN-ALREADY_LINKED_TO_THIS_FACEBOOK_ACCOUNT " success = True if positive_value_exists(facebook_email) or facebook_email == '': results = voter_manager.save_facebook_user_values(voter, facebook_id, facebook_email) status += results['status'] success = results['success'] else: # If here, we need to merge accounts status = "FACEBOOK_SIGN_IN-ALREADY_LINKED_TO_OTHER_ACCOUNT" success = False else: results = voter_manager.save_facebook_user_values(voter, facebook_id, facebook_email) status = results['status'] success = results['success'] if success: results = { 'success': True, 'status': status, 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } else: results = { 'success': False, 'status': status, 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } return results
def test_count_with_voter_device_id(self): """ Test the various cookie states :return: """ ####################################### # Generate the voter_device_id cookie response0 = self.client.get(self.generate_voter_device_id_url) json_data0 = json.loads(response0.content.decode()) # Make sure we got back a voter_device_id we can use self.assertEqual('voter_device_id' in json_data0, True, "voter_device_id expected in the deviceIdGenerateView json response") # Now put the voter_device_id in a variable we can use below voter_device_id = json_data0['voter_device_id'] if 'voter_device_id' in json_data0 else '' ####################################### # Test for status: VOTER_CREATED response02 = self.client.get(self.voter_create_url) json_data02 = json.loads(response02.content.decode()) self.assertEqual('status' in json_data02, True, "status expected in the voterCreateView json response but not found") self.assertEqual('voter_device_id' in json_data02, True, "voter_device_id expected in the voterCreateView json response but not found") # With a brand new voter_device_id, a new voter record should be created self.assertEqual( json_data02['status'], 'VOTER_CREATED', "status: {status} (VOTER_CREATED expected), voter_device_id: {voter_device_id}".format( status=json_data02['status'], voter_device_id=json_data02['voter_device_id'])) ####################################### # Check to see if there is 1 voter - i.e., the viewer response11 = self.client.get(self.voter_count_url) json_data11 = json.loads(response11.content.decode()) self.assertEqual('success' in json_data11, True, "'success' expected in the json response, and not found") self.assertEqual('voter_count' in json_data11, True, "'voter_count' expected in the voterCount json response") self.assertEqual( json_data11['voter_count'], 1, "success: {success} (voter_count '1' expected), voter_count: {voter_count}".format( success=json_data11['success'], voter_count=json_data11['voter_count'])) ####################################### # Add 3 voters so we can check count again voter_manager = VoterManager() email1 = "*****@*****.**" voter_manager.create_voter( email=email1, password="******", ) email2 = "*****@*****.**" voter_manager.create_voter( email=email2, password="******", ) email3 = "*****@*****.**" voter_manager.create_voter( email=email3, password="******", ) ####################################### # Check to see if there are 4 voters response12 = self.client.get(self.voter_count_url) json_data12 = json.loads(response12.content.decode()) self.assertEqual('success' in json_data12, True, "'success' expected in the json response, and not found") self.assertEqual('voter_count' in json_data12, True, "'voter_count' expected in the voterCount json response") self.assertEqual( json_data12['voter_count'], 4, "success: {success} (voter_count '4' expected), voter_count: {voter_count}".format( success=json_data12['success'], voter_count=json_data12['voter_count']))
def login_user(request): """ This method is called when you login from the /login/ form :param request: :return: """ voter_api_device_id = get_voter_api_device_id(request) # We look in the cookies for voter_api_device_id store_new_voter_api_device_id_in_cookie = False voter_signed_in = False voter_manager = VoterManager() voter_device_link_manager = VoterDeviceLinkManager() results = voter_manager.retrieve_voter_from_voter_device_id(voter_api_device_id) if results['voter_found']: voter_on_stage = results['voter'] voter_on_stage_id = voter_on_stage.id # Just because a We Vote voter is found doesn't mean they are authenticated for Django else: voter_on_stage_id = 0 info_message = '' error_message = '' username = '' # Does Django think user is already signed in? if request.user.is_authenticated(): # If so, make sure user and voter_on_stage are the same. if request.user.id != voter_on_stage_id: # Delete the prior voter_api_device_id from database voter_device_link_manager.delete_voter_device_link(voter_api_device_id) # Create a new voter_api_device_id and voter_device_link voter_api_device_id = generate_voter_device_id() results = voter_device_link_manager.save_new_voter_device_link(voter_api_device_id, request.user.id) store_new_voter_api_device_id_in_cookie = results['voter_device_link_created'] voter_on_stage = request.user voter_on_stage_id = voter_on_stage.id elif request.POST: username = request.POST.get('username') password = request.POST.get('password') user = authenticate(username=username, password=password) if user is not None: if user.is_active: login(request, user) info_message = "You're successfully logged in!" # Delete the prior voter_api_device_id from database voter_device_link_manager.delete_voter_device_link(voter_api_device_id) # Create a new voter_api_device_id and voter_device_link voter_api_device_id = generate_voter_device_id() results = voter_device_link_manager.save_new_voter_device_link(voter_api_device_id, user.id) store_new_voter_api_device_id_in_cookie = results['voter_device_link_created'] else: error_message = "Your account is not active, please contact the site admin." if user.id != voter_on_stage_id: # Eventually we want to merge voter_on_stage into user account pass else: error_message = "Your username and/or password were incorrect." elif not positive_value_exists(voter_on_stage_id): # If here, delete the prior voter_api_device_id from database voter_device_link_manager.delete_voter_device_link(voter_api_device_id) # We then need to set a voter_api_device_id cookie and create a new voter (even though not signed in) results = voter_setup(request) voter_api_device_id = results['voter_api_device_id'] store_new_voter_api_device_id_in_cookie = results['store_new_voter_api_device_id_in_cookie'] # Does Django think user is signed in? if request.user.is_authenticated(): voter_signed_in = True else: info_message = "Please log in below..." if positive_value_exists(error_message): messages.add_message(request, messages.ERROR, error_message) if positive_value_exists(info_message): messages.add_message(request, messages.INFO, info_message) messages_on_stage = get_messages(request) template_values = { 'request': request, 'username': username, 'next': next, 'voter_signed_in': voter_signed_in, 'messages_on_stage': messages_on_stage, } response = render(request, 'registration/login_user.html', template_values) # We want to store the voter_api_device_id cookie if it is new if positive_value_exists(voter_api_device_id) and positive_value_exists(store_new_voter_api_device_id_in_cookie): set_voter_api_device_id(request, response, voter_api_device_id) return response
def twitter_sign_in_start_for_api(voter_device_id): # twitterSignInStart """ :param voter_device_id: :return: """ # Get voter_id from the voter_device_id so we can figure out which ballot_items to offer results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id( voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'status': "VALID_VOTER_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', } return results voter = results['voter'] callback_url = WE_VOTE_SERVER_ROOT_URL + "/twitter/process_sign_in_response/" redirect_url = '' try: # We take the Consumer Key and the Consumer Secret, and request a token & token_secret auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, callback_url) redirect_url = auth.get_authorization_url() request_token_dict = auth.request_token twitter_request_token = '' twitter_request_token_secret = '' if 'oauth_token' in request_token_dict: twitter_request_token = request_token_dict['oauth_token'] if 'oauth_token_secret' in request_token_dict: twitter_request_token_secret = request_token_dict[ 'oauth_token_secret'] # We save these values in the Voter table, and then return a redirect_url where the user can sign in # Once they sign in to the Twitter login, they are redirected back to the We Vote callback_url # On that callback_url page (a Django/Python page as opposed to ReactJS), we are told if they are signed in # on Twitter or not, and capture an access key we can use to retrieve information about the Twitter user if positive_value_exists( twitter_request_token) and positive_value_exists( twitter_request_token_secret): voter.twitter_request_token = twitter_request_token voter.twitter_request_secret = twitter_request_token_secret voter.save() success = True status = "TWITTER_REDIRECT_URL_RETRIEVED" else: success = False status = "TWITTER_REDIRECT_URL_NOT_RETRIEVED" except tweepy.RateLimitError: success = False status = 'TWITTER_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = 'TWITTER_SIGN_IN_START: ' error_tuple = error_instance.args for error_dict in error_tuple: for one_error in error_dict: status += '[' + one_error['message'] + '] ' if success: results = { 'status': status, 'success': True, 'voter_device_id': voter_device_id, 'twitter_redirect_url': redirect_url, } else: results = { 'status': status, 'success': False, 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', } return results
def twitter_sign_in_start_for_api(voter_device_id, return_url): # twitterSignInStart """ :param voter_device_id: :param return_url: Where to direct the browser at the very end of the process :return: """ # Get voter_id from the voter_device_id results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', 'voter_info_retrieved': False, 'switch_accounts': False, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'status': "VALID_VOTER_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', 'voter_info_retrieved': False, 'switch_accounts': False, } return results voter = results['voter'] if voter.twitter_access_token and voter.twitter_access_secret: # If here the voter might already be signed in, so we don't want to ask them to approve again auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) auth.set_access_token(voter.twitter_access_token, voter.twitter_access_secret) api = tweepy.API(auth) try: tweepy_user_object = api.me() success = True # What is the error situation where the twitter_access_token and twitter_access_secret are no longer valid? # We need to deal with this (wipe them from the database and rewind to the right place in the process except tweepy.RateLimitError: success = False status = 'TWITTER_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = '' error_tuple = error_instance.args for error_dict in error_tuple: for one_error in error_dict: status += '[' + one_error['message'] + '] ' if success: # Reach out to the twitterSignInRequestVoterInfo -- no need to redirect empty_return_url = "" voter_info_results = twitter_sign_in_request_voter_info_for_api(voter_device_id, empty_return_url) success = voter_info_results['success'] status = "SKIPPED_AUTH_DIRECT_REQUEST_VOTER_INFO: " + voter_info_results['status'] results = { 'status': status, 'success': success, 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', 'voter_info_retrieved': voter_info_results['voter_info_retrieved'], 'switch_accounts': voter_info_results['switch_accounts'], # If true, new voter_device_id returned } return results else: # Somehow reset tokens and start over. pass callback_url = WE_VOTE_SERVER_ROOT_URL + "/apis/v1/twitterSignInRequestAccessToken/" callback_url += "?voter_device_id=" + voter_device_id callback_url += "&return_url=" + return_url # This is where twitter_authorization_url = '' try: # We take the Consumer Key and the Consumer Secret, and request a token & token_secret auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, callback_url) twitter_authorization_url = auth.get_authorization_url() request_token_dict = auth.request_token twitter_request_token = '' twitter_request_token_secret = '' if 'oauth_token' in request_token_dict: twitter_request_token = request_token_dict['oauth_token'] if 'oauth_token_secret' in request_token_dict: twitter_request_token_secret = request_token_dict['oauth_token_secret'] # We save these values in the Voter table, and then return a twitter_authorization_url where the voter signs in # Once they sign in to the Twitter login, they are redirected back to the We Vote callback_url # On that callback_url page, we are told if they are signed in # on Twitter or not, and capture an access key we can use to retrieve information about the Twitter user # NOTE: Regarding the callback url, I think this can just be a direct call to the API server, # since we have the voter_device_id if positive_value_exists(twitter_request_token) and positive_value_exists(twitter_request_token_secret): voter.twitter_request_token = twitter_request_token voter.twitter_request_secret = twitter_request_token_secret voter.save() success = True status = "TWITTER_REDIRECT_URL_RETRIEVED" else: success = False status = "TWITTER_REDIRECT_URL_NOT_RETRIEVED" except tweepy.RateLimitError: success = False status = 'TWITTER_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = 'TWITTER_SIGN_IN_START: ' error_tuple = error_instance.args for error_dict in error_tuple: for one_error in error_dict: status += '[' + one_error['message'] + '] ' if success: results = { 'status': status, 'success': True, 'voter_device_id': voter_device_id, 'twitter_redirect_url': twitter_authorization_url, 'voter_info_retrieved': False, 'switch_accounts': False, } else: results = { 'status': status, 'success': False, 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', 'voter_info_retrieved': False, 'switch_accounts': False, } return results
def twitter_sign_in_request_voter_info_for_api(voter_device_id, return_url, switch_accounts_if_needed=True): """ twitterSignInRequestVoterInfo When here, the incoming voter_device_id should already be authenticated :param voter_device_id: :param return_url: Where to return the browser when sign in process is complete :param switch_accounts_if_needed: :return: """ twitter_handle = '' twitter_handle_found = False tweepy_user_object = None twitter_user_object_found = False voter_info_retrieved = False switch_accounts = False # Get voter_id from the voter_device_id results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'twitter_handle': twitter_handle, 'twitter_handle_found': twitter_handle_found, 'voter_info_retrieved': voter_info_retrieved, 'switch_accounts': switch_accounts, 'return_url': return_url, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'status': "VALID_VOTER_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'twitter_handle': twitter_handle, 'twitter_handle_found': twitter_handle_found, 'voter_info_retrieved': voter_info_retrieved, 'switch_accounts': switch_accounts, 'return_url': return_url, } return results voter = results['voter'] auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) auth.set_access_token(voter.twitter_access_token, voter.twitter_access_secret) api = tweepy.API(auth) try: tweepy_user_object = api.me() twitter_json = tweepy_user_object._json success = True status = 'TWITTER_SIGN_IN_REQUEST_VOTER_INFO_SUCCESSFUL' twitter_handle = tweepy_user_object.screen_name twitter_handle_found = True twitter_user_object_found = True except tweepy.RateLimitError: success = False status = 'TWITTER_SIGN_IN_REQUEST_VOTER_INFO_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = 'TWITTER_SIGN_IN_REQUEST_VOTER_INFO_TWEEPY_ERROR: ' error_tuple = error_instance.args for error_dict in error_tuple: for one_error in error_dict: status += '[' + one_error['message'] + '] ' if twitter_user_object_found: # We need to deal with these cases # 1) Does account already exist? results = voter_manager.retrieve_voter_by_twitter_id(tweepy_user_object.id) if results['voter_found'] and switch_accounts_if_needed: voter_found_with_twitter_id = results['voter'] switch_accounts = True # Relink this voter_device_id to the original account voter_device_manager = VoterDeviceLinkManager() voter_device_link_results = voter_device_manager.retrieve_voter_device_link(voter_device_id) voter_device_link = voter_device_link_results['voter_device_link'] update_voter_device_link_results = voter_device_manager.update_voter_device_link( voter_device_link, voter_found_with_twitter_id) if update_voter_device_link_results['voter_device_link_updated']: # Transfer access token and secret voter_found_with_twitter_id.twitter_access_token = voter.twitter_access_token voter_found_with_twitter_id.twitter_access_secret = voter.twitter_access_secret voter_found_with_twitter_id.save() status += "TWITTER_SIGN_IN-ALREADY_LINKED_TO_OTHER_ACCOUNT-TRANSFERRED " success = True save_user_results = voter_manager.save_twitter_user_values(voter_found_with_twitter_id, tweepy_user_object) if save_user_results['success']: voter_info_retrieved = True status += save_user_results['status'] else: status = "TWITTER_SIGN_IN-ALREADY_LINKED_TO_OTHER_ACCOUNT-COULD_NOT_TRANSFER " success = False # 2) If account doesn't exist for this person, save else: save_user_results = voter_manager.save_twitter_user_values(voter, tweepy_user_object) if save_user_results['success']: voter_info_retrieved = True results = { 'status': status, 'success': success, 'voter_device_id': voter_device_id, 'twitter_handle': twitter_handle, 'twitter_handle_found': twitter_handle_found, 'voter_info_retrieved': voter_info_retrieved, 'switch_accounts': switch_accounts, 'return_url': return_url, } return results
def process_sign_in_response_view(request): oauth_token = request.GET.get('oauth_token', '') oauth_verifier = request.GET.get('oauth_verifier', '') if not positive_value_exists(oauth_token) or not positive_value_exists( oauth_verifier): # Redirect back to ReactJS so we can display failure message return HttpResponseRedirect( 'http://localhost:3001/twitter/missing_variables' ) # TODO Convert to env variable voter_manager = VoterManager() # Look in the Voter table for a matching request_token, placed by the API endpoint twitterSignInStart results = voter_manager.retrieve_voter_by_twitter_request_token( oauth_token) if not results['voter_found']: # Redirect back to ReactJS so we can display failure message if the token wasn't found return HttpResponseRedirect( 'http://localhost:3001/twitter/token_missing' ) # TODO Convert to env variable voter = results['voter'] # Fetch the access token try: # Set up a tweepy auth handler auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) auth.request_token = { 'oauth_token': voter.twitter_request_token, 'oauth_token_secret': voter.twitter_request_secret } auth.get_access_token(oauth_verifier) if not positive_value_exists( auth.access_token) or not positive_value_exists( auth.access_token_secret): # Redirect back with error return HttpResponseRedirect( 'http://localhost:3001/twitter/access_token_missing' ) # TODO Convert to env var voter.twitter_access_token = auth.access_token voter.twitter_access_secret = auth.access_token_secret voter.save() # Next use the access_token and access_secret to retrieve Twitter user info api = tweepy.API(auth) tweepy_user_object = api.me() voter_manager.save_twitter_user_values(voter, tweepy_user_object) except tweepy.RateLimitError: success = False status = 'TWITTER_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = '' error_tuple = error_instance.args for error_dict in error_tuple: for one_error in error_dict: status += '[' + one_error['message'] + '] ' # Redirect back, success return HttpResponseRedirect( 'http://localhost:3001/ballot') # TODO Convert to env var
def facebook_sign_in_for_api(voter_device_id, facebook_id=None, facebook_email=None): # facebookSignIn """ :param voter_device_id: :return: """ status = "" success = False # Get voter_id from the voter_device_id results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'success': False, 'status': "VALID_VOTER_MISSING", 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } return results voter = results['voter'] results_from_facebook_id = voter_manager.retrieve_voter_by_facebook_id(facebook_id) if positive_value_exists(results_from_facebook_id['voter_found']): voter_found_with_facebook_id = results_from_facebook_id['voter'] if voter_found_with_facebook_id.id == voter.id: # If here, the owner of the facebook_id is already the current primary voter status += "FACEBOOK_SIGN_IN-ALREADY_LINKED_TO_THIS_FACEBOOK_ACCOUNT " success = True # Only save if the email is different than what is saved if positive_value_exists(facebook_email) or facebook_email == '': results = voter_manager.save_facebook_user_values(voter, facebook_id, facebook_email) status += results['status'] success = results['success'] else: # If here, we need to merge accounts TODO # ...but for now we are simply going to switch to the earlier account and abandon # the newer account if positive_value_exists(facebook_email) or facebook_email == '': results = voter_manager.save_facebook_user_values(voter_found_with_facebook_id, facebook_id, facebook_email) status += results['status'] + ", " success = results['success'] # Relink this voter_device_id to the original account voter_device_manager = VoterDeviceLinkManager() voter_device_link_results = voter_device_manager.retrieve_voter_device_link(voter_device_id) voter_device_link = voter_device_link_results['voter_device_link'] update_voter_device_link_results = voter_device_manager.update_voter_device_link( voter_device_link, voter_found_with_facebook_id) if update_voter_device_link_results['voter_device_link_updated']: status += "FACEBOOK_SIGN_IN-ALREADY_LINKED_TO_OTHER_ACCOUNT-TRANSFERRED " success = True else: status = "FACEBOOK_SIGN_IN-ALREADY_LINKED_TO_OTHER_ACCOUNT-COULD_NOT_TRANSFER " success = False else: # An existing account linked to this facebook account was not found results = voter_manager.save_facebook_user_values(voter, facebook_id, facebook_email) status = results['status'] success = results['success'] if success: results = { 'success': True, 'status': status, 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } else: results = { 'success': False, 'status': status, 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } return results
def voter_position_comment_save_for_api( voter_device_id, position_id, position_we_vote_id, google_civic_election_id, office_we_vote_id, candidate_we_vote_id, measure_we_vote_id, statement_text, statement_html ): results = is_voter_device_id_valid(voter_device_id) if not results['success']: json_data_from_results = results['json_data'] json_data = { 'status': json_data_from_results['status'], 'success': False, 'voter_device_id': voter_device_id, 'position_id': position_id, 'position_we_vote_id': position_we_vote_id, 'new_position_created': False, 'ballot_item_display_name': '', 'speaker_display_name': '', 'speaker_image_url_https': '', 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return json_data voter_manager = VoterManager() voter_results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) voter_id = voter_results['voter_id'] if not positive_value_exists(voter_id): json_data = { 'status': "VOTER_NOT_FOUND_FROM_VOTER_DEVICE_ID", 'success': False, 'voter_device_id': voter_device_id, 'position_id': position_id, 'position_we_vote_id': position_we_vote_id, 'new_position_created': False, 'ballot_item_display_name': '', 'speaker_display_name': '', 'speaker_image_url_https': '', 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return json_data voter = voter_results['voter'] position_id = convert_to_int(position_id) position_we_vote_id = position_we_vote_id.strip() existing_unique_identifier_found = positive_value_exists(position_id) \ or positive_value_exists(position_we_vote_id) new_unique_identifier_found = positive_value_exists(voter_id) \ and positive_value_exists(google_civic_election_id) and ( positive_value_exists(office_we_vote_id) or positive_value_exists(candidate_we_vote_id) or positive_value_exists(measure_we_vote_id) ) unique_identifier_found = existing_unique_identifier_found or new_unique_identifier_found # We must have these variables in order to create a new entry required_variables_for_new_entry = positive_value_exists(voter_id) \ and positive_value_exists(google_civic_election_id) and ( positive_value_exists(office_we_vote_id) or positive_value_exists(candidate_we_vote_id) or positive_value_exists(measure_we_vote_id) ) if not unique_identifier_found: json_data = { 'status': "POSITION_REQUIRED_UNIQUE_IDENTIFIER_VARIABLES_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'position_id': position_id, 'position_we_vote_id': position_we_vote_id, 'new_position_created': False, 'ballot_item_display_name': '', 'speaker_display_name': '', 'speaker_image_url_https': '', 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return json_data elif not existing_unique_identifier_found and not required_variables_for_new_entry: json_data = { 'status': "NEW_POSITION_REQUIRED_VARIABLES_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'position_id': position_id, 'position_we_vote_id': position_we_vote_id, 'new_position_created': False, 'ballot_item_display_name': '', 'speaker_display_name': '', 'speaker_image_url_https': '', 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return json_data position_manager = PositionEnteredManager() save_results = position_manager.update_or_create_position( position_id=position_id, position_we_vote_id=position_we_vote_id, voter_we_vote_id=voter.we_vote_id, google_civic_election_id=google_civic_election_id, office_we_vote_id=office_we_vote_id, candidate_we_vote_id=candidate_we_vote_id, measure_we_vote_id=measure_we_vote_id, statement_text=statement_text, statement_html=statement_html, ) if save_results['success']: position = save_results['position'] json_data = { 'success': save_results['success'], 'status': save_results['status'], 'voter_device_id': voter_device_id, 'position_id': position.id, 'position_we_vote_id': position.we_vote_id, 'ballot_item_display_name': position.ballot_item_display_name, 'speaker_display_name': position.speaker_display_name, 'speaker_image_url_https': position.speaker_image_url_https, 'new_position_created': save_results['new_position_created'], 'is_support': position.is_support(), 'is_oppose': position.is_oppose(), 'is_information_only': position.is_information_only(), 'google_civic_election_id': position.google_civic_election_id, 'office_we_vote_id': position.contest_office_we_vote_id, 'candidate_we_vote_id': position.candidate_campaign_we_vote_id, 'measure_we_vote_id': position.contest_measure_we_vote_id, 'statement_text': position.statement_text, 'statement_html': position.statement_html, 'last_updated': position.last_updated(), } return json_data else: json_data = { 'success': False, 'status': save_results['status'], 'voter_device_id': voter_device_id, 'position_id': position_id, 'position_we_vote_id': position_we_vote_id, 'new_position_created': False, 'ballot_item_display_name': '', 'speaker_display_name': '', 'speaker_image_url_https': '', 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return json_data
def quick_info_text_save_for_api( # TODO to be converted voter_device_id, quick_info_id, quick_info_we_vote_id, google_civic_election_id, office_we_vote_id, candidate_we_vote_id, measure_we_vote_id, statement_text, statement_html ): results = is_voter_device_id_valid(voter_device_id) if not results['success']: json_data_from_results = results['json_data'] json_data = { 'status': json_data_from_results['status'], 'success': False, 'voter_device_id': voter_device_id, 'quick_info_id': quick_info_id, 'quick_info_we_vote_id': quick_info_we_vote_id, 'new_quick_info_created': False, 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return HttpResponse(json.dumps(json_data), content_type='application/json') voter_manager = VoterManager() voter_results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) voter_id = voter_results['voter_id'] if not positive_value_exists(voter_id): json_data = { 'status': "VOTER_NOT_FOUND_FROM_VOTER_DEVICE_ID", 'success': False, 'voter_device_id': voter_device_id, 'quick_info_id': quick_info_id, 'quick_info_we_vote_id': quick_info_we_vote_id, 'new_quick_info_created': False, 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return HttpResponse(json.dumps(json_data), content_type='application/json') voter = voter_results['voter'] quick_info_id = convert_to_int(quick_info_id) quick_info_we_vote_id = quick_info_we_vote_id.strip().lower() existing_unique_identifier_found = positive_value_exists(quick_info_id) \ or positive_value_exists(quick_info_we_vote_id) new_unique_identifier_found = positive_value_exists(voter_id) \ and positive_value_exists(google_civic_election_id) and ( positive_value_exists(office_we_vote_id) or positive_value_exists(candidate_we_vote_id) or positive_value_exists(measure_we_vote_id) ) unique_identifier_found = existing_unique_identifier_found or new_unique_identifier_found # We must have these variables in order to create a new entry required_variables_for_new_entry = positive_value_exists(voter_id) \ and positive_value_exists(google_civic_election_id) and ( positive_value_exists(office_we_vote_id) or positive_value_exists(candidate_we_vote_id) or positive_value_exists(measure_we_vote_id) ) if not unique_identifier_found: results = { 'status': "QUICK_INFO_REQUIRED_UNIQUE_IDENTIFIER_VARIABLES_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'quick_info_id': quick_info_id, 'quick_info_we_vote_id': quick_info_we_vote_id, 'new_quick_info_created': False, 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return results elif not existing_unique_identifier_found and not required_variables_for_new_entry: results = { 'status': "NEW_QUICK_INFO_REQUIRED_VARIABLES_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'quick_info_id': quick_info_id, 'quick_info_we_vote_id': quick_info_we_vote_id, 'new_quick_info_created': False, 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return results quick_info_manager = QuickInfoManager() save_results = quick_info_manager.update_or_create_quick_info( quick_info_id=quick_info_id, quick_info_we_vote_id=quick_info_we_vote_id, voter_we_vote_id=voter.we_vote_id, google_civic_election_id=google_civic_election_id, office_we_vote_id=office_we_vote_id, candidate_we_vote_id=candidate_we_vote_id, measure_we_vote_id=measure_we_vote_id, statement_text=statement_text, statement_html=statement_html, ) if save_results['success']: quick_info = save_results['quick_info'] results = { 'success': save_results['success'], 'status': save_results['status'], 'voter_device_id': voter_device_id, 'quick_info_id': quick_info.id, 'quick_info_we_vote_id': quick_info.we_vote_id, 'new_quick_info_created': save_results['new_quick_info_created'], 'is_support': quick_info.is_support(), 'is_oppose': quick_info.is_oppose(), 'is_information_only': quick_info.is_information_only(), 'google_civic_election_id': quick_info.google_civic_election_id, 'office_we_vote_id': quick_info.contest_office_we_vote_id, 'candidate_we_vote_id': quick_info.candidate_campaign_we_vote_id, 'measure_we_vote_id': quick_info.contest_measure_we_vote_id, 'statement_text': quick_info.statement_text, 'statement_html': quick_info.statement_html, 'last_updated': '', } return results else: results = { 'success': False, 'status': save_results['status'], 'voter_device_id': voter_device_id, 'quick_info_id': quick_info_id, 'quick_info_we_vote_id': quick_info_we_vote_id, 'new_quick_info_created': False, 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return results
def voter_retrieve_list_for_api(voter_device_id): results = is_voter_device_id_valid(voter_device_id) if not results['success']: results2 = { 'success': False, 'json_data': results['json_data'], } return results2 voter_id = fetch_voter_id_from_voter_device_link(voter_device_id) if voter_id > 0: voter_manager = VoterManager() results = voter_manager.retrieve_voter_by_id(voter_id) if results['voter_found']: voter_id = results['voter_id'] else: # If we are here, the voter_id could not be found from the voter_device_id json_data = { 'status': "VOTER_NOT_FOUND_FROM_DEVICE_ID", 'success': False, 'voter_device_id': voter_device_id, } results = { 'success': False, 'json_data': json_data, } return results if voter_id: voter_list = Voter.objects.all() voter_list = voter_list.filter(id=voter_id) if len(voter_list): results = { 'success': True, 'voter_list': voter_list, } return results # Trying to mimic the Google Civic error codes scheme errors_list = [{ 'domain': "TODO global", 'reason': "TODO reason", 'message': "TODO Error message here", 'locationType': "TODO Error message here", 'location': "TODO location", }] error_package = { 'errors': errors_list, 'code': 400, 'message': "Error message here", } json_data = { 'error': error_package, 'status': "VOTER_ID_COULD_NOT_BE_RETRIEVED", 'success': False, 'voter_device_id': voter_device_id, } results = { 'success': False, 'json_data': json_data, } return results
def twitter_sign_in_start_for_api(voter_device_id): # twitterSignInStart """ :param voter_device_id: :return: """ # Get voter_id from the voter_device_id so we can figure out which ballot_items to offer results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'status': "VALID_VOTER_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', } return results voter = results['voter'] callback_url = WE_VOTE_SERVER_ROOT_URL + "/twitter/process_sign_in_response/" redirect_url = '' try: # We take the Consumer Key and the Consumer Secret, and request a token & token_secret auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, callback_url) redirect_url = auth.get_authorization_url() request_token_dict = auth.request_token twitter_request_token = '' twitter_request_token_secret = '' if 'oauth_token' in request_token_dict: twitter_request_token = request_token_dict['oauth_token'] if 'oauth_token_secret' in request_token_dict: twitter_request_token_secret = request_token_dict['oauth_token_secret'] # We save these values in the Voter table, and then return a redirect_url where the user can sign in # Once they sign in to the Twitter login, they are redirected back to the We Vote callback_url # On that callback_url page (a Django/Python page as opposed to ReactJS), we are told if they are signed in # on Twitter or not, and capture an access key we can use to retrieve information about the Twitter user if positive_value_exists(twitter_request_token) and positive_value_exists(twitter_request_token_secret): voter.twitter_request_token = twitter_request_token voter.twitter_request_secret = twitter_request_token_secret voter.save() success = True status = "TWITTER_REDIRECT_URL_RETRIEVED" else: success = False status = "TWITTER_REDIRECT_URL_NOT_RETRIEVED" except tweepy.RateLimitError: success = False status = 'TWITTER_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = 'TWITTER_SIGN_IN_START: ' error_tuple = error_instance.args for error_dict in error_tuple: for one_error in error_dict: status += '[' + one_error['message'] + '] ' if success: results = { 'status': status, 'success': True, 'voter_device_id': voter_device_id, 'twitter_redirect_url': redirect_url, } else: results = { 'status': status, 'success': False, 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', } return results
def voter_guides_to_follow_retrieve_for_api( voter_device_id, # voterGuidesToFollow kind_of_ballot_item='', ballot_item_we_vote_id='', google_civic_election_id=0, search_string='', maximum_number_to_retrieve=0): # Get voter_id from the voter_device_id so we can figure out which voter_guides to offer results = is_voter_device_id_valid(voter_device_id) if not results['success']: json_data = { 'status': 'ERROR_GUIDES_TO_FOLLOW_NO_VOTER_DEVICE_ID', 'success': False, 'voter_device_id': voter_device_id, 'voter_guides': [], 'google_civic_election_id': google_civic_election_id, 'search_string': search_string, 'ballot_item_we_vote_id': ballot_item_we_vote_id, } results = { 'success': False, 'google_civic_election_id': 0, # Force the reset of google_civic_election_id cookie 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'json_data': json_data, } return results voter_id = fetch_voter_id_from_voter_device_link(voter_device_id) if not positive_value_exists(voter_id): json_data = { 'status': "ERROR_GUIDES_TO_FOLLOW_VOTER_NOT_FOUND_FROM_VOTER_DEVICE_ID", 'success': False, 'voter_device_id': voter_device_id, 'voter_guides': [], 'google_civic_election_id': google_civic_election_id, 'search_string': search_string, 'ballot_item_we_vote_id': ballot_item_we_vote_id, } results = { 'success': False, 'google_civic_election_id': 0, # Force the reset of google_civic_election_id cookie 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'json_data': json_data, } return results voter_guide_list = [] voter_guides = [] try: if positive_value_exists( kind_of_ballot_item) and positive_value_exists( ballot_item_we_vote_id): results = retrieve_voter_guides_to_follow_by_ballot_item( voter_id, kind_of_ballot_item, ballot_item_we_vote_id, search_string) success = results['success'] status = results['status'] voter_guide_list = results['voter_guide_list'] elif positive_value_exists(google_civic_election_id): # This retrieve also does the reordering results = retrieve_voter_guides_to_follow_by_election_for_api( voter_id, google_civic_election_id, search_string, maximum_number_to_retrieve, 'twitter_followers_count', 'desc') success = results['success'] status = results['status'] voter_guide_list = results['voter_guide_list'] else: results = retrieve_voter_guides_to_follow_generic_for_api( voter_id, search_string, maximum_number_to_retrieve, 'twitter_followers_count', 'desc') success = results['success'] status = results['status'] voter_guide_list = results['voter_guide_list'] except Exception as e: status = 'FAILED voter_guides_to_follow_retrieve_for_api, retrieve_voter_guides_for_election ' \ '{error} [type: {error_type}]'.format(error=e, error_type=type(e)) success = False if success: voter_manager = VoterManager() results = voter_manager.retrieve_voter_by_id(voter_id) linked_organization_we_vote_id = "" if results['voter_found']: voter = results['voter'] linked_organization_we_vote_id = voter.linked_organization_we_vote_id number_added_to_list = 0 position_manager = PositionEnteredManager() position = PositionEntered() for voter_guide in voter_guide_list: if positive_value_exists(voter_guide.organization_we_vote_id) \ and linked_organization_we_vote_id == voter_guide.organization_we_vote_id: # Do not return your own voter guide to follow continue position_found = False one_voter_guide = { 'we_vote_id': voter_guide.we_vote_id, 'google_civic_election_id': voter_guide.google_civic_election_id, 'time_span': voter_guide.vote_smart_time_span, 'voter_guide_display_name': voter_guide.voter_guide_display_name(), 'voter_guide_image_url': voter_guide.voter_guide_image_url(), 'voter_guide_owner_type': voter_guide.voter_guide_owner_type, 'organization_we_vote_id': voter_guide.organization_we_vote_id, 'public_figure_we_vote_id': voter_guide.public_figure_we_vote_id, 'twitter_description': voter_guide.twitter_description, 'twitter_followers_count': voter_guide.twitter_followers_count, 'twitter_handle': voter_guide.twitter_handle, 'owner_voter_id': voter_guide.owner_voter_id, 'last_updated': voter_guide.last_updated.strftime('%Y-%m-%d %H:%M'), } if positive_value_exists(ballot_item_we_vote_id): if kind_of_ballot_item == CANDIDATE: organization_manager = OrganizationManager() organization_id = organization_manager.fetch_organization_id( voter_guide.organization_we_vote_id) results = position_manager.retrieve_organization_candidate_campaign_position_with_we_vote_id( organization_id, ballot_item_we_vote_id) if results['position_found']: position = results['position'] position_found = True elif kind_of_ballot_item == MEASURE: organization_manager = OrganizationManager() organization_id = organization_manager.fetch_organization_id( voter_guide.organization_we_vote_id) results = position_manager.retrieve_organization_contest_measure_position_with_we_vote_id( organization_id, ballot_item_we_vote_id) if results['position_found']: position = results['position'] position_found = True if position_found: one_voter_guide['is_support'] = position.is_support() one_voter_guide[ 'is_positive_rating'] = position.is_positive_rating() one_voter_guide[ 'is_support_or_positive_rating'] = position.is_support_or_positive_rating( ) one_voter_guide['is_oppose'] = position.is_oppose() one_voter_guide[ 'is_negative_rating'] = position.is_negative_rating() one_voter_guide[ 'is_oppose_or_negative_rating'] = position.is_oppose_or_negative_rating( ) one_voter_guide[ 'is_information_only'] = position.is_information_only( ) one_voter_guide[ 'ballot_item_display_name'] = position.ballot_item_display_name one_voter_guide[ 'speaker_display_name'] = position.speaker_display_name one_voter_guide['statement_text'] = position.statement_text one_voter_guide['more_info_url'] = position.more_info_url one_voter_guide[ 'vote_smart_rating'] = position.vote_smart_rating one_voter_guide[ 'vote_smart_time_span'] = position.vote_smart_time_span voter_guides.append(one_voter_guide.copy()) if positive_value_exists(maximum_number_to_retrieve): number_added_to_list += 1 if number_added_to_list >= maximum_number_to_retrieve: break if len(voter_guides): json_data = { 'status': status + ' VOTER_GUIDES_TO_FOLLOW_RETRIEVED', 'success': True, 'voter_device_id': voter_device_id, 'voter_guides': voter_guides, 'google_civic_election_id': google_civic_election_id, 'search_string': search_string, 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'maximum_number_to_retrieve': maximum_number_to_retrieve, } else: json_data = { 'status': status + ' NO_VOTER_GUIDES_FOUND', 'success': True, 'voter_device_id': voter_device_id, 'voter_guides': voter_guides, 'google_civic_election_id': google_civic_election_id, 'search_string': search_string, 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'maximum_number_to_retrieve': maximum_number_to_retrieve, } results = { 'success': success, 'google_civic_election_id': google_civic_election_id, 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'json_data': json_data, } return results else: json_data = { 'status': status, 'success': False, 'voter_device_id': voter_device_id, 'voter_guides': [], 'google_civic_election_id': google_civic_election_id, 'search_string': search_string, 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'maximum_number_to_retrieve': maximum_number_to_retrieve, } results = { 'success': False, 'google_civic_election_id': 0, # Force the reset of google_civic_election_id cookie 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'json_data': json_data, } return results
def social_user(backend, uid, details, user=None, *args, **kwargs): voter_manager = VoterManager() provider = backend.name social = backend.strategy.storage.user.get_social_auth(provider, uid) if backend.name == 'twitter': # Twitter: Check to see if we have a voter with a matching twitter_id local_user_matches = user and user.twitter_id == uid else: local_user_matches = user and user.email != details.get('email') switch_user = not local_user_matches if switch_user: # Logout the current Django user logout(backend.strategy.request) user = None voter_that_matches_auth = None voter_found_that_matches_auth = False if social: if social.user: if backend.name == 'twitter': if social.user.twitter_id == uid: voter_that_matches_auth = social.user voter_found_that_matches_auth = True else: pass if not voter_found_that_matches_auth: # Find the voter account that actually matches this twitter_id results = voter_manager.retrieve_voter_by_twitter_id(uid) if results['voter_found']: voter_that_matches_auth = results['voter'] voter_found_that_matches_auth = True if voter_found_that_matches_auth: user = voter_that_matches_auth else: # No other account matches this, so we want to save basic information in social.user if backend.name == 'twitter': if social and social.user: twitter_user_dict = { 'id': uid, 'profile_image_url_https': kwargs['response']['profile_image_url_https'], 'screen_name': kwargs['response']['screen_name'] } results = voter_manager.save_twitter_user_values_from_dict( social.user, twitter_user_dict) if results['success']: social.user = results['voter'] user = results['voter'] return { 'social': social, 'user': user, 'is_new': user is None, 'switch_user': True, 'new_association': False }
def twitter_sign_in_request_access_token_for_api(voter_device_id, incoming_request_token, incoming_oauth_verifier, return_url): """ twitterSignInRequestAccessToken After signing in and agreeing to the application's terms, the user is redirected back to the application with the same request token and another value, this time the OAuth verifier. Within this function we use 1) the request token and 2) request secret along with the 3) OAuth verifier to get an access token, also from Twitter. :param voter_device_id: :param incoming_request_token: :param incoming_oauth_verifier: :param return_url: If a value is provided, return to this URL when the whole process is complete :return: """ # Get voter_id from the voter_device_id results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'access_token_and_secret_returned': False, 'return_url': return_url, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id( voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'status': "VALID_VOTER_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'access_token_and_secret_returned': False, 'return_url': return_url, } return results voter = results['voter'] if not voter.twitter_request_token == incoming_request_token: results = { 'status': "TWITTER_REQUEST_TOKEN_DOES_NOT_MATCH_STORED_VOTER_VALUE", 'success': False, 'voter_device_id': voter_device_id, 'access_token_and_secret_returned': False, 'return_url': return_url, } return results twitter_access_token = '' twitter_access_token_secret = '' try: # We take the Request Token, Request Secret, and OAuth Verifier and request an access_token auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) auth.request_token = { 'oauth_token': voter.twitter_request_token, 'oauth_token_secret': voter.twitter_request_secret } auth.get_access_token(incoming_oauth_verifier) if positive_value_exists(auth.access_token) and positive_value_exists( auth.access_token_secret): twitter_access_token = auth.access_token twitter_access_token_secret = auth.access_token_secret except tweepy.RateLimitError: success = False status = 'TWITTER_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = 'TWITTER_SIGN_IN_REQUEST_ACCESS_TOKEN: ' error_tuple = error_instance.args for error_dict in error_tuple: count = 0 # for one_error in error_dict: # status += '[' + one_error[count] + '] ' # count += 1 try: # We save these values in the Voter table if positive_value_exists( twitter_access_token) and positive_value_exists( twitter_access_token_secret): voter.twitter_access_token = twitter_access_token voter.twitter_access_secret = twitter_access_token_secret voter.save() success = True status = "TWITTER_ACCESS_TOKEN_RETRIEVED_AND_SAVED" else: success = False status = "TWITTER_ACCESS_TOKEN_NOT_RETRIEVED" except Exception as e: success = False status = "TWITTER_ACCESS_TOKEN_NOT_SAVED" if success: results = { 'status': status, 'success': True, 'voter_device_id': voter_device_id, 'access_token_and_secret_returned': True, 'return_url': return_url, } else: results = { 'status': status, 'success': False, 'voter_device_id': voter_device_id, 'access_token_and_secret_returned': False, 'return_url': return_url, } return results
def test_count_with_no_voter_device_id(self): """ This API should work even if person isn't signed in :return: """ ####################################### # Check to see if there are 0 voters response = self.client.get(self.voter_count_url) json_data = json.loads(response.content.decode()) # Python3 solution? Problem is refused connection # req = Request(self.voter_count_url) # response = urlopen(req) # json_data = response.read() self.assertEqual('success' in json_data, True, "'success' expected in the json response, and not found") self.assertEqual('voter_count' in json_data, True, "'voter_count' expected in the voterCount json response") self.assertEqual( json_data['voter_count'], 0, "success: {success} (voter_count '0' expected), voter_count: {voter_count}".format( success=json_data['success'], voter_count=json_data['voter_count'])) ####################################### # Add 3 voters so we can check count again voter_manager = VoterManager() email1 = "*****@*****.**" voter_manager.create_voter( email=email1, password="******", ) email2 = "*****@*****.**" voter_manager.create_voter( email=email2, password="******", ) email3 = "*****@*****.**" voter_manager.create_voter( email=email3, password="******", ) ####################################### # Check to see if there are 3 voters response2 = self.client.get(self.voter_count_url) json_data2 = json.loads(response2.content.decode()) self.assertEqual('success' in json_data2, True, "'success' expected in the json response, and not found") self.assertEqual('voter_count' in json_data2, True, "'voter_count' expected in the voterCount json response") self.assertEqual( json_data2['voter_count'], 3, "success: {success} (voter_count '3' expected), voter_count: {voter_count}".format( success=json_data2['success'], voter_count=json_data2['voter_count'])) ####################################### # Remove data for 3 voters voter_manager.delete_voter(email1) voter_manager.delete_voter(email2) voter_manager.delete_voter(email3) ####################################### # Check to see if there are 0 voters response3 = self.client.get(self.voter_count_url) json_data3 = json.loads(response3.content.decode()) self.assertEqual('success' in json_data, True, "'success' expected in the json response, and not found") self.assertEqual('voter_count' in json_data3, True, "'voter_count' expected in the voterCount json response") self.assertEqual( json_data3['voter_count'], 0, "success: {success} (voter_count '0' expected - 2nd pass), voter_count: {voter_count}".format( success=json_data3['success'], voter_count=json_data3['voter_count']))
def voter_we_vote_id(self): voter_manager = VoterManager() return voter_manager.fetch_we_vote_id_from_local_id(self.voter_id)
def quick_info_text_save_for_api( # TODO to be converted voter_device_id, quick_info_id, quick_info_we_vote_id, google_civic_election_id, office_we_vote_id, candidate_we_vote_id, measure_we_vote_id, statement_text, statement_html): results = is_voter_device_id_valid(voter_device_id) if not results['success']: json_data_from_results = results['json_data'] json_data = { 'status': json_data_from_results['status'], 'success': False, 'voter_device_id': voter_device_id, 'quick_info_id': quick_info_id, 'quick_info_we_vote_id': quick_info_we_vote_id, 'new_quick_info_created': False, 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return HttpResponse(json.dumps(json_data), content_type='application/json') voter_manager = VoterManager() voter_results = voter_manager.retrieve_voter_from_voter_device_id( voter_device_id) voter_id = voter_results['voter_id'] if not positive_value_exists(voter_id): json_data = { 'status': "VOTER_NOT_FOUND_FROM_VOTER_DEVICE_ID", 'success': False, 'voter_device_id': voter_device_id, 'quick_info_id': quick_info_id, 'quick_info_we_vote_id': quick_info_we_vote_id, 'new_quick_info_created': False, 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return HttpResponse(json.dumps(json_data), content_type='application/json') voter = voter_results['voter'] quick_info_id = convert_to_int(quick_info_id) quick_info_we_vote_id = quick_info_we_vote_id.strip().lower() existing_unique_identifier_found = positive_value_exists(quick_info_id) \ or positive_value_exists(quick_info_we_vote_id) new_unique_identifier_found = positive_value_exists(voter_id) \ and positive_value_exists(google_civic_election_id) and ( positive_value_exists(office_we_vote_id) or positive_value_exists(candidate_we_vote_id) or positive_value_exists(measure_we_vote_id) ) unique_identifier_found = existing_unique_identifier_found or new_unique_identifier_found # We must have these variables in order to create a new entry required_variables_for_new_entry = positive_value_exists(voter_id) \ and positive_value_exists(google_civic_election_id) and ( positive_value_exists(office_we_vote_id) or positive_value_exists(candidate_we_vote_id) or positive_value_exists(measure_we_vote_id) ) if not unique_identifier_found: results = { 'status': "QUICK_INFO_REQUIRED_UNIQUE_IDENTIFIER_VARIABLES_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'quick_info_id': quick_info_id, 'quick_info_we_vote_id': quick_info_we_vote_id, 'new_quick_info_created': False, 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return results elif not existing_unique_identifier_found and not required_variables_for_new_entry: results = { 'status': "NEW_QUICK_INFO_REQUIRED_VARIABLES_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'quick_info_id': quick_info_id, 'quick_info_we_vote_id': quick_info_we_vote_id, 'new_quick_info_created': False, 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return results quick_info_manager = QuickInfoManager() save_results = quick_info_manager.update_or_create_quick_info( quick_info_id=quick_info_id, quick_info_we_vote_id=quick_info_we_vote_id, voter_we_vote_id=voter.we_vote_id, google_civic_election_id=google_civic_election_id, office_we_vote_id=office_we_vote_id, candidate_we_vote_id=candidate_we_vote_id, measure_we_vote_id=measure_we_vote_id, statement_text=statement_text, statement_html=statement_html, ) if save_results['success']: quick_info = save_results['quick_info'] results = { 'success': save_results['success'], 'status': save_results['status'], 'voter_device_id': voter_device_id, 'quick_info_id': quick_info.id, 'quick_info_we_vote_id': quick_info.we_vote_id, 'new_quick_info_created': save_results['new_quick_info_created'], 'is_support': quick_info.is_support(), 'is_oppose': quick_info.is_oppose(), 'is_information_only': quick_info.is_information_only(), 'google_civic_election_id': quick_info.google_civic_election_id, 'office_we_vote_id': quick_info.contest_office_we_vote_id, 'candidate_we_vote_id': quick_info.candidate_campaign_we_vote_id, 'measure_we_vote_id': quick_info.contest_measure_we_vote_id, 'statement_text': quick_info.statement_text, 'statement_html': quick_info.statement_html, 'last_updated': '', } return results else: results = { 'success': False, 'status': save_results['status'], 'voter_device_id': voter_device_id, 'quick_info_id': quick_info_id, 'quick_info_we_vote_id': quick_info_we_vote_id, 'new_quick_info_created': False, 'is_support': False, 'is_oppose': False, 'is_information_only': False, 'google_civic_election_id': google_civic_election_id, 'office_we_vote_id': office_we_vote_id, 'candidate_we_vote_id': candidate_we_vote_id, 'measure_we_vote_id': measure_we_vote_id, 'statement_text': statement_text, 'statement_html': statement_html, 'last_updated': '', } return results
def test_count_with_no_cookie(self): """ This API should work even if person isn't signed in :return: """ ####################################### # Check to see if there are 0 voters response = self.client.get(self.voter_count_url) json_data = json.loads(response.content.decode()) # Python3 solution? Problem is refused connection # req = Request(self.voter_count_url) # response = urlopen(req) # json_data = response.read() self.assertEqual('success' in json_data, True, "'success' expected in the json response, and not found") self.assertEqual('voter_count' in json_data, True, "'voter_count' expected in the voterCount json response") self.assertEqual( json_data['voter_count'], 0, "success: {success} (voter_count '0' expected), voter_count: {voter_count}".format( success=json_data['success'], voter_count=json_data['voter_count'])) ####################################### # Add 3 voters so we can check count again voter_manager = VoterManager() email1 = "*****@*****.**" voter_manager.create_voter( email=email1, password="******", ) email2 = "*****@*****.**" voter_manager.create_voter( email=email2, password="******", ) email3 = "*****@*****.**" voter_manager.create_voter( email=email3, password="******", ) ####################################### # Check to see if there are 3 voters response2 = self.client.get(self.voter_count_url) json_data2 = json.loads(response2.content.decode()) self.assertEqual('success' in json_data2, True, "'success' expected in the json response, and not found") self.assertEqual('voter_count' in json_data2, True, "'voter_count' expected in the voterCount json response") self.assertEqual( json_data2['voter_count'], 3, "success: {success} (voter_count '3' expected), voter_count: {voter_count}".format( success=json_data2['success'], voter_count=json_data2['voter_count'])) ####################################### # Remove data for 3 voters voter_manager.delete_voter(email1) voter_manager.delete_voter(email2) voter_manager.delete_voter(email3) ####################################### # Check to see if there are 0 voters response3 = self.client.get(self.voter_count_url) json_data3 = json.loads(response3.content.decode()) self.assertEqual('success' in json_data, True, "'success' expected in the json response, and not found") self.assertEqual('voter_count' in json_data3, True, "'voter_count' expected in the voterCount json response") self.assertEqual( json_data3['voter_count'], 0, "success: {success} (voter_count '0' expected - 2nd pass), voter_count: {voter_count}".format( success=json_data3['success'], voter_count=json_data3['voter_count']))
def twitter_sign_in_start_for_api(voter_device_id, return_url): # twitterSignInStart """ :param voter_device_id: :param return_url: Where to direct the browser at the very end of the process :return: """ # Get voter_id from the voter_device_id results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', 'voter_info_retrieved': False, 'switch_accounts': False, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id( voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'status': "VALID_VOTER_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', 'voter_info_retrieved': False, 'switch_accounts': False, } return results voter = results['voter'] if voter.twitter_access_token and voter.twitter_access_secret: # If here the voter might already be signed in, so we don't want to ask them to approve again auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) auth.set_access_token(voter.twitter_access_token, voter.twitter_access_secret) api = tweepy.API(auth) try: tweepy_user_object = api.me() success = True # What is the error situation where the twitter_access_token and twitter_access_secret are no longer valid? # We need to deal with this (wipe them from the database and rewind to the right place in the process except tweepy.RateLimitError: success = False status = 'TWITTER_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = '' error_tuple = error_instance.args for error_dict in error_tuple: for one_error in error_dict: status += '[' + one_error['message'] + '] ' if success: # Reach out to the twitterSignInRequestVoterInfo -- no need to redirect empty_return_url = "" voter_info_results = twitter_sign_in_request_voter_info_for_api( voter_device_id, empty_return_url) success = voter_info_results['success'] status = "SKIPPED_AUTH_DIRECT_REQUEST_VOTER_INFO: " + voter_info_results[ 'status'] results = { 'status': status, 'success': success, 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', 'voter_info_retrieved': voter_info_results['voter_info_retrieved'], 'switch_accounts': voter_info_results[ 'switch_accounts'], # If true, new voter_device_id returned } return results else: # Somehow reset tokens and start over. pass callback_url = WE_VOTE_SERVER_ROOT_URL + "/apis/v1/twitterSignInRequestAccessToken/" callback_url += "?voter_device_id=" + voter_device_id callback_url += "&return_url=" + return_url # This is where twitter_authorization_url = '' try: # We take the Consumer Key and the Consumer Secret, and request a token & token_secret auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, callback_url) twitter_authorization_url = auth.get_authorization_url() request_token_dict = auth.request_token twitter_request_token = '' twitter_request_token_secret = '' if 'oauth_token' in request_token_dict: twitter_request_token = request_token_dict['oauth_token'] if 'oauth_token_secret' in request_token_dict: twitter_request_token_secret = request_token_dict[ 'oauth_token_secret'] # We save these values in the Voter table, and then return a twitter_authorization_url where the voter signs in # Once they sign in to the Twitter login, they are redirected back to the We Vote callback_url # On that callback_url page, we are told if they are signed in # on Twitter or not, and capture an access key we can use to retrieve information about the Twitter user # NOTE: Regarding the callback url, I think this can just be a direct call to the API server, # since we have the voter_device_id if positive_value_exists( twitter_request_token) and positive_value_exists( twitter_request_token_secret): voter.twitter_request_token = twitter_request_token voter.twitter_request_secret = twitter_request_token_secret voter.save() success = True status = "TWITTER_REDIRECT_URL_RETRIEVED" else: success = False status = "TWITTER_REDIRECT_URL_NOT_RETRIEVED" except tweepy.RateLimitError: success = False status = 'TWITTER_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = 'TWITTER_SIGN_IN_START: ' error_tuple = error_instance.args for error_dict in error_tuple: for one_error in error_dict: status += '[' + one_error['message'] + '] ' if success: results = { 'status': status, 'success': True, 'voter_device_id': voter_device_id, 'twitter_redirect_url': twitter_authorization_url, 'voter_info_retrieved': False, 'switch_accounts': False, } else: results = { 'status': status, 'success': False, 'voter_device_id': voter_device_id, 'twitter_redirect_url': '', 'voter_info_retrieved': False, 'switch_accounts': False, } return results
def quick_info_text_save_for_api( # TODO to be converted voter_device_id, quick_info_id, quick_info_we_vote_id, google_civic_election_id, office_we_vote_id, candidate_we_vote_id, measure_we_vote_id, statement_text, statement_html, ): results = is_voter_device_id_valid(voter_device_id) if not results["success"]: json_data_from_results = results["json_data"] json_data = { "status": json_data_from_results["status"], "success": False, "voter_device_id": voter_device_id, "quick_info_id": quick_info_id, "quick_info_we_vote_id": quick_info_we_vote_id, "new_quick_info_created": False, "is_support": False, "is_oppose": False, "is_information_only": False, "google_civic_election_id": google_civic_election_id, "office_we_vote_id": office_we_vote_id, "candidate_we_vote_id": candidate_we_vote_id, "measure_we_vote_id": measure_we_vote_id, "statement_text": statement_text, "statement_html": statement_html, "last_updated": "", } return HttpResponse(json.dumps(json_data), content_type="application/json") voter_manager = VoterManager() voter_results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) voter_id = voter_results["voter_id"] if not positive_value_exists(voter_id): json_data = { "status": "VOTER_NOT_FOUND_FROM_VOTER_DEVICE_ID", "success": False, "voter_device_id": voter_device_id, "quick_info_id": quick_info_id, "quick_info_we_vote_id": quick_info_we_vote_id, "new_quick_info_created": False, "is_support": False, "is_oppose": False, "is_information_only": False, "google_civic_election_id": google_civic_election_id, "office_we_vote_id": office_we_vote_id, "candidate_we_vote_id": candidate_we_vote_id, "measure_we_vote_id": measure_we_vote_id, "statement_text": statement_text, "statement_html": statement_html, "last_updated": "", } return HttpResponse(json.dumps(json_data), content_type="application/json") voter = voter_results["voter"] quick_info_id = convert_to_int(quick_info_id) quick_info_we_vote_id = quick_info_we_vote_id.strip() existing_unique_identifier_found = positive_value_exists(quick_info_id) or positive_value_exists( quick_info_we_vote_id ) new_unique_identifier_found = ( positive_value_exists(voter_id) and positive_value_exists(google_civic_election_id) and ( positive_value_exists(office_we_vote_id) or positive_value_exists(candidate_we_vote_id) or positive_value_exists(measure_we_vote_id) ) ) unique_identifier_found = existing_unique_identifier_found or new_unique_identifier_found # We must have these variables in order to create a new entry required_variables_for_new_entry = ( positive_value_exists(voter_id) and positive_value_exists(google_civic_election_id) and ( positive_value_exists(office_we_vote_id) or positive_value_exists(candidate_we_vote_id) or positive_value_exists(measure_we_vote_id) ) ) if not unique_identifier_found: results = { "status": "QUICK_INFO_REQUIRED_UNIQUE_IDENTIFIER_VARIABLES_MISSING", "success": False, "voter_device_id": voter_device_id, "quick_info_id": quick_info_id, "quick_info_we_vote_id": quick_info_we_vote_id, "new_quick_info_created": False, "is_support": False, "is_oppose": False, "is_information_only": False, "google_civic_election_id": google_civic_election_id, "office_we_vote_id": office_we_vote_id, "candidate_we_vote_id": candidate_we_vote_id, "measure_we_vote_id": measure_we_vote_id, "statement_text": statement_text, "statement_html": statement_html, "last_updated": "", } return results elif not existing_unique_identifier_found and not required_variables_for_new_entry: results = { "status": "NEW_QUICK_INFO_REQUIRED_VARIABLES_MISSING", "success": False, "voter_device_id": voter_device_id, "quick_info_id": quick_info_id, "quick_info_we_vote_id": quick_info_we_vote_id, "new_quick_info_created": False, "is_support": False, "is_oppose": False, "is_information_only": False, "google_civic_election_id": google_civic_election_id, "office_we_vote_id": office_we_vote_id, "candidate_we_vote_id": candidate_we_vote_id, "measure_we_vote_id": measure_we_vote_id, "statement_text": statement_text, "statement_html": statement_html, "last_updated": "", } return results quick_info_manager = QuickInfoManager() save_results = quick_info_manager.update_or_create_quick_info( quick_info_id=quick_info_id, quick_info_we_vote_id=quick_info_we_vote_id, voter_we_vote_id=voter.we_vote_id, google_civic_election_id=google_civic_election_id, office_we_vote_id=office_we_vote_id, candidate_we_vote_id=candidate_we_vote_id, measure_we_vote_id=measure_we_vote_id, statement_text=statement_text, statement_html=statement_html, ) if save_results["success"]: quick_info = save_results["quick_info"] results = { "success": save_results["success"], "status": save_results["status"], "voter_device_id": voter_device_id, "quick_info_id": quick_info.id, "quick_info_we_vote_id": quick_info.we_vote_id, "new_quick_info_created": save_results["new_quick_info_created"], "is_support": quick_info.is_support(), "is_oppose": quick_info.is_oppose(), "is_information_only": quick_info.is_information_only(), "google_civic_election_id": quick_info.google_civic_election_id, "office_we_vote_id": quick_info.contest_office_we_vote_id, "candidate_we_vote_id": quick_info.candidate_campaign_we_vote_id, "measure_we_vote_id": quick_info.contest_measure_we_vote_id, "statement_text": quick_info.statement_text, "statement_html": quick_info.statement_html, "last_updated": "", } return results else: results = { "success": False, "status": save_results["status"], "voter_device_id": voter_device_id, "quick_info_id": quick_info_id, "quick_info_we_vote_id": quick_info_we_vote_id, "new_quick_info_created": False, "is_support": False, "is_oppose": False, "is_information_only": False, "google_civic_election_id": google_civic_election_id, "office_we_vote_id": office_we_vote_id, "candidate_we_vote_id": candidate_we_vote_id, "measure_we_vote_id": measure_we_vote_id, "statement_text": statement_text, "statement_html": statement_html, "last_updated": "", } return results
def twitter_sign_in_request_voter_info_for_api(voter_device_id, return_url, switch_accounts_if_needed=True): """ twitterSignInRequestVoterInfo When here, the incoming voter_device_id should already be authenticated :param voter_device_id: :param return_url: Where to return the browser when sign in process is complete :param switch_accounts_if_needed: :return: """ twitter_handle = '' twitter_handle_found = False tweepy_user_object = None twitter_user_object_found = False voter_info_retrieved = False switch_accounts = False # Get voter_id from the voter_device_id results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'twitter_handle': twitter_handle, 'twitter_handle_found': twitter_handle_found, 'voter_info_retrieved': voter_info_retrieved, 'switch_accounts': switch_accounts, 'return_url': return_url, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id( voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'status': "VALID_VOTER_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'twitter_handle': twitter_handle, 'twitter_handle_found': twitter_handle_found, 'voter_info_retrieved': voter_info_retrieved, 'switch_accounts': switch_accounts, 'return_url': return_url, } return results voter = results['voter'] auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) auth.set_access_token(voter.twitter_access_token, voter.twitter_access_secret) api = tweepy.API(auth) try: tweepy_user_object = api.me() twitter_json = tweepy_user_object._json success = True status = 'TWITTER_SIGN_IN_REQUEST_VOTER_INFO_SUCCESSFUL' twitter_handle = tweepy_user_object.screen_name twitter_handle_found = True twitter_user_object_found = True except tweepy.RateLimitError: success = False status = 'TWITTER_SIGN_IN_REQUEST_VOTER_INFO_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = 'TWITTER_SIGN_IN_REQUEST_VOTER_INFO_TWEEPY_ERROR: ' error_tuple = error_instance.args for error_dict in error_tuple: for one_error in error_dict: status += '[' + one_error['message'] + '] ' if twitter_user_object_found: # We need to deal with these cases # 1) Does account already exist? results = voter_manager.retrieve_voter_by_twitter_id( tweepy_user_object.id) if results['voter_found'] and switch_accounts_if_needed: voter_found_with_twitter_id = results['voter'] switch_accounts = True # Relink this voter_device_id to the original account voter_device_manager = VoterDeviceLinkManager() voter_device_link_results = voter_device_manager.retrieve_voter_device_link( voter_device_id) voter_device_link = voter_device_link_results['voter_device_link'] update_voter_device_link_results = voter_device_manager.update_voter_device_link( voter_device_link, voter_found_with_twitter_id) if update_voter_device_link_results['voter_device_link_updated']: # Transfer access token and secret voter_found_with_twitter_id.twitter_access_token = voter.twitter_access_token voter_found_with_twitter_id.twitter_access_secret = voter.twitter_access_secret voter_found_with_twitter_id.save() status += "TWITTER_SIGN_IN-ALREADY_LINKED_TO_OTHER_ACCOUNT-TRANSFERRED " success = True save_user_results = voter_manager.save_twitter_user_values( voter_found_with_twitter_id, tweepy_user_object) if save_user_results['success']: voter_info_retrieved = True status += save_user_results['status'] else: status = "TWITTER_SIGN_IN-ALREADY_LINKED_TO_OTHER_ACCOUNT-COULD_NOT_TRANSFER " success = False # 2) If account doesn't exist for this person, save else: save_user_results = voter_manager.save_twitter_user_values( voter, tweepy_user_object) if save_user_results['success']: voter_info_retrieved = True results = { 'status': status, 'success': success, 'voter_device_id': voter_device_id, 'twitter_handle': twitter_handle, 'twitter_handle_found': twitter_handle_found, 'voter_info_retrieved': voter_info_retrieved, 'switch_accounts': switch_accounts, 'return_url': return_url, } return results
def facebook_sign_in_for_api(voter_device_id, facebook_id=None, facebook_email=None): # facebookSignIn """ :param voter_device_id: :return: """ status = "" success = False # Get voter_id from the voter_device_id results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id( voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'success': False, 'status': "VALID_VOTER_MISSING", 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } return results voter = results['voter'] results_from_facebook_id = voter_manager.retrieve_voter_by_facebook_id( facebook_id) if positive_value_exists(results_from_facebook_id['voter_found']): voter_found_with_facebook_id = results_from_facebook_id['voter'] if voter_found_with_facebook_id.id == voter.id: # If here, the owner of the facebook_id is already the current primary voter status += "FACEBOOK_SIGN_IN-ALREADY_LINKED_TO_THIS_FACEBOOK_ACCOUNT " success = True # Only save if the email is different than what is saved if positive_value_exists(facebook_email) or facebook_email == '': results = voter_manager.save_facebook_user_values( voter, facebook_id, facebook_email) status += results['status'] success = results['success'] else: # If here, we need to merge accounts TODO # ...but for now we are simply going to switch to the earlier account and abandon # the newer account if positive_value_exists(facebook_email) or facebook_email == '': results = voter_manager.save_facebook_user_values( voter_found_with_facebook_id, facebook_id, facebook_email) status += results['status'] + ", " success = results['success'] # Relink this voter_device_id to the original account voter_device_manager = VoterDeviceLinkManager() voter_device_link_results = voter_device_manager.retrieve_voter_device_link( voter_device_id) voter_device_link = voter_device_link_results['voter_device_link'] update_voter_device_link_results = voter_device_manager.update_voter_device_link( voter_device_link, voter_found_with_facebook_id) if update_voter_device_link_results['voter_device_link_updated']: status += "FACEBOOK_SIGN_IN-ALREADY_LINKED_TO_OTHER_ACCOUNT-TRANSFERRED " success = True else: status = "FACEBOOK_SIGN_IN-ALREADY_LINKED_TO_OTHER_ACCOUNT-COULD_NOT_TRANSFER " success = False else: # An existing account linked to this facebook account was not found results = voter_manager.save_facebook_user_values( voter, facebook_id, facebook_email) status = results['status'] success = results['success'] if success: results = { 'success': True, 'status': status, 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } else: results = { 'success': False, 'status': status, 'voter_device_id': voter_device_id, 'facebook_id': facebook_id, 'facebook_email': facebook_email, } return results
def twitter_sign_in_request_access_token_for_api(voter_device_id, incoming_request_token, incoming_oauth_verifier, return_url): """ twitterSignInRequestAccessToken After signing in and agreeing to the application's terms, the user is redirected back to the application with the same request token and another value, this time the OAuth verifier. Within this function we use 1) the request token and 2) request secret along with the 3) OAuth verifier to get an access token, also from Twitter. :param voter_device_id: :param incoming_request_token: :param incoming_oauth_verifier: :param return_url: If a value is provided, return to this URL when the whole process is complete :return: """ # Get voter_id from the voter_device_id results = is_voter_device_id_valid(voter_device_id) if not results['success']: results = { 'success': False, 'status': "VALID_VOTER_DEVICE_ID_MISSING", 'voter_device_id': voter_device_id, 'access_token_and_secret_returned': False, 'return_url': return_url, } return results voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) if not positive_value_exists(results['voter_found']): results = { 'status': "VALID_VOTER_MISSING", 'success': False, 'voter_device_id': voter_device_id, 'access_token_and_secret_returned': False, 'return_url': return_url, } return results voter = results['voter'] if not voter.twitter_request_token == incoming_request_token: results = { 'status': "TWITTER_REQUEST_TOKEN_DOES_NOT_MATCH_STORED_VOTER_VALUE", 'success': False, 'voter_device_id': voter_device_id, 'access_token_and_secret_returned': False, 'return_url': return_url, } return results twitter_access_token = '' twitter_access_token_secret = '' try: # We take the Request Token, Request Secret, and OAuth Verifier and request an access_token auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) auth.request_token = {'oauth_token': voter.twitter_request_token, 'oauth_token_secret': voter.twitter_request_secret} auth.get_access_token(incoming_oauth_verifier) if positive_value_exists(auth.access_token) and positive_value_exists(auth.access_token_secret): twitter_access_token = auth.access_token twitter_access_token_secret = auth.access_token_secret except tweepy.RateLimitError: success = False status = 'TWITTER_RATE_LIMIT_ERROR' except tweepy.error.TweepError as error_instance: success = False status = 'TWITTER_SIGN_IN_REQUEST_ACCESS_TOKEN: ' error_tuple = error_instance.args for error_dict in error_tuple: count = 0 # for one_error in error_dict: # status += '[' + one_error[count] + '] ' # count += 1 try: # We save these values in the Voter table if positive_value_exists(twitter_access_token) and positive_value_exists(twitter_access_token_secret): voter.twitter_access_token = twitter_access_token voter.twitter_access_secret = twitter_access_token_secret voter.save() success = True status = "TWITTER_ACCESS_TOKEN_RETRIEVED_AND_SAVED" else: success = False status = "TWITTER_ACCESS_TOKEN_NOT_RETRIEVED" except Exception as e: success = False status = "TWITTER_ACCESS_TOKEN_NOT_SAVED" if success: results = { 'status': status, 'success': True, 'voter_device_id': voter_device_id, 'access_token_and_secret_returned': True, 'return_url': return_url, } else: results = { 'status': status, 'success': False, 'voter_device_id': voter_device_id, 'access_token_and_secret_returned': False, 'return_url': return_url, } return results
def voter_guides_to_follow_retrieve_for_api(voter_device_id, # voterGuidesToFollow kind_of_ballot_item='', ballot_item_we_vote_id='', google_civic_election_id=0, search_string='', maximum_number_to_retrieve=0): # Get voter_id from the voter_device_id so we can figure out which voter_guides to offer results = is_voter_device_id_valid(voter_device_id) if not results['success']: json_data = { 'status': 'ERROR_GUIDES_TO_FOLLOW_NO_VOTER_DEVICE_ID', 'success': False, 'voter_device_id': voter_device_id, 'voter_guides': [], 'google_civic_election_id': google_civic_election_id, 'search_string': search_string, 'ballot_item_we_vote_id': ballot_item_we_vote_id, } results = { 'success': False, 'google_civic_election_id': 0, # Force the reset of google_civic_election_id cookie 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'json_data': json_data, } return results voter_id = fetch_voter_id_from_voter_device_link(voter_device_id) if not positive_value_exists(voter_id): json_data = { 'status': "ERROR_GUIDES_TO_FOLLOW_VOTER_NOT_FOUND_FROM_VOTER_DEVICE_ID", 'success': False, 'voter_device_id': voter_device_id, 'voter_guides': [], 'google_civic_election_id': google_civic_election_id, 'search_string': search_string, 'ballot_item_we_vote_id': ballot_item_we_vote_id, } results = { 'success': False, 'google_civic_election_id': 0, # Force the reset of google_civic_election_id cookie 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'json_data': json_data, } return results voter_guide_list = [] voter_guides = [] try: if positive_value_exists(kind_of_ballot_item) and positive_value_exists(ballot_item_we_vote_id): results = retrieve_voter_guides_to_follow_by_ballot_item(voter_id, kind_of_ballot_item, ballot_item_we_vote_id, search_string) success = results['success'] status = results['status'] voter_guide_list = results['voter_guide_list'] elif positive_value_exists(google_civic_election_id): # This retrieve also does the reordering results = retrieve_voter_guides_to_follow_by_election_for_api(voter_id, google_civic_election_id, search_string, maximum_number_to_retrieve, 'twitter_followers_count', 'desc') success = results['success'] status = results['status'] voter_guide_list = results['voter_guide_list'] else: results = retrieve_voter_guides_to_follow_generic_for_api(voter_id, search_string, maximum_number_to_retrieve, 'twitter_followers_count', 'desc') success = results['success'] status = results['status'] voter_guide_list = results['voter_guide_list'] except Exception as e: status = 'FAILED voter_guides_to_follow_retrieve_for_api, retrieve_voter_guides_for_election ' \ '{error} [type: {error_type}]'.format(error=e, error_type=type(e)) success = False if success: voter_manager = VoterManager() results = voter_manager.retrieve_voter_by_id(voter_id) linked_organization_we_vote_id = "" if results['voter_found']: voter = results['voter'] linked_organization_we_vote_id = voter.linked_organization_we_vote_id number_added_to_list = 0 position_manager = PositionEnteredManager() position = PositionEntered() for voter_guide in voter_guide_list: if positive_value_exists(voter_guide.organization_we_vote_id) \ and linked_organization_we_vote_id == voter_guide.organization_we_vote_id: # Do not return your own voter guide to follow continue position_found = False one_voter_guide = { 'we_vote_id': voter_guide.we_vote_id, 'google_civic_election_id': voter_guide.google_civic_election_id, 'time_span': voter_guide.vote_smart_time_span, 'voter_guide_display_name': voter_guide.voter_guide_display_name(), 'voter_guide_image_url': voter_guide.voter_guide_image_url(), 'voter_guide_owner_type': voter_guide.voter_guide_owner_type, 'organization_we_vote_id': voter_guide.organization_we_vote_id, 'public_figure_we_vote_id': voter_guide.public_figure_we_vote_id, 'twitter_description': voter_guide.twitter_description, 'twitter_followers_count': voter_guide.twitter_followers_count, 'twitter_handle': voter_guide.twitter_handle, 'owner_voter_id': voter_guide.owner_voter_id, 'last_updated': voter_guide.last_updated.strftime('%Y-%m-%d %H:%M'), } if positive_value_exists(ballot_item_we_vote_id): if kind_of_ballot_item == CANDIDATE: organization_manager = OrganizationManager() organization_id = organization_manager.fetch_organization_id( voter_guide.organization_we_vote_id) results = position_manager.retrieve_organization_candidate_campaign_position_with_we_vote_id( organization_id, ballot_item_we_vote_id) if results['position_found']: position = results['position'] position_found = True elif kind_of_ballot_item == MEASURE: organization_manager = OrganizationManager() organization_id = organization_manager.fetch_organization_id( voter_guide.organization_we_vote_id) results = position_manager.retrieve_organization_contest_measure_position_with_we_vote_id( organization_id, ballot_item_we_vote_id) if results['position_found']: position = results['position'] position_found = True if position_found: one_voter_guide['is_support'] = position.is_support() one_voter_guide['is_positive_rating'] = position.is_positive_rating() one_voter_guide['is_support_or_positive_rating'] = position.is_support_or_positive_rating() one_voter_guide['is_oppose'] = position.is_oppose() one_voter_guide['is_negative_rating'] = position.is_negative_rating() one_voter_guide['is_oppose_or_negative_rating'] = position.is_oppose_or_negative_rating() one_voter_guide['is_information_only'] = position.is_information_only() one_voter_guide['ballot_item_display_name'] = position.ballot_item_display_name one_voter_guide['speaker_display_name'] = position.speaker_display_name one_voter_guide['statement_text'] = position.statement_text one_voter_guide['more_info_url'] = position.more_info_url one_voter_guide['vote_smart_rating'] = position.vote_smart_rating one_voter_guide['vote_smart_time_span'] = position.vote_smart_time_span voter_guides.append(one_voter_guide.copy()) if positive_value_exists(maximum_number_to_retrieve): number_added_to_list += 1 if number_added_to_list >= maximum_number_to_retrieve: break if len(voter_guides): json_data = { 'status': status + ' VOTER_GUIDES_TO_FOLLOW_RETRIEVED', 'success': True, 'voter_device_id': voter_device_id, 'voter_guides': voter_guides, 'google_civic_election_id': google_civic_election_id, 'search_string': search_string, 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'maximum_number_to_retrieve': maximum_number_to_retrieve, } else: json_data = { 'status': status + ' NO_VOTER_GUIDES_FOUND', 'success': True, 'voter_device_id': voter_device_id, 'voter_guides': voter_guides, 'google_civic_election_id': google_civic_election_id, 'search_string': search_string, 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'maximum_number_to_retrieve': maximum_number_to_retrieve, } results = { 'success': success, 'google_civic_election_id': google_civic_election_id, 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'json_data': json_data, } return results else: json_data = { 'status': status, 'success': False, 'voter_device_id': voter_device_id, 'voter_guides': [], 'google_civic_election_id': google_civic_election_id, 'search_string': search_string, 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'maximum_number_to_retrieve': maximum_number_to_retrieve, } results = { 'success': False, 'google_civic_election_id': 0, # Force the reset of google_civic_election_id cookie 'ballot_item_we_vote_id': ballot_item_we_vote_id, 'json_data': json_data, } return results
def login_user(request): """ This method is called when you login from the /login/ form :param request: :return: """ voter_api_device_id = get_voter_api_device_id( request) # We look in the cookies for voter_api_device_id store_new_voter_api_device_id_in_cookie = False voter_signed_in = False voter_manager = VoterManager() voter_device_link_manager = VoterDeviceLinkManager() results = voter_manager.retrieve_voter_from_voter_device_id( voter_api_device_id) if results['voter_found']: voter_on_stage = results['voter'] voter_on_stage_id = voter_on_stage.id # Just because a We Vote voter is found doesn't mean they are authenticated for Django else: voter_on_stage_id = 0 info_message = '' error_message = '' username = '' # Does Django think user is already signed in? if request.user.is_authenticated(): # If so, make sure user and voter_on_stage are the same. if request.user.id != voter_on_stage_id: # Delete the prior voter_api_device_id from database voter_device_link_manager.delete_voter_device_link( voter_api_device_id) # Create a new voter_api_device_id and voter_device_link voter_api_device_id = generate_voter_device_id() results = voter_device_link_manager.save_new_voter_device_link( voter_api_device_id, request.user.id) store_new_voter_api_device_id_in_cookie = results[ 'voter_device_link_created'] voter_on_stage = request.user voter_on_stage_id = voter_on_stage.id elif request.POST: username = request.POST.get('username') password = request.POST.get('password') user = authenticate(username=username, password=password) if user is not None: if user.is_active: login(request, user) info_message = "You're successfully logged in!" # Delete the prior voter_api_device_id from database voter_device_link_manager.delete_voter_device_link( voter_api_device_id) # Create a new voter_api_device_id and voter_device_link voter_api_device_id = generate_voter_device_id() results = voter_device_link_manager.save_new_voter_device_link( voter_api_device_id, user.id) store_new_voter_api_device_id_in_cookie = results[ 'voter_device_link_created'] else: error_message = "Your account is not active, please contact the site admin." if user.id != voter_on_stage_id: # Eventually we want to merge voter_on_stage into user account pass else: error_message = "Your username and/or password were incorrect." elif not positive_value_exists(voter_on_stage_id): # If here, delete the prior voter_api_device_id from database voter_device_link_manager.delete_voter_device_link(voter_api_device_id) # We then need to set a voter_api_device_id cookie and create a new voter (even though not signed in) results = voter_setup(request) voter_api_device_id = results['voter_api_device_id'] store_new_voter_api_device_id_in_cookie = results[ 'store_new_voter_api_device_id_in_cookie'] # Does Django think user is signed in? if request.user.is_authenticated(): voter_signed_in = True else: info_message = "Please log in below..." if positive_value_exists(error_message): messages.add_message(request, messages.ERROR, error_message) if positive_value_exists(info_message): messages.add_message(request, messages.INFO, info_message) messages_on_stage = get_messages(request) template_values = { 'request': request, 'username': username, 'next': next, 'voter_signed_in': voter_signed_in, 'messages_on_stage': messages_on_stage, } response = render(request, 'registration/login_user.html', template_values) # We want to store the voter_api_device_id cookie if it is new if positive_value_exists(voter_api_device_id) and positive_value_exists( store_new_voter_api_device_id_in_cookie): set_voter_api_device_id(request, response, voter_api_device_id) return response
def voter_retrieve_list_for_api(voter_device_id): results = is_voter_device_id_valid(voter_device_id) if not results['success']: results2 = { 'success': False, 'json_data': results['json_data'], } return results2 voter_id = fetch_voter_id_from_voter_device_link(voter_device_id) if voter_id > 0: voter_manager = VoterManager() results = voter_manager.retrieve_voter_by_id(voter_id) if results['voter_found']: voter_id = results['voter_id'] else: # If we are here, the voter_id could not be found from the voter_device_id json_data = { 'status': "VOTER_NOT_FOUND_FROM_DEVICE_ID", 'success': False, 'voter_device_id': voter_device_id, } results = { 'success': False, 'json_data': json_data, } return results if voter_id: voter_list = Voter.objects.all() voter_list = voter_list.filter(id=voter_id) if len(voter_list): results = { 'success': True, 'voter_list': voter_list, } return results # Trying to mimic the Google Civic error codes scheme errors_list = [ { 'domain': "TODO global", 'reason': "TODO reason", 'message': "TODO Error message here", 'locationType': "TODO Error message here", 'location': "TODO location", } ] error_package = { 'errors': errors_list, 'code': 400, 'message': "Error message here", } json_data = { 'error': error_package, 'status': "VOTER_ID_COULD_NOT_BE_RETRIEVED", 'success': False, 'voter_device_id': voter_device_id, } results = { 'success': False, 'json_data': json_data, } return results
def test_count_with_cookie(self): """ Test the various cookie states :return: """ ####################################### # Generate the voter_device_id cookie response0 = self.client.get(self.generate_voter_device_id_url) json_data0 = json.loads(response0.content.decode()) # Make sure we got back a voter_device_id we can use self.assertEqual('voter_device_id' in json_data0, True, "voter_device_id expected in the deviceIdGenerateView json response") # Now save the retrieved voter_device_id in a mock cookie cookies = SimpleCookie() cookies["voter_device_id"] = json_data0['voter_device_id'] self.client = Client(HTTP_COOKIE=cookies.output(header='', sep='; ')) ####################################### # Test for status: VOTER_CREATED response02 = self.client.get(self.voter_create_url) json_data02 = json.loads(response02.content.decode()) self.assertEqual('status' in json_data02, True, "status expected in the voterCreateView json response but not found") self.assertEqual('voter_device_id' in json_data02, True, "voter_device_id expected in the voterCreateView json response but not found") # With a brand new voter_device_id, a new voter record should be created self.assertEqual( json_data02['status'], 'VOTER_CREATED', "status: {status} (VOTER_CREATED expected), voter_device_id: {voter_device_id}".format( status=json_data02['status'], voter_device_id=json_data02['voter_device_id'])) ####################################### # Check to see if there is 1 voter - i.e., the viewer response11 = self.client.get(self.voter_count_url) json_data11 = json.loads(response11.content.decode()) self.assertEqual('success' in json_data11, True, "'success' expected in the json response, and not found") self.assertEqual('voter_count' in json_data11, True, "'voter_count' expected in the voterCount json response") self.assertEqual( json_data11['voter_count'], 1, "success: {success} (voter_count '1' expected), voter_count: {voter_count}".format( success=json_data11['success'], voter_count=json_data11['voter_count'])) ####################################### # Add 3 voters so we can check count again voter_manager = VoterManager() email1 = "*****@*****.**" voter_manager.create_voter( email=email1, password="******", ) email2 = "*****@*****.**" voter_manager.create_voter( email=email2, password="******", ) email3 = "*****@*****.**" voter_manager.create_voter( email=email3, password="******", ) ####################################### # Check to see if there are 4 voters response12 = self.client.get(self.voter_count_url) json_data12 = json.loads(response12.content.decode()) self.assertEqual('success' in json_data12, True, "'success' expected in the json response, and not found") self.assertEqual('voter_count' in json_data12, True, "'voter_count' expected in the voterCount json response") self.assertEqual( json_data12['voter_count'], 4, "success: {success} (voter_count '4' expected), voter_count: {voter_count}".format( success=json_data12['success'], voter_count=json_data12['voter_count']))
def voter_create_for_api(voter_device_id): # voterCreate # If a voter_device_id isn't passed in, automatically create a new voter_device_id if not positive_value_exists(voter_device_id): voter_device_id = generate_voter_device_id() else: # If a voter_device_id is passed in that isn't valid, we want to throw an error results = is_voter_device_id_valid(voter_device_id) if not results['success']: return HttpResponse(json.dumps(results['json_data']), content_type='application/json') voter_id = 0 voter_we_vote_id = '' # Make sure a voter record hasn't already been created for this voter_manager = VoterManager() results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) if results['voter_found']: voter = results['voter'] voter_id = voter.id voter_we_vote_id = voter.we_vote_id json_data = { 'status': "VOTER_ALREADY_EXISTS", 'success': True, 'voter_device_id': voter_device_id, 'voter_id': voter_id, 'voter_we_vote_id': voter_we_vote_id, } return HttpResponse(json.dumps(json_data), content_type='application/json') # Create a new voter and return the voter_device_id voter_manager = VoterManager() results = voter_manager.create_voter() if results['voter_created']: voter = results['voter'] # Now save the voter_device_link voter_device_link_manager = VoterDeviceLinkManager() results = voter_device_link_manager.save_new_voter_device_link(voter_device_id, voter.id) if results['voter_device_link_created']: voter_device_link = results['voter_device_link'] voter_id_found = True if voter_device_link.voter_id > 0 else False if voter_id_found: voter_id = voter.id voter_we_vote_id = voter.we_vote_id if voter_id: json_data = { 'status': "VOTER_CREATED", 'success': True, 'voter_device_id': voter_device_id, 'voter_id': voter_id, 'voter_we_vote_id': voter_we_vote_id, } return HttpResponse(json.dumps(json_data), content_type='application/json') else: json_data = { 'status': "VOTER_NOT_CREATED", 'success': False, 'voter_device_id': voter_device_id, 'voter_id': 0, 'voter_we_vote_id': '', } return HttpResponse(json.dumps(json_data), content_type='application/json')
def organization_save_for_api(voter_device_id, organization_id, organization_we_vote_id, # organizationSave organization_name, organization_email, organization_website, organization_twitter_handle, organization_facebook, organization_image, refresh_from_twitter): organization_id = convert_to_int(organization_id) organization_we_vote_id = organization_we_vote_id.strip().lower() # Make sure we are only working with the twitter handle, and not the "https" or "@" organization_twitter_handle = extract_twitter_handle_from_text_string(organization_twitter_handle) existing_unique_identifier_found = positive_value_exists(organization_id) \ or positive_value_exists(organization_we_vote_id) new_unique_identifier_found = positive_value_exists(organization_twitter_handle) \ or positive_value_exists(organization_website) unique_identifier_found = existing_unique_identifier_found or new_unique_identifier_found # We must have one of these: twitter_handle or website, AND organization_name required_variables_for_new_entry = positive_value_exists(organization_twitter_handle) \ or positive_value_exists(organization_website) and positive_value_exists(organization_name) if not unique_identifier_found: results = { 'status': "ORGANIZATION_REQUIRED_UNIQUE_IDENTIFIER_VARIABLES_MISSING", 'success': False, 'organization_id': organization_id, 'organization_we_vote_id': organization_we_vote_id, 'new_organization_created': False, 'organization_name': organization_name, 'organization_email': organization_email, 'organization_website': organization_website, 'organization_facebook': organization_facebook, 'organization_photo_url': organization_image, 'organization_twitter_handle': organization_twitter_handle, 'twitter_followers_count': 0, 'twitter_description': "", 'refresh_from_twitter': refresh_from_twitter, } return results elif not existing_unique_identifier_found and not required_variables_for_new_entry: results = { 'status': "NEW_ORGANIZATION_REQUIRED_VARIABLES_MISSING", 'success': False, 'organization_id': organization_id, 'organization_we_vote_id': organization_we_vote_id, 'new_organization_created': False, 'organization_name': organization_name, 'organization_email': organization_email, 'organization_website': organization_website, 'organization_facebook': organization_facebook, 'organization_photo_url': organization_image, 'organization_twitter_handle': organization_twitter_handle, 'twitter_followers_count': 0, 'twitter_description': "", 'refresh_from_twitter': refresh_from_twitter, } return results organization_manager = OrganizationManager() save_results = organization_manager.update_or_create_organization( organization_id=organization_id, we_vote_id=organization_we_vote_id, organization_website_search=organization_website, organization_twitter_search=organization_twitter_handle, organization_name=organization_name, organization_website=organization_website, organization_twitter_handle=organization_twitter_handle, organization_email=organization_email, organization_facebook=organization_facebook, organization_image=organization_image, refresh_from_twitter=refresh_from_twitter) if save_results['success']: organization = save_results['organization'] status = save_results['status'] # Now update the voter record with the organization_we_vote_id voter_manager = VoterManager() voter_results = voter_manager.retrieve_voter_from_voter_device_id(voter_device_id) if voter_results['voter_found']: voter = voter_results['voter'] # Does this voter have the same Twitter handle as this organization? If so, link this organization to # this particular voter if voter.twitter_screen_name.lower() == organization.organization_twitter_handle.lower(): try: voter.linked_organization_we_vote_id = organization.we_vote_id voter.save() except Exception as e: status += " UNABLE_TO_UPDATE_VOTER_WITH_ORGANIZATION_WE_VOTE_ID" # If not, then this is a volunteer or admin setting up an organization else: status += " DID_NOT_UPDATE_VOTER_WITH_ORGANIZATION_WE_VOTE_ID-VOTER_DOES_NOT_MATCH_TWITTER_HANDLE" results = { 'success': save_results['success'], 'status': status, 'voter_device_id': voter_device_id, 'organization_id': organization.id, 'organization_we_vote_id': organization.we_vote_id, 'new_organization_created': save_results['new_organization_created'], 'organization_name': organization.organization_name if positive_value_exists(organization.organization_name) else '', 'organization_email': organization.organization_email if positive_value_exists(organization.organization_email) else '', 'organization_website': organization.organization_website if positive_value_exists(organization.organization_website) else '', 'organization_facebook': organization.organization_facebook if positive_value_exists(organization.organization_facebook) else '', 'organization_photo_url': organization.organization_photo_url() if positive_value_exists(organization.organization_photo_url()) else '', 'organization_twitter_handle': organization.organization_twitter_handle if positive_value_exists( organization.organization_twitter_handle) else '', 'twitter_followers_count': organization.twitter_followers_count if positive_value_exists( organization.twitter_followers_count) else 0, 'twitter_description': organization.twitter_description if positive_value_exists( organization.twitter_description) else '', 'refresh_from_twitter': refresh_from_twitter, } return results else: results = { 'success': False, 'status': save_results['status'], 'voter_device_id': voter_device_id, 'organization_id': organization_id, 'organization_we_vote_id': organization_we_vote_id, 'new_organization_created': save_results['new_organization_created'], 'organization_name': organization_name, 'organization_email': organization_email, 'organization_website': organization_website, 'organization_facebook': organization_facebook, 'organization_photo_url': organization_image, 'organization_twitter_handle': organization_twitter_handle, 'twitter_followers_count': 0, 'twitter_description': "", 'refresh_from_twitter': refresh_from_twitter, } return results