Google drive api загружается как неправильный пользователь

У меня есть раздел моего программного обеспечения, которое недавно перестало работать правильно. Программа должна позволять пользователю загружать PDF-файл в нашу учетную запись на Google Диске, а затем программа отправит электронное письмо некоторым другим людям в нашем офисе для просмотра. Это работало до понедельника, когда загрузки и электронные письма от моих пользователей начали поступать из моей учетной записи Google, а не из их собственной. Это случается не со всеми, может быть, от 1/3 до 1/2 пользователей сталкиваются с этой проблемой. Иногда программа отправляет электронное письмо от имени меня, а иногда выдает ошибку <HttpError 403 при запросе https://gmail.googleapis.com/gmail/v1/users/username/messages/send?alt=json. 'Делегирование отклонено для '[email protected]'>. Поскольку ничего не изменилось в моих функциях загрузки и отправки электронной почты, я думаю, что это связано с разрешениями или тем, как программа распространяется? Любое понимание будет оценено.

Я написал все на python3 и скомпилировал exe для распространения среди моей команды с помощью pyinstaller.

pyinstaller --onefile path/to/code.py

Вещи, которые я устал устранять: запустить от имени администратора пользователи перезагружали свои ПК У меня был кто-то из моей команды, который запускал py-файл напрямую, и это работало правильно. Первоначально у меня был --hidden-import='googleapiclient' для pyinstaller, который я удалил Первоначально в части электронной почты у меня был userId='me', и я изменил его, чтобы получить фактический адрес электронной почты пользователя. (Идея того, что pyinstaller блокирует «меня» как мою личную электронную почту. Этот код запускается после загрузки, так что, похоже, это не проблема.)

Соответствующий код загрузки на случай, если кто-то обнаружит проблему:

self.SCOPES = ['https://www.googleapis.com/auth/gmail.modify',
               'https://www.googleapis.com/auth/spreadsheets',
               'https://www.googleapis.com/auth/drive']
credentials.json:
{
    "installed":{
        "client_id":"client_id.apps.googleusercontent.com",
        "project_id":"project_ID",
        "auth_uri":"https://accounts.google.com/o/oauth2/auth",
        "token_uri":"https://oauth2.googleapis.com/token",
        "auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
        "client_secret":"secret_code",
        "redirect_uris":[
            "urn:ietf:wg:oauth:2.0:oob",
            "http://localhost"
        ]
    }
}

def upload(self, letterfile, plansfile, parentdrive):
    # Check for json credentials for google drive and API access
    try:
        x = os.stat(os.path.join(self.prefs['data'], 'token.json'))
        result = time.time() - x.st_mtime
        if result > 129600:
            os.remove(os.path.join(self.prefs['data'], 'token.json'))
    except:
        pass
    creds = None
    jsonpath = os.path.join(self.prefs['data'], 'token.json')
    if os.path.exists(jsonpath):
        creds = Credentials.from_authorized_user_file(jsonpath,
                                                      self.SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    try:
        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    os.path.join(self.prefs['data'], 'credentials.json'),
                    self.SCOPES)
                creds = flow.run_local_server(port=0)
            # Save the credentials for the next run
            with open(os.path.join(self.prefs['data'], 'token.json'), 'w') as token:
                token.write(creds.to_json())
    except BaseException as e:
        print(f'Error with credentials.json check: {e}')
    # Build the services to access the Gmail API and Drive API
    driveService = build('drive', 'v3', credentials=creds)
    file = letterfile
    folderLink = f'https://drive.google.com/drive/folders/{parentdrive}'
    # Work with different attachment formats (Text, Image, or PDF). This
    # will need to be a FOR loop to iterate through all imported files
    # from the app
    content_type, encoding = mimetypes.guess_type(file)
    if content_type is None or encoding is not None:
        content_type = 'application/octet-stream'
    main_type, sub_type = content_type.split('/', 1)
    if main_type == 'text':
        with open(file, 'rb') as fp:
            msg = MIMEText(fp.read(), _subtype=sub_type)
            fp.close()
    elif main_type == 'image':
        with open(file, 'rb') as fp:
            msg = MIMEImage(fp.read(), _subtype=sub_type)
            fp.close()
    else:
        with open(file, 'rb') as fp:
            msg = MIMEBase(main_type, sub_type)
            msg.set_payload(fp.read())
            fp.close()
    calcfile = os.path.basename(letterfile)
    try:
        planname = os.path.basename(plansfile)
    except BaseException as e:
        planname = []
        for planfile in plansfile:
            planname.append(os.path.basename(planfile))
    # Upload file to Drive Project Folder
    file_metadata = {'name': calcfile, 'parents': [parentdrive]}
    media = MediaFileUpload(letterfile,
                            mimetype=content_type,
                            resumable=True)
    tempcalcfile = driveService.files().create(body=file_metadata,
                                               media_body=media,
                                               supportsAllDrives=True).execute()
    try:
        plan_metadata = {'name': planname, 'parents': [parentdrive]}
        media = MediaFileUpload(plansfile,
                                mimetype=content_type,
                                resumable=True)
        tempplansfile = driveService.files().create(body=plan_metadata,
                                                    media_body=media,
                                                    supportsAllDrives=True).execute()
    except BaseException as e:
        for i in range(len(planname)):
            plan_metadata = {'name': planname[i], 'parents': [parentdrive]}
            media = MediaFileUpload(plansfile[i],
                                    mimetype=content_type,
                                    resumable=True)
            tempplansfile = driveService.files().create(body=plan_metadata,
                                                        media_body=media,
                                                        supportsAllDrives=True).execute()
    print('Files sent to Drive Folder through API')

Выполняет ли ваш процесс делегирование электронной почты? Можете ли вы попробовать изменить настройку для затронутых пользователей.

Twilight 26.05.2023 05:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У меня была папка, в которой хранились учетные данные.json, мой файл token.json и некоторые другие файлы, которые были распространены среди моей команды. Я случайно делюсь с ними МОИМ файлом token.json, поэтому, когда Google Oauth2 запустился, он прочитал файл как я, а не как пользователь.

Моя команда удалила файл token.json, что вызвало повторную авторизацию пользователя, создание нового token.json и устранило проблему.

Другие вопросы по теме