microsoft / microsoft/azure-devops-python-api

build_client.get_artifact_content_zip() raises "The user '' is not authorized

Aberta
#316 3 comentários 1 reação 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

Linguagem predominante
Python
Estrelas
684
Forks
218
Merge médio
8d 10h
PRs com merge (30d)
1

Descrição

I opened the issue originally at https://developercommunity.visualstudio.com/content/problem/917755/get-artifact-content-zip-always-returns-authorizat.html

I got "TF400813: The user '' is not authorized to access this resource.", when using build_client.get_artifact_content_zip()

I did find that I can only reproduce it on certain artifacts, not all of them. My suspicion is that for artifacts whose downloadUrl points to some other host, the credential doesn't transfer correctly.

Here's the code:

import argparse
import pathlib
import sys
import tempfile
import zipfile

import azure.devops.connection as azdo_connection
import msrest

# NOTE, please run this with python >= 3.6, in venv that has these reqs:
# * azure-devops~=5.1.0b3
# * msrest~=0.6.9


def parser():
    parser = argparse.ArgumentParser(description="Download artifact")
    parser.add_argument(
        "--url", required=True, help="Example: https://dev.azure.com/MY_ORGANIZATION"
    )
    parser.add_argument("--access-token", required=True, help="Access token to use.")
    parser.add_argument("--project", required=True, help="Azdo project.")
    parser.add_argument("--build-id", required=True, help="Current build id.")
    parser.add_argument("--artifact-name", required=True, help="Artifact name.")
    parser.add_argument(
        "--output-dir", default=".", type=pathlib.Path, help="Artifact name."
    )
    return parser


def main(argv=None):
    if argv is None:
        argv = sys.argv
    args = parser().parse_args(argv[1:])

    credentials = msrest.authentication.BasicAuthentication("", args.access_token)
    connection = azdo_connection.Connection(base_url=args.url, creds=credentials)
    build_client = connection.clients_v5_1.get_build_client()
    artifact_info = build_client.get_artifact(
        args.project, args.build_id, args.artifact_name
    )
    print(f"Artifact info: {artifact_info}")
    with tempfile.TemporaryFile() as f:
        for i in build_client.get_artifact_content_zip(
            args.project, args.build_id, args.artifact_name
        ):
            f.write(i)
        f.seek(0)
        zf = zipfile.ZipFile(f)
        outdir = args.output_dir
        outdir.mkdir(parents=True, exist_ok=True)
        zf.extractall(path=outdir)


if __name__ == "__main__":
    sys.exit(main())

A workaround I found is to apply this patch:

@@ -40,9 +42,18 @@ def main(argv=None):
     )
     print(f"Artifact info: {artifact_info}")
     with tempfile.TemporaryFile() as f:
-        for i in build_client.get_artifact_content_zip(
-            args.project, args.build_id, args.artifact_name
-        ):
+        try:
+            stream = build_client.get_artifact_content_zip(
+                args.project, args.build_id, args.artifact_name
+            )
+        except AzureDevOpsServiceError as e:
+            if "The user '' is not authorized to access this resource" in e.message:
+                stream = requests.get(
+                    artifact_info.resource.download_url, auth=("", args.access_token)
+                )
+            else:
+                raise
+        for i in stream:
             f.write(i)
         f.seek(0)
         zf = zipfile.ZipFile(f)

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece com a reprodução em Python fornecida e o ponto de entrada build_client.get_artifact_content_zip(). Compare seu comportamento de autenticação com artifact_info.resource.download_url para artefatos hospedados em outro domínio, usando o erro de autorização relatado como sinal de falha. O trabalho estará concluído quando os downloads de ZIP de artefatos funcionarem tanto para URLs de download no mesmo host quanto para URLs de download externas, sem exigir a solução alternativa do chamador.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
azure, python
Domínio
api
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Estagnada
Clareza
Razoavelmente clara
Facilidade para iniciantes
38/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.