def index(request): """ Step 1 of Google OAuth 2.0 flow. """ # Create and store the per-user flow object FLOW = flow_from_clientsecrets( CLIENT_SECRETS, scope=request.session.get('gauth_scope', ''), redirect_uri=request.build_absolute_uri(reverse('gauth_callback'))) FLOW.params['access_type'] = 'offline' FLOW.params['approval_prompt'] = 'force' # Properly gets refresh token FLOW.params['include_granted_scopes'] = 'true' # incremental authorization FLOW.params['state'] = xsrfutil.generate_token(settings.SECRET_KEY, request.user) authorize_url = FLOW.step1_get_authorize_url() flow_storage = Storage(FlowModel, 'id', request.user, 'flow') flow_storage.put(FLOW) # Don't worry if a next parameter is not set. `auth_return` will use the # homepage by default. Allows for `next_view` to be set from other places. try: request.session['next_view'] = request.GET['next'] except KeyError: pass return redirect(authorize_url)
def auth_granted(request): get_params = request.GET try: if 'error' in get_params: raise ValueError('Error authorizing application: %s' % get_params[error]) session_key = request.session.session_key session = Session.objects.get(pk = session_key) flow_obj = FlowModel.objects.get(session_id = session) flow = flow_obj.flow credentials = flow.step2_exchange(get_params["code"]) http = httplib2.Http() http = credentials.authorize(http) (resp, content) = http.request("https://drchrono.com/api/users/current", "GET") data = json.loads(content.decode("utf-8")) print(data) doctor_id = data['doctor'] doctor = Doctor(pk = doctor_id) doctor.save() storage = Storage(CredentialsModel, 'doctor_id', doctor_id, "credential") storage.put(credentials) except ValueError as err: print('Handling run-time error: ', err) return render(request, "success.html")
def get_access_token(credentials, integration_type, code=None): """ Generic function to retrieve an OAuth 2.0 access token. Args: credentials (object): Contains the OAuth 2.0 credentials needed to retrieve a token. integration_type (str): Name of the integration for which the credentials should be retrieved. code (str, optional): Authorization code which will be exchanged for an access token. Returns: credentials (object): Updated credentials with a new access token. """ payload = { 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, } if code: # Trade the auth code for an access token. payload.update({ 'grant_type': 'authorization_code', 'redirect_uri': credentials.redirect_uri, 'code': code }) else: # Already authenticated once, but access token expired. payload.update({ 'grant_type': 'refresh_token', 'refresh_token': credentials.refresh_token }) integration_type = IntegrationType.objects.get( name__iexact=integration_type) response = requests.post( url=integration_type.token_url, data=payload, ) if response.status_code == 200: data = response.json() expires = data.get('expires_in') credentials.access_token = data.get('access_token') credentials.refresh_token = data.get('refresh_token') if expires: credentials.expires = timezone.now() + timedelta(seconds=expires) details = IntegrationDetails.objects.get(type=integration_type.id) storage = Storage(IntegrationCredentials, 'details', details, 'credentials') storage.put(credentials) return credentials else: return None
def get(self, request): # Get the state param from the request. state = str(request.GET.get('state')) # Replace %xx characters with single quotes and UTF8 decode the string. state = urllib.unquote(state).decode('utf8') # Deserialize the JSON string. state = anyjson.deserialize(b64decode(state)) if not validate_token(settings.SECRET_KEY, state.get('token'), request.user.pk): return HttpResponseBadRequest() error = request.GET.get('error') if error: messages.error( self.request, _('Sorry, Lily needs authorization from Google to synchronize your email account.' )) return HttpResponseRedirect('/#/preferences/emailaccounts') credentials = FLOW.step2_exchange(code=request.GET.get('code')) # Setup service to retrieve email address. service = build_gmail_service(credentials) profile = service.users().getProfile(userId='me').execute() # Create account based on email address. account, created = EmailAccount.objects.get_or_create( owner=request.user, email_address=profile.get('emailAddress')) # Store credentials based on new email account. storage = Storage(GmailCredentialsModel, 'id', account, 'credentials') storage.put(credentials) # Set account as authorized. account.is_authorized = True account.is_deleted = False account.label = account.label or account.email_address account.from_name = account.from_name or ' '.join( account.email_address.split('@')[0].split('.')).title() set_to_public = bool(int(state.get('public'))) if account.public is not set_to_public: account.public = set_to_public only_sync_new_mails = bool(int(state.get('only_new'))) if only_sync_new_mails and created: # Setting it before the first sync means it will only fetch changes starting now. account.history_id = profile.get('historyId') account.full_sync_finished = True account.save() post_intercom_event(event_name='email-account-added', user_id=request.user.id) return HttpResponseRedirect('/#/preferences/emailaccounts/edit/%s' % account.pk)
def auth_return(request): if not xsrfutil.validate_token(settings.SECRET_KEY, request.REQUEST['state'], request.user): return HttpResponseBadRequest() credential = FLOW.step2_exchange(request.REQUEST) storage = Storage(CredentialsModel, 'id', request.user, 'credential') storage.put(credential) return HttpResponseRedirect("/")
def finalize(request): ac = AppCreds(user=request.user, label=request.POST['label']) ac.save() credential = FLOW.step2_exchange(request.POST) internal_label = "%s-%s" % (request.user.id, request.POST['label']) storage = Storage(CredentialsModel, 'id', ac, 'credential') storage.put(credential) return HttpResponseRedirect("/googleaccount/")
def finalize(request): ac = AppCreds(user=request.user, label=request.POST['label']) ac.save() credential = FLOW.step2_exchange(request.POST) internal_label = "%s-%s" % (request.user.id, request.POST['label']) storage = Storage(CredentialsModel, 'id', ac, 'credential') storage.put(credential) return HttpResponseRedirect("/accounts/")
def auth_return_view(request): user = request.user if not xsrfutil.validate_token(settings.SECRET_KEY, str(request.GET['state']), user): return HttpResponseBadRequest() FLOW = FlowModel.objects.get(id=user).flow credential = FLOW.step2_exchange(request.GET) storage = Storage(CredentialsModel, 'id', user, 'credential') storage.put(credential) return HttpResponseRedirect('/oauth2')
def get(self, request): # Get the state param from the request. state = str(request.GET.get('state')) # Replace %xx characters with single quotes and UTF8 decode the string. state = urllib.unquote(state).decode('utf8') # Deserialize the JSON string. state = anyjson.deserialize(b64decode(state)) if not validate_token(settings.SECRET_KEY, state.get('token'), request.user.pk): return HttpResponseBadRequest() error = request.GET.get('error') if error: messages.error( self.request, _('Sorry, Lily needs authorization from Google to synchronize your email account.') ) return HttpResponseRedirect('/#/preferences/emailaccounts') credentials = FLOW.step2_exchange(code=request.GET.get('code')) # Setup service to retrieve email address. service = build_gmail_service(credentials) profile = service.users().getProfile(userId='me').execute() # Create account based on email address. account, created = EmailAccount.objects.get_or_create( owner=request.user, email_address=profile.get('emailAddress') ) # Store credentials based on new email account. storage = Storage(GmailCredentialsModel, 'id', account, 'credentials') storage.put(credentials) # Set account as authorized. account.is_authorized = True account.is_deleted = False account.label = account.label or account.email_address account.from_name = account.from_name or ' '.join(account.email_address.split('@')[0].split('.')).title() set_to_public = bool(int(state.get('public'))) if account.public is not set_to_public: account.public = set_to_public only_sync_new_mails = bool(int(state.get('only_new'))) if only_sync_new_mails and created: # Setting it before the first sync means it will only fetch changes starting now. account.history_id = profile.get('historyId') account.first_sync_finished = True account.save() post_intercom_event(event_name='email-account-added', user_id=request.user.id) return HttpResponseRedirect('/#/preferences/emailaccounts/edit/%s' % account.pk)
def oauth2callback(request): if not xsrfutil.validate_token(settings.SECRET_KEY, str(request.GET['state']), request.user): return HttpResponseBadRequest() credential = FLOW.step2_exchange(request.GET) storage = Storage(GoogleCredentialsModel, 'id', request.user, 'credential') storage.put(credential) redirect_url = request.session['redirect_uri_after_step2'] return HttpResponseRedirect(redirect_url)
def auth_return(request): print settings.SECRET_KEY, request.GET['state'], request.user if not xsrfutil.validate_token(settings.SECRET_KEY, str(request.GET['state']), request.user): return HttpResponseBadRequest() credential = FLOW.step2_exchange(request.GET) print credential, request.user storage = Storage(CredentialsModel, 'id', request.user, 'credential') storage.put(credential) return HttpResponseRedirect("/fitcraft")
def auth_return(request): user = request.user FLOW = FlowModel.objects.get(id=user).flow if not xsrfutil.validate_token( settings.SECRET_KEY, FLOW.params['state'], user): return HttpResponseBadRequest() credential = FLOW.step2_exchange(request.GET['code']) storage = Storage(CredentialsModel, 'id', user, 'credential') storage.put(credential) return HttpResponseRedirect(reverse("oauth2:index"))
def auth_return(request): user = request.user if not xsrfutil.validate_token(settings.SECRET_KEY, str(request.GET['state']), user): return HttpResponseBadRequest() FLOW = FlowModel.objects.get(id=user).flow credential = FLOW.step2_exchange(request.GET) storage = Storage(CredentialsModel, 'id', user, 'credential') storage.put(credential) return HttpResponseRedirect("/scheduler/home")
def post(self, request, integration_type): """ Get the authentication URL for the given integration type. """ client_id = request.POST.get('client_id') client_secret = request.POST.get('client_secret') integration_context = request.POST.get('integration_context') if integration_context: integration_context = anyjson.loads(integration_context) errors = {} if not client_id: errors.update({ 'client_id': ['Please enter a valid client ID'], }) if not client_secret: errors.update({ 'client_secret': ['Please enter a valid client secret'], }) if errors: return HttpResponseBadRequest(anyjson.serialize(errors), content_type='application/json') integration_type = IntegrationType.objects.get(name__iexact=integration_type) redirect_uri = request.build_absolute_uri() params = { 'client_id': client_id, 'client_secret': client_secret, 'redirect_uri': redirect_uri, 'scope': integration_type.scope, 'response_type': 'code', } details, created = IntegrationDetails.objects.get_or_create(type=integration_type) storage = Storage(IntegrationCredentials, 'details', details, 'credentials') credentials = LilyOAuthCredentials( client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, integration_context=integration_context, ) storage.put(credentials) auth_url = integration_type.auth_url + urllib.urlencode(params) response = anyjson.serialize({'url': auth_url}) return HttpResponse(response, content_type='application/json')
def auth_return(request): user = request.user secret = request.REQUEST['state'].split('___')[0] group_name = request.REQUEST['state'].split('___')[1] if not xsrfutil.validate_token(settings.SECRET_KEY, str(secret), user): return HttpResponseBadRequest() FLOW = FlowModel.objects.get(id=user).flow credential = FLOW.step2_exchange(request.REQUEST) storage = Storage(CredentialsModel, 'id', user, 'credential') storage.put(credential) return HttpResponseRedirect("/gmail_setup?group=" + group_name)
def get(self, request, *args, **kwargs): if not xsrfutil.validate_token(settings.SECRET_KEY, str(request.REQUEST['state']), request.user): return HttpResponseBadRequest("ERROR: XSRF fail. %s %s %s" % ( str(request.REQUEST['state']), settings.SECRET_KEY, request.user)) credential = self.flow.step2_exchange(request.REQUEST) storage = Storage(CredentialsModel, 'id', request.user, 'credential') storage.put(credential) return HttpResponseRedirect(request.session.get(self.return_path_session_key,"/"))
def put_credentials(integration_type, credentials): """ Store new information for the given credentials. Args: integration_type (str): Name of the integration for which the storage should be retrieved. credentials (IntegrationCredentials): Updated credentials object. """ integration_type = IntegrationType.objects.get(name__iexact=integration_type) details = IntegrationDetails.objects.get(type=integration_type.id) storage = Storage(IntegrationCredentials, 'details', details, 'credentials') storage.put(credentials)
def link_google(request): flow = client.flow_from_clientsecrets(CLIENT_SECRET_CONTACTS, scope=GOOGLE_SCOPES, redirect_uri=REDIRECT_URI) flow.user_agent = APPLICATION_NAME auth_uri = flow.step1_get_authorize_url() try: user = User.objects.get(username=request.user) storage = Storage(FlowModel, 'id', user, 'flow') storage.put(flow) except: pass return HttpResponseRedirect(auth_uri)
def auth_return(request): log.debug("made it to auth_return") if not xsrfutil.validate_token(settings.SECRET_KEY, request.REQUEST['state'], request.user): log.debug("auth_return: user: %s" % request.user) log.debug("auth_return: state: %s" % request.REQUEST['state']) log.debug("auth_return: SECRET_KEY: %s" % settings.SECRET_KEY) log.debug("auth_return: API_KEY: %s" % API_KEY) log.debug("auth_return: HttpResponseBadRequest") return HttpResponseBadRequest() credential = FLOW.step2_exchange(request.REQUEST) storage = Storage(CredentialsModel, 'id', request.user, 'credential') storage.put(credential) log.debug("auth_return: credential", credential) log.debug("auth_return: HttpResponseRedirect") return None
def finalize(request): ac = AppCreds(user=request.user, label=request.POST['label']) ac.save() credential = FLOW.step2_exchange(request.POST) internal_label = "%s-%s" % (request.user.id, request.POST['label']) storage = Storage(CredentialsModel, 'id', ac, 'credential') storage.put(credential) if 'redir' in request.POST: if request.POST['redir'] == 'ffsetup': return HttpResponseRedirect("/fanfunding/setup?force=1") if request.POST['redir'] == 'subs': return HttpResponseRedirect("/youtubesubs/setup?force=1") if request.POST['redir'] == 'sponsors': return HttpResponseRedirect("/sponsors/setup?force=1") return HttpResponseRedirect("/accounts/")
def post(self, request): client_id = request.POST.get('client_id') client_secret = request.POST.get('client_secret') errors = {} if not client_id: errors.update({ 'client_id': ['Please enter a valid client ID'], }) if not client_secret: errors.update({ 'client_secret': ['Please enter a valid client secret'], }) if errors: return HttpResponseBadRequest(anyjson.serialize(errors), content_type='application/json') params = { 'client_id': client_id, 'client_secret': client_secret, 'redirect_uri': request.build_absolute_uri(), 'scope': 'read+write', 'response_type': 'code', } details, created = IntegrationDetails.objects.get_or_create(type=IntegrationDetails.PANDADOC) storage = Storage(IntegrationCredentials, 'details', details, 'credentials') credentials = storage.get() if not credentials: credentials = LilyOAuthCredentials( client_id=client_id, client_secret=client_secret, ) storage.put(credentials) auth_url = 'https://app.pandadoc.com/oauth2/authorize?' + urllib.urlencode(params) response = anyjson.serialize({'url': auth_url}) return HttpResponse(response, content_type='application/json')
def store_oauth2_credential(request): if request.method == 'GET': return HttpResponseNotAllowed(['POST', 'OPTIONS']) data = request.POST if 'access_token' not in data: logger.info('Failed to retrieve access token') if 'error' in data: error_msg = (str(data['error']) + str(data.get('error_description', ''))) else: error_msg = 'Invalid response. No access token.' raise AccessTokenCredentialsError(error_msg) access_token = data['access_token'] if 'refresh_token' in data: refresh_token = data['refresh_token'] else: refresh_token = None logger.info('Received token response with no refresh_token. Consider ' "reauthenticating with approval_prompt='force'.") token_expiry = None if 'expires_in' in data: delta = datetime.timedelta(seconds=int(data['expires_in'])) token_expiry = delta + datetime.datetime.utcnow() logger.info('Successfully retrieved access token') flow = _get_oauth_flow() credential = OAuth2Credentials(access_token, flow.client_id, flow.client_secret, refresh_token, token_expiry, flow.token_uri, flow.user_agent, revoke_uri=flow.revoke_uri, id_token=None, token_response=data, scopes=flow.scope, token_info_uri=flow.token_info_uri) storage = Storage(GoogleCredentialsModel, 'id', request.user, 'credential') storage.put(credential) return HttpResponse('{"detail": "The credential was successfully saved."}')
def auth_return(request): if not xsrfutil.validate_token(settings.SECRET_KEY, str(request.GET['state']), request.user.username): return HttpResponseBadRequest() credential = FLOW.step2_exchange(request.GET) http = httplib2.Http() http = credential.authorize(http) resp, data = http.request("https://api.patreon.com/oauth2/api/current_user") data = json.loads(data) name = data['data']['attributes'].get("full_name") or "(unnamed)" internal_label = "%s-%s" % (request.user.id, name) ac = PatreonAppCreds(user=request.user, label=internal_label) ac.save() storage = Storage(PatreonCredentialsModel, 'id', ac, 'credential') storage.put(credential) pu = PatreonUpdate(credentials=ac, user=request.user, type="patreon") pu.save() return HttpResponseRedirect("/patreon/")
def get_api_data(): all_data = {} for doctor in Doctor.objects.all(): storage = Storage(CredentialsModel, 'doctor_id', doctor.id, 'credential') credentials = storage.get() http = httplib2.Http() http = credentials.authorize(http) storage.put(credentials) (resp, content) = http.request("https://drchrono.com/api/patients", "GET") data = json.loads(content.decode("utf-8")) all_data[doctor.id] = data return all_data
def auth_return(request): """ Step 2 of Google OAuth 2.0 flow. """ if 'state' not in request.REQUEST: return redirect('gauth_index') if not xsrfutil.validate_token( settings.SECRET_KEY, str(request.REQUEST['state']), request.user): return HttpResponseBadRequest() FLOW = Storage(FlowModel, 'id', request.user, 'flow').get() if FLOW is None: return redirect('gauth_index') credential = FLOW.step2_exchange(request.REQUEST) cred_storage = Storage(CredentialsModel, 'id', request.user, 'credential') cred_storage.put(credential) return redirect(request.session.get('next_view', '/'))
def auth_return(request): if not xsrfutil.validate_token(settings.SECRET_KEY, str(request.GET['state']), request.user.username): return HttpResponseBadRequest() credential = FLOW.step2_exchange(request.GET) http = httplib2.Http() http = credential.authorize(http) resp, data = http.request( "https://api.patreon.com/oauth2/api/current_user") data = json.loads(data) name = data['data']['attributes'].get("full_name") or "(unnamed)" internal_label = "%s-%s" % (request.user.id, name) ac = PatreonAppCreds(user=request.user, label=internal_label) ac.save() storage = Storage(PatreonCredentialsModel, 'id', ac, 'credential') storage.put(credential) pu = PatreonUpdate(credentials=ac, user=request.user, type="patreon") pu.save() return HttpResponseRedirect("/patreon/")
def auth_return(request): if not xsrfutil.validate_token(settings.SECRET_KEY, str(request.GET['state']), request.user.username): return HttpResponseBadRequest() credential = FLOW.step2_exchange(request.POST) # https://api.patreon.com/oauth2/api/current_user http = httplib2.Http() http = credential.authorize(http) resp, data = http.request( "https://api.patreon.com/oauth2/api/current_user") data = json.loads(data) internal_label = "%s-%s" % (request.user.id, request.POST['label']) storage = Storage(PatreonCredentialsModel, 'id', ac, 'credential') storage.put(credential) ac = PatreonAppCreds(user=request.user, label="1") ac.save() pu = PatreonUpdate(credentials=ac) pu.save() return HttpResponseRedirect("/patreon/")
def auth_return(request): # user = request.user if request.session.get("oauth_appointment"): customer_factory = CustomerServicesFactory() dealer_factory = DealerShipServicesFactory() dealer_service = dealer_factory.get_instance("dealership") appt_service = dealer_factory.get_instance( "appointment") #AppointmentService() appointment = appt_service.get_appointment( request.session.get("oauth_appointment")) #,dealer) # if not xsrfutil.validate_token( # settings.SECRET_KEY, request.REQUEST['state'], user): # return HttpResponseBadRequest() FLOW = FlowModel.objects.get(id=appointment).flow credential = FLOW.step2_exchange(request.REQUEST) storage = Storage(CredentialsModel, 'id', appointment, 'credential') storage.put(credential) return HttpResponseRedirect( reverse('customer:sync_gcalendar') + "?appointment_id=" + str(appointment.id))
def post(self, request): error = request.data.get('error') if error: logger.error(error) raise exceptions.ValidationError(error) try: state = request.data['state'].encode('ascii') code = request.data['code'] except KeyError: logger.error('No mandatory fields supplied') raise exceptions.ValidationError('No mandatory fields supplied') if not xsrfutil.validate_token(settings.SECRET_KEY, state, request.user): logger.error('Invalid token') raise exceptions.PermissionDenied('Invalid token') key = analytics_settings.FLOW_CACHE_KEY_PLACEHOLDER % request.user.pk logger.debug('Getting OAuth2 Web server Flow from cache by key: %s', key) cached_flow = cache.get(key) if cached_flow: flow = pickle.loads(cached_flow) else: flow = self.get_flow(scope=analytics_settings.FLOW_SCOPE) try: credential = flow.step2_exchange(code) logger.debug('Saving OAuth2 credential to database') storage = Storage(CredentialsModel, 'user', request.user, 'credential') storage.put(credential) except FlowExchangeError as ex: logger.error(ex.message) raise exceptions.APIException(ex.message) return Response({}, status=status.HTTP_201_CREATED)
def auth_return(request): '''The Token generated in index() should be validated here with the same user that was used to generate the token''' U = User(username='******', firstname='Bla Bla', lastname='Bla Bla', email='*****@*****.**') ''' Reference: 1. https://github.com/tschellenbach/Django-facebook/pull/564 2. encode() is used here because in Django 1.6 or less we used to get the string automatically but in Django 1.7+ we have to use encode() to get the string ''' if not xsrfutil.validate_token(settings.SECRET_KEY, (request.GET['state']).encode('utf-8'), U): print("Test: 1") return HttpResponseBadRequest() print("Test: 2") credential = FLOW.step2_exchange(request.GET) storage = Storage(CredentialsModel, 'id', U, 'credential') storage.put(credential) return HttpResponseRedirect("/")
def auth_return(request): if not xsrfutil.validate_token(settings.SECRET_KEY, str(request.GET['state']), request.user.username): return HttpResponseBadRequest() credential = FLOW.step2_exchange(request.GET) http = httplib2.Http() http = credential.authorize(http) resp, data = http.request("https://beam.pro/api/v1/users/current") data = json.loads(data) print data channelId = None if 'channel' in data: channelId = data['channel']['id'] name = data['channel'].get("name") or "(unnamed)" internal_label = "%s-%s" % (channelId, name) ac = BeamAppCreds(user=request.user, label=internal_label) ac.save() storage = Storage(BeamCredentialsModel, 'id', ac, 'credential') storage.put(credential) pu = BeamUpdate(credentials=ac, user=request.user, type="beam") pu.save() return HttpResponseRedirect("/beam/")
def auth_return(request): '''The Token generated in index() should be validated here with the same user that was used to generate the token''' U = User( username = '******', firstname= 'Bla Bla', lastname= 'Bla Bla', email = '*****@*****.**' ) ''' Reference: 1. https://github.com/tschellenbach/Django-facebook/pull/564 2. encode() is used here because in Django 1.6 or less we used to get the string automatically but in Django 1.7+ we have to use encode() to get the string ''' if not xsrfutil.validate_token(settings.SECRET_KEY, (request.GET['state']).encode('utf-8'), U): print("Test: 1") return HttpResponseBadRequest() print("Test: 2") credential = FLOW.step2_exchange(request.GET) storage = Storage(CredentialsModel, 'id', U, 'credential') storage.put(credential) return HttpResponseRedirect("/")
def authenticate_pandadoc(credentials, integration_type, code=None): payload = { 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, } if code: # Trade the auth code for an access token. payload.update({ 'grant_type': 'authorization_code', 'code': code }) else: # Already authenticated once, but access token expired. payload.update({ 'grant_type': 'refresh_token', 'refresh_token': credentials.refresh_token }) response = requests.post( url='https://api.pandadoc.com/oauth2/access_token', data=payload, ) if response.status_code == 200: data = response.json() credentials.access_token = data.get('access_token') credentials.refresh_token = data.get('refresh_token') credentials.expires = timezone.now() + timedelta(seconds=data.get('expires_in')) details = IntegrationDetails.objects.get(type=integration_type) storage = Storage(IntegrationCredentials, 'details', details, 'credentials') storage.put(credentials) return credentials
def get(self, request): error = request.GET.get('error') if error: messages.error( self.request, _('Sorry, Lily needs authorization from Google to synchronize your email account.' )) return HttpResponseRedirect('/#/preferences/emailaccounts') # Get the state param from the request. state = str(request.GET.get('state')) # Replace %xx characters with single quotes and UTF8 decode the string. state = urllib.unquote(state).decode('utf8') # Deserialize the JSON string. state = anyjson.deserialize(b64decode(state)) if not validate_token(settings.SECRET_KEY, state.get('token'), request.user.pk): return HttpResponseBadRequest() credentials = FLOW.step2_exchange(code=request.GET.get('code')) # Setup service to retrieve email address from Google. gmail_service = GmailService(credentials) try: profile = gmail_service.execute_service( gmail_service.service.users().getProfile(userId='me')) except HttpError as error: error = anyjson.loads(error.content) error = error.get('error', error) if error.get('code') == 400 and error.get( 'message') == 'Mail service not enabled': messages.error( self.request, _('Mail is not enabled for this email account.')) else: messages.error(self.request, error.get('message')) # Adding email account failed, administer it as skipping the email setup or otherwise the user will be # stuck in redirect loop. user = self.request.user user.info.email_account_status = UserInfo.SKIPPED user.info.save() return HttpResponseRedirect('/#/preferences/emailaccounts') # Create account based on email address. try: account, created = EmailAccount.objects.get_or_create( owner=request.user, tenant_id=request.user.tenant_id, email_address=profile.get('emailAddress')) except EmailAccount.MultipleObjectsReturned: account, created = EmailAccount.objects.get_or_create( owner=request.user, tenant_id=request.user.tenant_id, email_address=profile.get('emailAddress'), is_deleted=False) # Store credentials based on new email account. storage = Storage(GmailCredentialsModel, 'id', account, 'credentials') storage.put(credentials) account.is_deleted = False if request.user.tenant.billing.is_free_plan: account.privacy = EmailAccount.PRIVATE if created: account.only_new = None account.save() post_intercom_event(event_name='email-account-added', user_id=request.user.id) if request.user.info and not request.user.info.email_account_status: # First time setup, so we want a different view. return HttpResponseRedirect( '/#/preferences/emailaccounts/setup/%s' % account.pk) else: return HttpResponseRedirect( '/#/preferences/emailaccounts/edit/%s' % account.pk)
def finalize(request): credential = FLOW.step2_exchange(request.POST) internal_label = "%s-%s" % (request.user.id, request.POST['label']) storage = Storage(TwitchCredentialsModel, 'id', ac, 'credential') storage.put(credential) return HttpResponseRedirect("/accounts/")
def post(self, request, integration_type): """ Get the authentication URL for the given integration type. """ is_slack = integration_type == 'slack' if is_slack: client_id = settings.SLACK_LILY_CLIENT_ID client_secret = settings.SLACK_LILY_CLIENT_SECRET else: client_id = request.POST.get('client_id') client_secret = request.POST.get('client_secret') integration_context = request.POST.get('integration_context', {}) if integration_context: integration_context = anyjson.loads(integration_context) errors = {} if not client_id: errors.update({ 'client_id': ['Please enter a valid client ID'], }) if not client_secret: errors.update({ 'client_secret': ['Please enter a valid client secret'], }) if errors: return HttpResponseBadRequest(anyjson.serialize(errors), content_type='application/json') integration_type = IntegrationType.objects.get(name__iexact=integration_type) redirect_uri = request.build_absolute_uri() params = { 'client_id': client_id, 'client_secret': client_secret, 'redirect_uri': redirect_uri, 'scope': integration_type.scope, 'response_type': 'code', } if is_slack: # Save a unique identifier so we can verify the follow up request from Slack is legit. state = sha256('%s-%s' % ( self.request.user.id, settings.SECRET_KEY )).hexdigest() params.update({'state': state}) details, created = SlackDetails.objects.get_or_create(type=integration_type) else: details, created = IntegrationDetails.objects.get_or_create(type=integration_type) storage = Storage(IntegrationCredentials, 'details', details, 'credentials') credentials = LilyOAuthCredentials( client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, integration_context=integration_context, ) storage.put(credentials) auth_url = integration_type.auth_url + urllib.urlencode(params) response = anyjson.serialize({'url': auth_url}) return HttpResponse(response, content_type='application/json')
def get_access_token(credentials, integration_type, code=None): """ Generic function to retrieve an OAuth 2.0 access token. Args: credentials (object): Contains the OAuth 2.0 credentials needed to retrieve a token. integration_type (str): Name of the integration for which the credentials should be retrieved. code (str, optional): Authorization code which will be exchanged for an access token. Returns: credentials (object): Updated credentials with a new access token. """ payload = { 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, } if code: # Trade the auth code for an access token. payload.update({ 'grant_type': 'authorization_code', 'redirect_uri': credentials.redirect_uri, 'code': code }) else: # Already authenticated once, but access token expired. payload.update({ 'grant_type': 'refresh_token', 'refresh_token': credentials.refresh_token }) if isinstance(integration_type, basestring): # Sometimes we pass just a string, so fetch the actual integration type. integration_type = IntegrationType.objects.get(name__iexact=integration_type) response = requests.post( url=integration_type.token_url, data=payload, ) if response.status_code == 200: is_slack = integration_type.name.lower() == 'slack' data = response.json() expires = data.get('expires_in') credentials.access_token = data.get('access_token') credentials.refresh_token = data.get('refresh_token') if expires: credentials.expires = timezone.now() + timedelta(seconds=expires) if is_slack: # Store the team ID so we can use it later for authorization. details = SlackDetails.objects.get(type=integration_type.id) details.team_id = data.get('team_id') details.save() else: details = IntegrationDetails.objects.get(type=integration_type.id) storage = Storage(IntegrationCredentials, 'details', details, 'credentials') storage.put(credentials) return credentials else: return None
def get(self, request): error = request.GET.get('error') if error: messages.error( self.request, _('Sorry, Lily needs authorization from Google to synchronize your email account.') ) return HttpResponseRedirect('/#/preferences/emailaccounts') # Get the state param from the request. state = str(request.GET.get('state')) # Replace %xx characters with single quotes and UTF8 decode the string. state = urllib.unquote(state).decode('utf8') # Deserialize the JSON string. state = anyjson.deserialize(b64decode(state)) if not validate_token(settings.SECRET_KEY, state.get('token'), request.user.pk): return HttpResponseBadRequest() credentials = FLOW.step2_exchange(code=request.GET.get('code')) # Setup service to retrieve email address from Google. gmail_service = GmailService(credentials) try: profile = gmail_service.execute_service(gmail_service.service.users().getProfile(userId='me')) except HttpError as error: error = anyjson.loads(error.content) error = error.get('error', error) if error.get('code') == 400 and error.get('message') == 'Mail service not enabled': messages.error(self.request, _('Mail is not enabled for this email account.')) else: messages.error(self.request, error.get('message')) if not request.user.info.registration_finished: # User is still busy with registration, so redirect to email account setup step again. return HttpResponseRedirect(reverse('register_email_account_setup')) else: return HttpResponseRedirect('/#/preferences/emailaccounts') # Create account based on email address. try: account, created = EmailAccount.objects.get_or_create( owner=request.user, tenant_id=request.user.tenant_id, email_address=profile.get('emailAddress') ) except EmailAccount.MultipleObjectsReturned: account, created = EmailAccount.objects.get_or_create( owner=request.user, tenant_id=request.user.tenant_id, email_address=profile.get('emailAddress'), is_deleted=False ) # Store credentials based on new email account. storage = Storage(GmailCredentialsModel, 'id', account, 'credentials') storage.put(credentials) account.is_deleted = False if request.user.tenant.billing.is_free_plan: account.privacy = EmailAccount.PRIVATE if created: account.only_new = None account.save() post_intercom_event(event_name='email-account-added', user_id=request.user.id) if not request.user.info.registration_finished: # User is still busy with registration, so redirect to the next step in the flow. return HttpResponseRedirect(reverse('register_email_account_details')) else: return HttpResponseRedirect('/#/preferences/emailaccounts/edit/%s' % account.pk)