77from typing import Any , TypedDict
88from urllib .parse import parse_qs , quote , unquote , urlencode , urlparse
99
10- from django import forms
1110from django .http .request import HttpRequest
12- from django .http .response import HttpResponseBase
1311from django .utils .translation import gettext as _
1412from rest_framework import serializers
1513from rest_framework .fields import CharField
2018from sentry .auth .exceptions import IdentityNotValid
2119from sentry .constants import ObjectStatus
2220from sentry .identity .oauth2 import OAuth2ApiStep
23- from sentry .identity .pipeline import IdentityPipeline
2421from sentry .identity .services .identity .model import RpcIdentity
2522from sentry .identity .vsts .provider import VSTSNewIdentityProvider , get_user_info
2623from sentry .integrations .base import (
5552from sentry .organizations .services .organization .model import RpcOrganization
5653from sentry .pipeline .types import PipelineStepResult
5754from sentry .pipeline .views .base import ApiPipelineSteps , PipelineView
58- from sentry .pipeline .views .nested import NestedPipelineView
5955from sentry .shared_integrations .exceptions import (
6056 ApiError ,
6157 IntegrationError ,
6460from sentry .silo .base import SiloMode
6561from sentry .utils import metrics
6662from sentry .utils .http import absolute_uri
67- from sentry .web .helpers import render_to_response
6863
6964from .client import VstsApiClient , VstsSetupApiClient
7065from .repository import VstsRepositoryProvider
@@ -611,20 +606,7 @@ def get_scopes(self) -> Sequence[str]:
611606 return VstsIntegrationProvider .NEW_SCOPES
612607
613608 def get_pipeline_views (self ) -> Sequence [PipelineView [IntegrationPipeline ]]:
614- identity_pipeline_config = {
615- "redirect_url" : absolute_uri (self .oauth_redirect_url ),
616- "oauth_scopes" : self .get_scopes (),
617- }
618-
619- return [
620- NestedPipelineView (
621- bind_key = "identity" ,
622- provider_key = self .key ,
623- pipeline_cls = IdentityPipeline ,
624- config = identity_pipeline_config ,
625- ),
626- AccountConfigView (),
627- ]
609+ return []
628610
629611 def get_pipeline_api_steps (self ) -> ApiPipelineSteps [IntegrationPipeline ]:
630612 return [
@@ -650,13 +632,7 @@ def _make_oauth_api_step(self) -> OAuth2ApiStep:
650632 )
651633
652634 def build_integration (self , state : Mapping [str , Any ]) -> IntegrationData :
653- # TODO: legacy views write token data to state["identity"]["data"] via
654- # NestedPipelineView. API steps write directly to state["oauth_data"].
655- # Remove the legacy path once the old views are retired.
656- if "oauth_data" in state :
657- data = state ["oauth_data" ]
658- else :
659- data = state ["identity" ]["data" ]
635+ data = state ["oauth_data" ]
660636 oauth_data = self .get_oauth_data (data )
661637 account = state ["account" ]
662638 user = get_user_info (data ["access_token" ])
@@ -834,57 +810,3 @@ def setup(self) -> None:
834810 bindings .add (
835811 "integration-repository.provider" , VstsRepositoryProvider , id = "integrations:vsts"
836812 )
837-
838-
839- class AccountConfigView :
840- def dispatch (self , request : HttpRequest , pipeline : IntegrationPipeline ) -> HttpResponseBase :
841- with IntegrationPipelineViewEvent (
842- IntegrationPipelineViewType .ACCOUNT_CONFIG ,
843- IntegrationDomain .SOURCE_CODE_MANAGEMENT ,
844- VstsIntegrationProvider .key ,
845- ).capture () as lifecycle :
846- account_id = request .POST .get ("account" )
847- if account_id is not None :
848- state_accounts : Sequence [Mapping [str , Any ]] | None = pipeline .fetch_state (
849- key = "accounts"
850- )
851- account = get_account_from_id (account_id , state_accounts or [])
852- if account is not None :
853- pipeline .bind_state ("account" , account )
854- return pipeline .next_step ()
855-
856- state : Mapping [str , Any ] | None = pipeline .fetch_state (key = "identity" )
857- access_token = (state or {}).get ("data" , {}).get ("access_token" )
858- user = get_user_info (access_token )
859-
860- accounts = get_accounts (access_token , user ["uuid" ])
861- extra = {
862- "organization_id" : pipeline .organization .id if pipeline .organization else None ,
863- "user_id" : request .user .id ,
864- "accounts" : accounts ,
865- }
866- if not accounts or not accounts .get ("value" ):
867- lifecycle .record_halt (IntegrationPipelineHaltReason .NO_ACCOUNTS , extra = extra )
868- return render_to_response (
869- template = "sentry/integrations/vsts-config.html" ,
870- context = {"no_accounts" : True },
871- request = request ,
872- )
873- accounts = accounts ["value" ]
874- pipeline .bind_state ("accounts" , accounts )
875- account_form = AccountForm (accounts )
876- return render_to_response (
877- template = "sentry/integrations/vsts-config.html" ,
878- context = {"form" : account_form , "no_accounts" : False },
879- request = request ,
880- )
881-
882-
883- class AccountForm (forms .Form ):
884- def __init__ (self , accounts : Sequence [Mapping [str , str ]], * args : Any , ** kwargs : Any ) -> None :
885- super ().__init__ (* args , ** kwargs )
886- self .fields ["account" ] = forms .ChoiceField (
887- choices = [(acct ["accountId" ], acct ["accountName" ]) for acct in accounts ],
888- label = "Account" ,
889- help_text = "Azure DevOps organization." ,
890- )
0 commit comments