public EncTicketPart(
     TicketFlags param0,
     EncryptionKey param1,
     Realm param2,
     PrincipalName param3,
     TransitedEncoding param4,
     KerberosTime param5,
     KerberosTime param6,
     KerberosTime param7,
     KerberosTime param8,
     HostAddresses param9,
     AuthorizationData param10)
 {
     this.flags = param0;
     this.key = param1;
     this.crealm = param2;
     this.cname = param3;
     this.transited = param4;
     this.authtime = param5;
     this.starttime = param6;
     this.endtime = param7;
     this.renew_till = param8;
     this.caddr = param9;
     this.authorization_data = param10;
 }
 public AD_AND_OR(
     KerbInt32 param0,
     AuthorizationData param1)
 {
     this.condition_count = param0;
     this.elements = param1;
 }
 public AD_KDCIssued(
     Checksum param0,
     Realm param1,
     PrincipalName param2,
     AuthorizationData param3)
 {
     this.ad_checksum = param0;
     this.i_realm = param1;
     this.i_sname = param2;
     this.elements = param3;
 }
 public Authenticator(
     Asn1Integer param0,
     Realm param1,
     PrincipalName param2,
     Checksum param3,
     Microseconds param4,
     KerberosTime param5,
     EncryptionKey param6,
     KerbUInt32 param7,
     AuthorizationData param8)
 {
     this.authenticator_vno = param0;
     this.crealm = param1;
     this.cname = param2;
     this.cksum = param3;
     this.cusec = param4;
     this.ctime = param5;
     this.subkey = param6;
     this.seq_number = param7;
     this.authorization_data = param8;
 }
        private PA_DATA CreatePaTgsReq(ChecksumType checksumType, byte[] checksumBody, AuthorizationData data)
        {
            APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None));
            EncryptionKey key = Context.SessionKey;
            EncryptionKey subkey = null;
            Ticket ticket = Context.Ticket.Ticket;
            KerberosApRequest apRequest = CreateApRequest(option, Context.Ticket, subkey, data, KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator, checksumType, checksumBody);

            PaTgsReq paTgsReq = new PaTgsReq(apRequest.Request);
            return paTgsReq.Data;
        }
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                BulkServiceManager = new BulkServiceManager(
                    authorizationData: authorizationData,
                    apiEnvironment: environment);
                BulkServiceManager.StatusPollIntervalInMilliseconds = 5000;

                // Track download or upload progress

                var progress = new Progress <BulkOperationProgressInfo>(x =>
                                                                        OutputStatusMessage(string.Format("{0} % Complete",
                                                                                                          x.PercentComplete.ToString(CultureInfo.InvariantCulture))));

                // Some BulkServiceManager operations can be cancelled after a time interval.

                var tokenSource = new CancellationTokenSource();
                tokenSource.CancelAfter(TimeoutInMilliseconds);

                // Download all campaigns, ad groups, and ads in the account.

                var entities = new[] {
                    DownloadEntity.Campaigns,
                    DownloadEntity.AdGroups,
                    DownloadEntity.Ads,
                };

                // DownloadParameters is used for Option A below.
                var downloadParameters = new DownloadParameters
                {
                    CampaignIds         = null,
                    DataScope           = DataScope.EntityData | DataScope.QualityScoreData,
                    DownloadEntities    = entities,
                    FileType            = FileType,
                    LastSyncTimeInUTC   = null,
                    ResultFileDirectory = FileDirectory,
                    ResultFileName      = DownloadFileName,
                    OverwriteResultFile = true
                };

                // SubmitDownloadParameters is used for Option B and Option C below.
                var submitDownloadParameters = new SubmitDownloadParameters
                {
                    CampaignIds       = null,
                    DataScope         = DataScope.EntityData | DataScope.QualityScoreData,
                    DownloadEntities  = entities,
                    FileType          = FileType,
                    LastSyncTimeInUTC = null
                };

                // Option A - Background Completion with BulkServiceManager
                // You can submit a download or upload request and the BulkServiceManager will automatically
                // return results. The BulkServiceManager abstracts the details of checking for result file
                // completion, and you don't have to write any code for results polling.

                OutputStatusMessage("-----\nAwaiting Background Completion with DownloadFileAsync...");
                await BackgroundCompletionAsync(
                    downloadParameters : downloadParameters,
                    progress : progress,
                    cancellationToken : tokenSource.Token);

                // Alternatively we can use DownloadEntitiesAsync if we want to work with the entities in memory.
                // If you enable this option the result file from BackgroundCompletionAsync will also be deleted
                // if written to the same working directory.
                OutputStatusMessage("-----\nAwaiting Background Completion with DownloadEntitiesAsync...");
                var downloadEntities = await DownloadEntitiesAsync(
                    downloadParameters : downloadParameters,
                    progress : progress,
                    cancellationToken : tokenSource.Token);

                // Option B - Submit and Download with BulkServiceManager
                // Submit the download request and then use the BulkDownloadOperation result to
                // track status until the download is complete e.g. either using
                // TrackAsync or GetStatusAsync.

                OutputStatusMessage("-----\nAwaiting Submit, Track, and Download...");
                await SubmitTrackDownloadAsync(
                    submitDownloadParameters : submitDownloadParameters,
                    progress : progress,
                    cancellationToken : tokenSource.Token);

                // A second variation of Option B.
                // See SubmitTrackDownloadAsync for details.

                OutputStatusMessage("-----\nAwaiting Submit, Poll, and Download...");
                await SubmitTrackDownloadAsync(
                    submitDownloadParameters : submitDownloadParameters,
                    progress : progress,
                    cancellationToken : tokenSource.Token);

                // Option C - Download Results with BulkServiceManager
                // If for any reason you have to resume from a previous application state,
                // you can use an existing download request identifier and use it
                // to download the result file.

                // For example you might have previously retrieved a request ID using SubmitDownloadAsync.

                var bulkDownloadOperation = await BulkServiceManager.SubmitDownloadAsync(
                    parameters : submitDownloadParameters);

                var requestId = bulkDownloadOperation.RequestId;

                // Given the request ID above, you can resume the workflow and download the bulk file.
                // The download request identifier is valid for two days.
                // If you do not download the bulk file within two days, you must request it again.

                OutputStatusMessage("-----\nAwaiting Download Results...");
                await DownloadResultsAsync(
                    requestId : requestId,
                    authorizationData : authorizationData,
                    progress : progress,
                    cancellationToken : tokenSource.Token);
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Bulk service exceptions
            catch (FaultException <Microsoft.BingAds.V13.Bulk.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(String.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V13.Bulk.ApiFaultDetail> ex)
            {
                OutputStatusMessage(String.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(String.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationInProgressException ex)
            {
                OutputStatusMessage("The result file for the bulk operation is not yet available for download.");
                OutputStatusMessage(ex.Message);
            }
            catch (BulkOperationCouldNotBeCompletedException <DownloadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationCouldNotBeCompletedException <UploadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
Exemplo n.º 7
0
        private async Task <Token> AskServerForToken(string clientId, string secretId, AuthorizationData authData)
        {
            return(await Task.Run(async() =>
            {
                Token token = null;
                Thread.Sleep(1000 * 15);
                var rtdf = "https://allegro.pl/auth/oauth/token?grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=";
                var url = new Uri(rtdf + authData.DeviceCode);
                var oAuth = getAuthParameters(clientId, secretId);
                while (true)
                {
                    var res = await sendRequest(url, oAuth, "application/json", "");

                    if (res.ResultOk)
                    {
                        token = Utility.Deserialize <Token>(res.Stream);
                        token.TimeCreated = DateTime.UtcNow;
                        break;
                    }
                    Thread.Sleep(1000 * authData.Interval);
                }
                return token;
            }));
        }
Exemplo n.º 8
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper(
                    OutputStatusMessageDefault: this.OutputStatusMessage);
                CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient <ICampaignManagementService>(
                    authorizationData: authorizationData,
                    environment: environment);

                // Add a campaign that will later be associated with negative keywords.

                var campaigns = new[] {
                    new Campaign
                    {
                        BudgetType   = BudgetLimitType.DailyBudgetStandard,
                        DailyBudget  = 50,
                        CampaignType = CampaignType.Search,
                        Description  = "Red shoes line.",
                        Languages    = new string[] { "All" },
                        Name         = "Women's Shoes " + DateTime.UtcNow,
                        TimeZone     = "PacificTimeUSCanadaTijuana",
                    },
                };

                OutputStatusMessage("-----\nAddCampaigns:");
                AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync(
                    accountId : authorizationData.AccountId,
                    campaigns : campaigns,
                    includeDynamicSearchAdsSource : false);

                long?[]      campaignIds    = addCampaignsResponse.CampaignIds.ToArray();
                BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray();
                OutputStatusMessage("CampaignIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors);

                long campaignId = (long)campaignIds[0];

                // You may choose to associate an exclusive set of negative keywords to an individual campaign
                // or ad group. An exclusive set of negative keywords cannot be shared with other campaigns
                // or ad groups. This example only associates negative keywords with a campaign.

                var entityNegativeKeywords = new[]
                {
                    new EntityNegativeKeyword
                    {
                        EntityId         = campaignId,
                        EntityType       = "Campaign",
                        NegativeKeywords = new[]
                        {
                            new NegativeKeyword
                            {
                                MatchType = MatchType.Phrase,
                                Text      = "auto"
                            },
                            new NegativeKeyword
                            {
                                MatchType = MatchType.Exact,
                                Text      = "auto"
                            },
                        }
                    }
                };

                OutputStatusMessage("-----\nAddNegativeKeywordsToEntities:");
                AddNegativeKeywordsToEntitiesResponse addNegativeKeywordsToEntitiesResponse =
                    await CampaignManagementExampleHelper.AddNegativeKeywordsToEntitiesAsync(
                        entityNegativeKeywords : entityNegativeKeywords);

                OutputStatusMessage("Added an exclusive set of negative keywords to the Campaign");
                OutputStatusMessage("NegativeKeywordIds:");
                CampaignManagementExampleHelper.OutputArrayOfIdCollection(addNegativeKeywordsToEntitiesResponse.NegativeKeywordIds);
                OutputStatusMessage("NestedPartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(addNegativeKeywordsToEntitiesResponse.NestedPartialErrors);

                // If you attempt to delete a negative keyword without an identifier the operation will return
                // partial errors corresponding to the index of the negative keyword that was not deleted.

                OutputStatusMessage("-----\nDeleteNegativeKeywordsFromEntities:");
                BatchErrorCollection[] nestedPartialErrors = (await CampaignManagementExampleHelper.DeleteNegativeKeywordsFromEntitiesAsync(
                                                                  entityNegativeKeywords: entityNegativeKeywords)).NestedPartialErrors.ToArray();
                OutputStatusMessage("Attempt to DeleteNegativeKeywordsFromEntities without NegativeKeyword identifier partially fails by design.");
                CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(nestedPartialErrors);

                // Negative keywords can also be added and deleted from a shared negative keyword list.
                // The negative keyword list can be shared or associated with multiple campaigns.
                // NegativeKeywordList inherits from SharedList which inherits from SharedEntity.

                var negativeKeywordList = new NegativeKeywordList
                {
                    Name = "My Negative Keyword List" + DateTime.UtcNow,
                    Type = "NegativeKeywordList"
                };

                SharedListItem[] negativeKeywords =
                {
                    new NegativeKeyword
                    {
                        Text      = "car",
                        Type      = "NegativeKeyword",
                        MatchType = MatchType.Exact
                    },
                    new NegativeKeyword
                    {
                        Text      = "car",
                        Type      = "NegativeKeyword",
                        MatchType = MatchType.Phrase
                    }
                };

                // Add a negative keyword list that can be shared.

                OutputStatusMessage("-----\nAddSharedEntity:");
                var addSharedEntityResponse = await CampaignManagementExampleHelper.AddSharedEntityAsync(
                    sharedEntity : negativeKeywordList,
                    listItems : negativeKeywords);

                var    sharedEntityId = addSharedEntityResponse.SharedEntityId;
                long[] listItemIds    = addSharedEntityResponse.ListItemIds.ToArray();

                OutputStatusMessage(string.Format(
                                        "NegativeKeywordList added to account library and assigned identifer {0}",
                                        sharedEntityId)
                                    );

                // Negative keywords were added to the negative keyword list above. You can associate the
                // shared list of negative keywords with a campaign with or without negative keywords.
                // Shared negative keyword lists cannot be associated with an ad group. An ad group can only
                // be assigned an exclusive set of negative keywords.

                var associations = new[]
                {
                    new SharedEntityAssociation
                    {
                        EntityId         = campaignId,
                        EntityType       = "Campaign",
                        SharedEntityId   = sharedEntityId,
                        SharedEntityType = "NegativeKeywordList"
                    }
                };

                OutputStatusMessage("-----\nSetSharedEntityAssociations:");
                var partialErrors = (await CampaignManagementExampleHelper.SetSharedEntityAssociationsAsync(
                                         associations: associations)).PartialErrors;
                OutputStatusMessage(string.Format(
                                        "Associated CampaignId {0} with Negative Keyword List Id {1}.",
                                        campaignId, sharedEntityId)
                                    );

                // Delete the campaign and everything it contains e.g., ad groups and ads.

                OutputStatusMessage("-----\nDeleteCampaigns:");
                await CampaignManagementExampleHelper.DeleteCampaignsAsync(
                    accountId : authorizationData.AccountId,
                    campaignIds : new[] { (long)campaignIds[0] });

                OutputStatusMessage(string.Format("Deleted Campaign Id {0}", campaignIds[0]));

                // DeleteCampaigns does not delete the negative keyword list from the account's library.
                // Call the DeleteSharedEntities operation to delete the negative keyword list.

                OutputStatusMessage("-----\nDeleteSharedEntities:");
                partialErrors = (await CampaignManagementExampleHelper.DeleteSharedEntitiesAsync(
                                     sharedEntities: new SharedEntity[] { new NegativeKeywordList {
                                                                              Id = sharedEntityId
                                                                          } }))?.PartialErrors;
                OutputStatusMessage(string.Format("Deleted Negative Keyword List Id {0}", sharedEntityId));
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
        public void ChannelBindingSuccess_Http()
        {
            base.Logging();

            client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName,
                this.testConfig.LocalRealm.User[1].Username,
                this.testConfig.LocalRealm.User[1].Password,
                KerberosAccountType.User,
                testConfig.LocalRealm.KDC[0].IPAddress,
                testConfig.LocalRealm.KDC[0].Port,
                testConfig.TransportType,
                testConfig.SupportedOid);

            // Kerberos Proxy Service is used
            if (this.testConfig.UseProxy)
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client .");
                KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig);
                proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName;
                client.UseProxy = true;
                client.ProxyClient = proxyClient;
            }

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;
            client.SendAsRequest(options, null);
            //Recieve preauthentication required error
            METHOD_DATA methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string timeStamp = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                0,
                client.Context.SelectedEType,
                this.client.Context.CName.Password,
                this.client.Context.CName.Salt);
            PaPacRequest paPacRequest = new PaPacRequest(true);
            Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });
            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();
            BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT.");

            //Create and send TGS request
            client.SendTgsRequest(this.testConfig.LocalRealm.WebServer[0].HttpServiceName, options);
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();
            BaseTestSite.Assert.IsNotNull(tgsResponse.Response.ticket, "Service ticket should not be null.");

            //AP exchange part
            AdAuthDataApOptions authApOptions = new AdAuthDataApOptions(KerberosConstValue.KERB_AP_OPTIONS_CBT);
            AdIfRelevent adIfRelevent = new AdIfRelevent(new AD_IF_RELEVANT(new AuthorizationDataElement[] { authApOptions.AuthDataElement }));
            AuthorizationData data = new AuthorizationData(new AuthorizationDataElement[] { adIfRelevent.AuthDataElement });

            EncryptionKey subkey = KerberosUtility.GenerateKey(client.Context.SessionKey);
            byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired,
                data,
                subkey,
                ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send Http request.");
            KerberosApResponse apRep = client.GetApResponseFromToken(SendAndRecieveHttpAp(this.testConfig.LocalRealm.WebServer[0], token));
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve Http response.");
        }
 /// <summary>
 /// Initializes a new instance of this class with the specified <paramref name="requestId"/> and <see cref="BingAds.AuthorizationData"/>.
 /// </summary>
 /// <param name="requestId">The identifier of a download request that has previously been submitted.</param>
 /// <param name="authorizationData">
 /// Represents a user who intends to access the corresponding customer and account. 
 /// </param>
 public ReportingDownloadOperation(string requestId, AuthorizationData authorizationData)
     : this(requestId, authorizationData, null, null)
 {
 }
Exemplo n.º 11
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                CampaignService = new ServiceClient <ICampaignManagementService>(authorizationData);

                BulkServiceManager = new BulkServiceManager(authorizationData);

                var progress = new Progress <BulkOperationProgressInfo>(x =>
                                                                        OutputStatusMessage(string.Format("{0} % Complete",
                                                                                                          x.PercentComplete.ToString(CultureInfo.InvariantCulture))));

                OutputStatusMessage("Add and Update Criterions . . .\n");
                await AddUpdateDeleteCriterions().ConfigureAwait(continueOnCapturedContext: false);
            }
            // Catch Microsoft Account authorization exceptions.
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            // Catch Bulk service exceptions
            catch (FaultException <Microsoft.BingAds.V11.Bulk.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V11.Bulk.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationInProgressException ex)
            {
                OutputStatusMessage("The result file for the bulk operation is not yet available for download.");
                OutputStatusMessage(ex.Message);
            }
            catch (BulkOperationCouldNotBeCompletedException <DownloadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationCouldNotBeCompletedException <UploadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
            finally
            {
                if (Reader != null)
                {
                    Reader.Dispose();
                }
                if (Writer != null)
                {
                    Writer.Dispose();
                }
            }
        }
 internal ReportingDownloadOperation(string requestId, AuthorizationData authorizationData, string trackingId)
     : this(requestId, authorizationData, new ReportingStatusProvider(requestId), trackingId, null)
 {
 }
        private KDC_REQ_BODY CreateKdcRequestBody(
            KdcOptions kdcOptions,
            PrincipalName sName,
            AuthorizationData data = null
            )
        {
            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sName);

            if (data == null)
                return kdcReqBody;

            Asn1BerEncodingBuffer asnBuffer = new Asn1BerEncodingBuffer();
            // Fix me: NullReferenceException if data is null.
            if (data != null) data.BerEncode(asnBuffer, true);

            EncryptedData eData = new EncryptedData();
            eData.etype = new KerbInt32(0);
            byte[] encAsnEncoded = asnBuffer.Data;
            if (Context.SessionKey != null && Context.SessionKey.keytype != null
                && Context.SessionKey.keyvalue != null && Context.SessionKey.keyvalue.Value != null)
            {
                encAsnEncoded = KerberosUtility.Encrypt((EncryptionType)Context.SessionKey.keytype.Value,
                                                    Context.SessionKey.keyvalue.ByteArrayValue,
                                                    asnBuffer.Data,
                                                    (int)KeyUsageNumber.TGS_REQ_KDC_REQ_BODY_AuthorizationData);
                eData.etype = new KerbInt32(Context.SessionKey.keytype.Value);
            }
            eData.cipher = new Asn1OctetString(encAsnEncoded);
            kdcReqBody.enc_authorization_data = eData;

            return kdcReqBody;
        }
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                CustomerManagementExampleHelper CustomerManagementExampleHelper =
                    new CustomerManagementExampleHelper(this.OutputStatusMessage);
                CustomerManagementExampleHelper.CustomerManagementService =
                    new ServiceClient <ICustomerManagementService>(authorizationData, environment);

                var getUserResponse = await CustomerManagementExampleHelper.GetUserAsync(null, true);

                var user = getUserResponse.User;

                // Search for the Bing Ads accounts that the user can access.

                var predicate = new Predicate
                {
                    Field    = "UserId",
                    Operator = PredicateOperator.Equals,
                    Value    = user.Id.ToString()
                };

                var paging = new Paging
                {
                    Index = 0,
                    Size  = 10
                };

                var request = new SearchAccountsRequest
                {
                    Ordering   = null,
                    PageInfo   = paging,
                    Predicates = new[] { predicate }
                };

                var accounts = (await CustomerManagementExampleHelper.SearchAccountsAsync(
                                    new[] { predicate },
                                    null,
                                    paging
                                    ))?.Accounts.ToArray();

                OutputStatusMessage("The user can access the following Bing Ads accounts: \n");
                foreach (var account in accounts)
                {
                    CustomerManagementExampleHelper.OutputAdvertiserAccount(account);

                    // You can find out which pilot features the customer is able to use.
                    // Each account could belong to a different customer, so use the customer ID in each account.
                    var featurePilotFlags = (await CustomerManagementExampleHelper.GetCustomerPilotFeaturesAsync(account.ParentCustomerId)).FeaturePilotFlags;
                    OutputStatusMessage("Customer Pilot flags:");
                    OutputStatusMessage(string.Join("; ", featurePilotFlags.Select(flag => string.Format("{0}", flag))));
                }
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Customer Management service exceptions
            catch (FaultException <Microsoft.BingAds.V12.CustomerManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V12.CustomerManagement.ApiFault> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
        /// <summary>
        /// Create authenticator for ChecksumType.ap_authenticator_8003
        /// </summary>
        private Authenticator CreateAuthenticator(
            KerberosTicket ticket,
            AuthorizationData data,
            EncryptionKey subkey,
            ChecksumFlags checksumFlag
            )
        {
            Authenticator plaintextAuthenticator = CreateAuthenticator(ticket, data, subkey);

            AuthCheckSum checksum = new AuthCheckSum();
            checksum.Lgth = KerberosConstValue.AUTHENTICATOR_CHECKSUM_LENGTH;
            checksum.Bnd = new byte[checksum.Lgth];
            checksum.Flags = (int)checksumFlag;
            byte[] checkData = ArrayUtility.ConcatenateArrays(BitConverter.GetBytes(checksum.Lgth),
                checksum.Bnd, BitConverter.GetBytes(checksum.Flags));

            plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)ChecksumType.ap_authenticator_8003), new Asn1OctetString(checkData));
            return plaintextAuthenticator;
        }
        public void TokenRestrictionSameMachineId_Http()
        {
            base.Logging();

            client = new KerberosTestClient(
                this.testConfig.LocalRealm.RealmName,
                this.testConfig.LocalRealm.User[1].Username,
                this.testConfig.LocalRealm.User[1].Password,
                KerberosAccountType.User,
                testConfig.LocalRealm.KDC[0].IPAddress,
                testConfig.LocalRealm.KDC[0].Port,
                testConfig.TransportType,
                testConfig.SupportedOid);

            // Kerberos Proxy Service is used
            if (this.testConfig.UseProxy)
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client .");
                KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig);
                proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName;
                client.UseProxy = true;
                client.ProxyClient = proxyClient;
            }

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;
            client.SendAsRequest(options, null);
            //Recieve preauthentication required error
            METHOD_DATA methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string timeStamp = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                0,
                client.Context.SelectedEType,
                this.client.Context.CName.Password,
                this.client.Context.CName.Salt);
            PaPacRequest paPacRequest = new PaPacRequest(true);
            Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });
            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();
            BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT.");

            //Create and send TGS request
            KerbAuthDataTokenRestrictions krbAuthDataTokenRestictions = new KerbAuthDataTokenRestrictions(
                0,
                (uint)LSAP_TOKEN_INFO_INTEGRITY_Flags.FULL_TOKEN,
                (uint)LSAP_TOKEN_INFO_INTEGRITY_TokenIL.High,
                new Guid().ToString().Replace("-", ""));

            AdIfRelevent adIfRelevent = new AdIfRelevent(new AD_IF_RELEVANT(new AuthorizationDataElement[] { krbAuthDataTokenRestictions.AuthDataElement }));
            AuthorizationData data = new AuthorizationData(new AuthorizationDataElement[] { adIfRelevent.AuthDataElement });

            client.SendTgsRequest(this.testConfig.LocalRealm.WebServer[0].HttpServiceName, options, null, null, null, data);
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send TGS request");
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve a TGS response.");

            BaseTestSite.Assert.IsNotNull(tgsResponse.Response.ticket, "Service ticket should not be null.");
            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.WebServer[0].HttpServiceName,
                KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname),
                "Service principal name in service ticket should match expected.");

            EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.WebServer[0].HttpServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType);
            tgsResponse.DecryptTicket(key);

            //tgsResponse.DecryptTicket(testConfig.LocalRealm.WebServer[0].Password, testConfig.LocalRealm.WebServer[0].ServiceSalt);
            BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart, "The encrypted part of TGS-REP is decrypted.");
            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(),
                tgsResponse.TicketEncPart.crealm.Value.ToLower(),
                "Realm name in service ticket encrypted part should match expected.");
            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username,
                KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname),
                "Realm name in service ticket encrypted part should match expected.");

            //Assert authorization data
            LinkedList<IAuthDataElement> authDataList = new LinkedList<IAuthDataElement>();
            BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data.");
            KerbAuthDataTokenRestrictions tokenRestrictions = FindOneInAuthData<KerbAuthDataTokenRestrictions>(tgsResponse.TicketEncPart.authorization_data.Elements);
            BaseTestSite.Assert.IsNotNull(tokenRestrictions, "KerbAuthDataTokenRestrictions is inside the authorization data.");

            EncryptionKey subkey = KerberosUtility.GenerateKey(client.Context.SessionKey);
            byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired,
                data,
                subkey,
                ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send Http request.");
            KerberosApResponse apRep = client.GetApResponseFromToken(SendAndRecieveHttpAp(this.testConfig.LocalRealm.WebServer[0], token));
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve Http response.");
        }
        private Authenticator CreateAuthenticator(PrincipalName cname, Realm realm, EncryptionKey subkey = null, AuthorizationData data = null)
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create authenticator");
            Random r = new Random();
            int seqNum = r.Next();

            Authenticator plaintextAuthenticator = new Authenticator
            {
                authenticator_vno = new Asn1Integer(KerberosConstValue.KERBEROSV5),
                crealm = realm,
                cusec = new Microseconds(0),
                ctime = KerberosUtility.CurrentKerberosTime,
                seq_number = new KerbUInt32(seqNum),
                cname = cname,
                subkey = subkey,
                authorization_data = data
            };

            AuthCheckSum checksum = new AuthCheckSum { Lgth = KerberosConstValue.AUTHENTICATOR_CHECKSUM_LENGTH };
            checksum.Bnd = new byte[checksum.Lgth];
            checksum.Flags = (int)(ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG);
            byte[] checkData = ArrayUtility.ConcatenateArrays(BitConverter.GetBytes(checksum.Lgth),
                checksum.Bnd, BitConverter.GetBytes(checksum.Flags));
            plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)ChecksumType.ap_authenticator_8003), new Asn1OctetString(checkData));

            return plaintextAuthenticator;
        }
 private void AppendNewAuthDataElement(AuthorizationData originalAuthData, AuthorizationDataElement newElement)
 {
     int elementNum = originalAuthData.Elements.Length;
     AuthorizationDataElement[] elements = new AuthorizationDataElement[elementNum + 1];
     originalAuthData.Elements.CopyTo(elements, 0);
     elements[elementNum] = newElement;
     originalAuthData.Elements = elements;
 }
 /// <summary>
 /// Initializes a new instance of this class with the specified <see cref="AuthorizationData"/>.
 /// </summary>
 /// <param name="authorizationData">Represents a user who intends to access the corresponding customer and account. </param>
 public ReportingServiceManager(AuthorizationData authorizationData)
     : this(authorizationData, null)
 {
 }
Exemplo n.º 20
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper(this.OutputStatusMessage);
                CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient <ICampaignManagementService>(authorizationData);

                var offlineConversionGoalName = "My Offline Conversion Goal " + DateTime.UtcNow;

                var conversionGoals = new ConversionGoal[]
                {
                    new OfflineConversionGoal
                    {
                        // Determines how long after a click that you want to count offline conversions.
                        ConversionWindowInMinutes = 43200,

                        // If the count type is 'Unique' then only the first offline conversion will be counted.
                        // By setting the count type to 'All', then all offline conversions for the same
                        // MicrosoftClickId with different conversion times will be added cumulatively.
                        CountType = ConversionGoalCountType.All,

                        Name = offlineConversionGoalName,

                        // The default conversion currency code and value. Each offline conversion can override it.
                        Revenue = new ConversionGoalRevenue
                        {
                            CurrencyCode = null,
                            Type         = ConversionGoalRevenueType.FixedValue,
                            Value        = 5.00m,
                        },
                        Scope  = EntityScope.Account,
                        Status = ConversionGoalStatus.Active,
                        TagId  = null
                    },
                };

                OutputStatusMessage("Add conversion goal...\n");
                var addConversionGoalsResponse = await CampaignManagementExampleHelper.AddConversionGoalsAsync(conversionGoals);

                List <long> conversionGoalIds   = GetNonNullableIds(addConversionGoalsResponse.ConversionGoalIds);
                var         conversionGoalTypes = ConversionGoalType.OfflineConversion;
                var         getConversionGoals  =
                    (await CampaignManagementExampleHelper.GetConversionGoalsByIdsAsync(conversionGoalIds, conversionGoalTypes)).ConversionGoals;

                CampaignManagementExampleHelper.OutputArrayOfConversionGoal(getConversionGoals);

                // Every time you create a new OfflineConversionGoal via either the Bing Ads web application or Campaign Management API,
                // the MSCLKIDAutoTaggingEnabled value of the corresponding AccountProperty is set to 'true' automatically.
                // We can confirm the setting now.

                var accountPropertyNames = new List <AccountPropertyName>();
                accountPropertyNames.Add(AccountPropertyName.MSCLKIDAutoTaggingEnabled);

                OutputStatusMessage("Get account properties...\n");
                var getAccountPropertiesResponse = await CampaignManagementExampleHelper.GetAccountPropertiesAsync(accountPropertyNames);

                CampaignManagementExampleHelper.OutputArrayOfAccountProperty(getAccountPropertiesResponse.AccountProperties);

                var offlineConversions = new[]
                {
                    new OfflineConversion
                    {
                        // If you do not specify an offline conversion currency code,
                        // then the 'CurrencyCode' element of the goal's 'ConversionGoalRevenue' is used.
                        ConversionCurrencyCode = "USD",

                        // The conversion name must match the 'Name' of the 'OfflineConversionGoal'.
                        // If it does not match you won't observe any error, although the offline
                        // conversion will not be counted.
                        ConversionName = offlineConversionGoalName,

                        // The date and time must be in UTC, should align to the date and time of the
                        // recorded click (MicrosoftClickId), and cannot be in the future.
                        ConversionTime = DateTime.UtcNow,

                        // If you do not specify an offline conversion value,
                        // then the 'Value' element of the goal's 'ConversionGoalRevenue' is used.
                        ConversionValue = 10,

                        MicrosoftClickId = "f894f652ea334e739002f7167ab8f8e3"
                    }
                };

                // After the OfflineConversionGoal is set up, wait two hours before sending Bing Ads the offline conversions.
                // This example would not succeed in production because we created the goal very recently i.e.,
                // please see above call to AddConversionGoalsAsync.

                OutputStatusMessage("Apply the offline conversion...\n");
                var applyOfflineConversionsResponse = await CampaignManagementExampleHelper.ApplyOfflineConversionsAsync(offlineConversions);

                CampaignManagementExampleHelper.OutputArrayOfOfflineConversion(offlineConversions);
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
        /// <summary>
        /// Create AP request and encode to GSSAPI token
        /// </summary>
        /// <param name="apOptions">AP options</param>
        /// <param name="data">Authorization data</param>
        /// <param name="subkey">Sub-session key in authenticator</param>
        /// <param name="checksumFlags">Checksum flags</param>
        /// <returns></returns>
        public byte[] CreateGssApiToken(ApOptions apOptions, AuthorizationData data, EncryptionKey subkey, ChecksumFlags checksumFlags,
            Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.KerberosConstValue.GSSToken gssToken = KerberosConstValue.GSSToken.GSSSPNG)
        {
            APOptions options = new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions));

            Authenticator authenticator = CreateAuthenticator(Context.Ticket, data, subkey, checksumFlags);

            KerberosApRequest request = new KerberosApRequest(
                Context.Pvno,
                options,
                Context.Ticket,
                authenticator,
                KeyUsageNumber.AP_REQ_Authenticator
                );

            return KerberosUtility.AddGssApiTokenHeader(request, this.oidPkt, gssToken);
        }
 /// <summary>
 /// Initializes a new instance of this class with the specified <paramref name="requestId"/> and <see cref="BingAds.AuthorizationData"/>.
 /// </summary>
 /// <param name="requestId">The identifier of a download request that has previously been submitted.</param>
 /// <param name="authorizationData">
 /// Represents a user who intends to access the corresponding customer and account.
 /// </param>
 public ReportingDownloadOperation(string requestId, AuthorizationData authorizationData)
     : this(requestId, authorizationData, null, null)
 {
 }
        /// <summary>
        /// Create and send TGS request
        /// </summary>
        /// <param name="sName">Service principal name</param>
        /// <param name="kdcOptions">KDC options</param>
        /// <param name="seqPadata">A sequence of preauthentication data</param>
        /// <param name="checksumType">Checksum type of PA-TGS-REQ</param>
        /// <param name="additionalTicket">Additional ticket</param>
        /// <param name="data">Authorization data</param>
        public void SendTgsRequest(string sName,
            KdcOptions kdcOptions,
            Asn1SequenceOf<PA_DATA> seqPadata = null,
            Ticket additionalTicket = null,
            AuthorizationData dataInAuthenticator = null,
            AuthorizationData dataInEncAuthData = null)
        {
            if (sName == null)
            {
                throw new ArgumentNullException("sName");
            }
            PrincipalName sname = new PrincipalName(
                new KerbInt32((int)PrincipalType.NT_SRV_INST),
                KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, dataInEncAuthData);
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();
            kdcReqBody.BerEncode(bodyBuffer);

            ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType);
            PA_DATA paTgsReq = CreatePaTgsReq(checksumType, bodyBuffer.Data, dataInAuthenticator);

            Asn1SequenceOf<PA_DATA> tempPaData = null;
            if (seqPadata == null || seqPadata.Elements == null || seqPadata.Elements.Length == 0)
            {
                tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq });
            }
            else
            {
                PA_DATA[] paDatas = new PA_DATA[seqPadata.Elements.Length + 1];
                Array.Copy(seqPadata.Elements, paDatas, seqPadata.Elements.Length);
                paDatas[seqPadata.Elements.Length] = paTgsReq;
                tempPaData = new Asn1SequenceOf<PA_DATA>(paDatas);
            }

            KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, tempPaData, Context.TransportType);
            this.SendPdu(tgsRequest);
            this.testSite.Log.Add(LogEntryKind.Debug, "Send TGS request.");
        }
        public void AdFxFastArmorInAuthenticator()
        {
            base.Logging();

            client = new KerberosTestClient(
                this.testConfig.LocalRealm.RealmName,
                this.testConfig.LocalRealm.ClientComputer.NetBiosName,
                this.testConfig.LocalRealm.ClientComputer.Password,
                KerberosAccountType.Device,
                testConfig.LocalRealm.KDC[0].IPAddress,
                testConfig.LocalRealm.KDC[0].Port,
                testConfig.TransportType,
                testConfig.SupportedOid,
               testConfig.LocalRealm.ClientComputer.AccountSalt);

            // Kerberos Proxy Service is used
            if (this.testConfig.UseProxy)
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client .");
                KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig);
                proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName;
                client.UseProxy = true;
                client.ProxyClient = proxyClient;
            }

            // AS_REQ and KRB-ERROR using device principal
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;
            client.SendAsRequest(options, null);
            METHOD_DATA methodData;
            KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData);

            // AS_REQ and AS_REP using device principal
            string timeStamp = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(
                timeStamp,
                0,
                client.Context.SelectedEType,
                this.client.Context.CName.Password,
                this.client.Context.CName.Salt);
            Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data });
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                string.Format("The type of AS-REP encrypted part is {0}.", asResponse.EncPart.GetType().Name));

            AdFxFastArmor adFxFastArmor = new AdFxFastArmor();
            AuthorizationData authData = new AuthorizationData(new AuthorizationDataElement[] { adFxFastArmor.AuthDataElement });
            client.SendTgsRequest(testConfig.LocalRealm.ClientComputer.DefaultServiceName, options, null, null, authData);
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Receive TGS Error, KDC MUST reject the request.");
            KerberosKrbError krbError = client.ExpectKrbError();
        }
        /// <summary>
        /// Create and send FAST TGS request
        /// </summary>
        /// <param name="sName">Service principal name</param>
        /// <param name="kdcOptions">KDC options</param>
        /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param>
        /// <param name="outerSeqPaData">A sequence of preauthentication data</param>
        /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param>
        /// <param name="fastOptions">FAST options</param>
        /// <param name="apOptions">AP options in FAST armor field</param>
        /// <param name="data">Authorization data</param>
        public void SendTgsRequestWithExplicitFast(
            string sName,
            KdcOptions kdcOptions,
            Asn1SequenceOf<PA_DATA> innerSeqPaData,
            Asn1SequenceOf<PA_DATA> outerSeqPaData,
            EncryptionKey subKey,
            FastOptions fastOptions,
            ApOptions apOptions,
            AuthorizationData data = null)
        {
            Context.Subkey = subKey;
            Context.ReplyKey = subKey;
            string domain = this.Context.Realm.Value;
            PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST),
                KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, data);
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();
            kdcReqBody.BerEncode(bodyBuffer);

            //Create PA-TGS-REQ
            APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None));
            ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType);
            KerberosApRequest apRequest = CreateApRequest(
                option,
                Context.Ticket,
                subKey,
                data,
                KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator,
                checksumType,
                bodyBuffer.Data);

            PaTgsReq paTgsReq = new PaTgsReq(apRequest.Request);

            Asn1SequenceOf<PA_DATA> tempPaData = null;
            if (outerSeqPaData == null || outerSeqPaData.Elements == null || outerSeqPaData.Elements.Length == 0)
            {
                tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq.Data });
            }
            else
            {
                tempPaData.Elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, tempPaData.Elements, outerSeqPaData.Elements.Length);
                tempPaData.Elements[outerSeqPaData.Elements.Length] = paTgsReq.Data;
            }
            //Create explicit FAST armor
            EncryptionKey explicitSubkey = KerberosUtility.MakeKey(
                Context.SelectedEType,
                "Password04!",
                "This is a salt");
            Authenticator plaintextAuthenticator = CreateAuthenticator(Context.ArmorTicket, null, explicitSubkey);
            KerberosApRequest apReq = new KerberosApRequest(Context.Pvno,
                new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions)),
                Context.ArmorTicket,
                plaintextAuthenticator,
                KeyUsageNumber.AP_REQ_Authenticator);
            FastArmorApRequest explicitArmor = new FastArmorApRequest(apReq.Request);

            //Create armor key
            var armorKey = GetArmorKey(Context.ArmorSessionKey, subKey, explicitSubkey);
            Context.FastArmorkey = armorKey;

            //Create PA-FX-FAST
            var pafxfast = CreateTgsPaFxFast(armorKey, Context.ArmorTicket, fastOptions, apOptions, tempPaData, sName, paTgsReq.Data.padata_value.ByteArrayValue, explicitArmor);

            PA_DATA[] elements;
            if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0)
            {
                elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length);
                elements[outerSeqPaData.Elements.Length] = pafxfast.Data;
                elements[outerSeqPaData.Elements.Length + 1] = paTgsReq.Data;
            }
            else
            {
                elements = new PA_DATA[] { pafxfast.Data, paTgsReq.Data };
            }
            Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>();
            KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements), Context.TransportType);

            this.SendPdu(tgsRequest);
            this.testSite.Log.Add(LogEntryKind.Debug, "Send FAST TGS request.");
        }
 internal ReportingDownloadOperation(string requestId, AuthorizationData authorizationData, string trackingId, ApiEnvironment? apiEnvironment)
     : this(requestId, authorizationData, new ReportingStatusProvider(requestId), trackingId, apiEnvironment)
 {
 }
        /// <summary>
        /// Create and send FAST TGS request
        /// </summary>
        /// <param name="sName">Service principal name</param>
        /// <param name="kdcOptions">KDC options</param>
        /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param>
        /// <param name="outerSeqPaData">A sequence of preauthentication data</param>
        /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param>
        /// <param name="fastOptions">FAST options</param>
        /// <param name="apOptions">AP options in FAST armor field</param>
        /// <param name="data">Authorization data</param>
        public void SendTgsRequestWithFastHideCName(
            string sName,
            PrincipalName cName,
            KdcOptions kdcOptions,
            Asn1SequenceOf<PA_DATA> innerSeqPaData,
            Asn1SequenceOf<PA_DATA> outerSeqPaData,
            EncryptionKey subKey,
            ApOptions apOptions,
            AuthorizationData data = null)
        {
            var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(
                KerberosUtility.ConvertInt2Flags((int)FastOptionFlags.Hide_Client_Names));
            Context.Subkey = subKey;
            Context.ReplyKey = subKey;
            string domain = this.Context.Realm.Value;
            PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST),
                KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, data);
            kdcReqBody.cname = cName;
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();
            kdcReqBody.BerEncode(bodyBuffer);

            APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None));
            ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType);
            KerberosApRequest apRequest = CreateApRequest(
                option,
                Context.Ticket,
                subKey,
                data,
                KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator,
                checksumType,
                bodyBuffer.Data);

            PaTgsReq paTgsReq = new PaTgsReq(apRequest.Request);

            Asn1SequenceOf<PA_DATA> tempPaData = null;
            if (outerSeqPaData == null || outerSeqPaData.Elements == null || outerSeqPaData.Elements.Length == 0)
            {
                tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq.Data });
            }
            else
            {
                tempPaData.Elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, tempPaData.Elements, outerSeqPaData.Elements.Length);
                tempPaData.Elements[outerSeqPaData.Elements.Length] = paTgsReq.Data;
            }
            var armorKey = GetArmorKey(Context.SessionKey, subKey);
            var pafxfast = CreateTgsPaFxFast(armorKey, Context.Ticket, fastOptions, apOptions, tempPaData, sName, paTgsReq.Data.padata_value.ByteArrayValue);
            Context.FastArmorkey = armorKey;
            PA_DATA[] elements;
            if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0)
            {
                elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length);
                elements[outerSeqPaData.Elements.Length] = pafxfast.Data;
                elements[outerSeqPaData.Elements.Length + 1] = paTgsReq.Data;
            }
            else
            {
                elements = new PA_DATA[] { pafxfast.Data, paTgsReq.Data };
            }
            Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>();
            KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements), Context.TransportType);

            this.SendPdu(tgsRequest);
            this.testSite.Log.Add(LogEntryKind.Debug, "Send FAST TGS request.");
        }
        public KileTgsResponse CreateTgsResponse(
            KileConnection kileConnection,
            _SeqOfPA_DATA seqOfPaData,
            EncTicketFlags encTicketFlags,
            EncryptionKey ticketEncryptKey,
            AuthorizationData ticketAuthorizationData)
        {
            KileServerContext serverContext = GetServerContextByKileConnection(kileConnection);

            if (ticketEncryptKey == null)
            {
                throw new ArgumentNullException("ticketEncryptKey");
            }
            else
            {
                serverContext.TicketEncryptKey = ticketEncryptKey;
            }
            KileTgsResponse response = new KileTgsResponse(serverContext);

            // Construct a Ticket
            Ticket ticket = new Ticket();
            ticket.tkt_vno = new Asn1Integer(ConstValue.KERBEROSV5);
            ticket.realm = new Realm(domain);
            ticket.sname = serverContext.SName;

            // Set EncTicketPart
            EncTicketPart encTicketPart = new EncTicketPart();
            EncryptionType encryptionType = (EncryptionType)serverContext.EncryptType.elements[0].mValue;
            encTicketPart.key = new EncryptionKey((int)encryptionType, GetEncryptionKeyByType(encryptionType));
            encTicketPart.flags = new TicketFlags(KileUtility.ConvertInt2Flags((int)encTicketFlags));
            encTicketPart.crealm = serverContext.TgsTicket.crealm;
            encTicketPart.cname = serverContext.TgsTicket.cname;
            encTicketPart.transited = serverContext.TgsTicket.transited;
            encTicketPart.authtime = KileUtility.CurrentKerberosTime;
            encTicketPart.starttime = KileUtility.CurrentKerberosTime;
            encTicketPart.endtime = serverContext.TgsTicket.endtime;
            encTicketPart.renew_till = serverContext.TgsTicket.renew_till;
            encTicketPart.caddr = serverContext.Addresses;
            encTicketPart.authorization_data = ticketAuthorizationData;
            response.TicketEncPart = encTicketPart;

            // Set AS_REP
            response.Response.pvno = new Asn1Integer(ConstValue.KERBEROSV5);
            response.Response.msg_type = new Asn1Integer((int)MsgType.KRB_TGS_RESP);
            response.Response.padata = seqOfPaData;
            response.Response.crealm = serverContext.UserRealm;
            response.Response.cname = serverContext.UserName;
            response.Response.ticket = ticket;

            // Set EncASRepPart
            EncTGSRepPart encTGSRepPart = new EncTGSRepPart();
            encTGSRepPart.key = encTicketPart.key;
            LastReq_element element = new LastReq_element(new Int32(0), KileUtility.CurrentKerberosTime);
            encTGSRepPart.last_req = new LastReq(new LastReq_element[] { element });
            encTGSRepPart.nonce = serverContext.Nonce;
            encTGSRepPart.flags = encTicketPart.flags;
            encTGSRepPart.authtime = encTicketPart.authtime;
            encTGSRepPart.starttime = encTicketPart.starttime;
            encTGSRepPart.endtime = encTicketPart.endtime;
            encTGSRepPart.renew_till = encTicketPart.renew_till;
            encTGSRepPart.srealm = ticket.realm;
            encTGSRepPart.sname = ticket.sname;
            encTGSRepPart.caddr = encTicketPart.caddr;
            response.EncPart = encTGSRepPart;

            return response;
        }
 private KerberosApRequest CreateApRequest(APOptions option, KerberosTicket ticket, EncryptionKey subkey, AuthorizationData data, KeyUsageNumber keyUsageNumber, ChecksumType checksumType, byte[] checksumBody)
 {
     Authenticator authenticator = CreateAuthenticator(ticket, data, subkey, checksumType, checksumBody);
     KerberosApRequest apReq = new KerberosApRequest(Context.Pvno, option, ticket, authenticator, keyUsageNumber);
     return apReq;
 }
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                CustomerService = new ServiceClient <ICustomerManagementService>(authorizationData);

                var getUserResponse = await GetUserAsync(null);

                var user = getUserResponse.User;

                // Only a user with the aggregator role (33) can sign up new customers.
                // If the user does not have the aggregator role, then do not continue.
                if (!getUserResponse.Roles.Contains(33))
                {
                    OutputStatusMessage("Only a user with the aggregator role (33) can sign up new customers.");
                    return;
                }

                // For Customer.CustomerAddress and Account.BusinessAddress, you can use the same address
                // as your aggregator user, although you must set Id and TimeStamp to null.
                var userAddress = user.ContactInfo.Address;
                userAddress.Id        = null;
                userAddress.TimeStamp = null;

                var customer = new Customer
                {
                    // The customer's business address.
                    CustomerAddress = userAddress,

                    // The list of key and value strings for forward compatibility. This element can be used
                    // to avoid otherwise breaking changes when new elements are added in future releases.
                    // There are currently no forward compatibility changes for the Customer object.
                    ForwardCompatibilityMap = null,

                    // The primary business segment of the customer, for example, automotive, food, or entertainment.
                    Industry = Industry.Other,

                    // The primary country where the customer operates. This country will be the
                    // default country for ad groups in the customer’s campaigns.
                    MarketCountry = "US",

                    // The primary language that the customer uses. This language will be the
                    // default language for ad groups in the customer’s campaigns.
                    MarketLanguage = LanguageType.English,

                    // The name of the customer. This element can contain a maximum of 100 characters.
                    Name = "Child Customer " + DateTime.UtcNow,
                };

                // Optionally you can set up each account with auto tagging.
                // The AutoTag key and value pair is an account level setting that determines whether to append or replace
                // the supported UTM tracking codes within the final URL of ads delivered. The default value is '0', and
                // Bing Ads will not append any UTM tracking codes to your ad or keyword final URL.
                var accountFCM = new List <KeyValuePair <string, string> >();
                accountFCM.Add(new KeyValuePair <string, string>(
                                   "AutoTag",
                                   "0"));

                var account = new AdvertiserAccount
                {
                    // The type of account. Bing Ads API only supports the Advertiser account.
                    AccountType = AccountType.Advertiser,

                    // The location where your business is legally registered.
                    // The business address is used to determine your tax requirements.
                    // BusinessAddress will be required in a future version of the Bing Ads API.
                    // Please start using it.
                    BusinessAddress = userAddress,

                    // The type of currency that is used to settle the account. The service uses the currency information for billing purposes.
                    CurrencyType = CurrencyType.USDollar,

                    // The list of key and value strings for forward compatibility. This element can be used
                    // to avoid otherwise breaking changes when new elements are added in future releases.
                    ForwardCompatibilityMap = accountFCM,

                    // The name of the account. The name can contain a maximum of 100 characters and must be unique within the customer.
                    Name = "Child Account " + DateTime.UtcNow,

                    // The identifier of the customer that owns the account. In the Bing Ads API operations
                    // that require a customer identifier, this is the identifier that you set the CustomerId SOAP header to.
                    ParentCustomerId = (long)user.CustomerId,

                    // The list of key and value strings for tax information.
                    // The TaxId (VAT identifier) is optional. If specified, The VAT identifier must be valid
                    // in the country that you specified in the BusinessAddress element. Without a VAT registration
                    // number or exemption certificate, taxes might apply based on your business location.
                    TaxInformation = null,

                    // The default time-zone value to use for campaigns in this account.
                    // If not specified, the time zone will be set to PacificTimeUSCanadaTijuana by default.
                    // TimeZone will be required in a future version of the Bing Ads API.
                    // Please start using it.
                    TimeZone = TimeZoneType.PacificTimeUSCanadaTijuana,
                };

                // Signup a new customer and account for the reseller.
                var signupCustomerResponse = await SignupCustomerAsync(
                    customer,
                    account,
                    user.CustomerId);

                OutputStatusMessage(string.Format("New Customer and Account:\n"));

                // This is the identifier that you will use to set the CustomerId
                // element in most of the Bing Ads API service operations.
                OutputStatusMessage(string.Format("\tCustomerId: {0}", signupCustomerResponse.CustomerId));

                // The read-only system-generated customer number that is used in the Bing Ads web application.
                // The customer number is of the form, Cnnnnnnn, where nnnnnnn is a series of digits.
                OutputStatusMessage(string.Format("\tCustomerNumber: {0}", signupCustomerResponse.CustomerNumber));

                // This is the identifier that you will use to set the AccountId and CustomerAccountId
                // elements in most of the Bing Ads API service operations.
                OutputStatusMessage(string.Format("\tAccountId: {0}", signupCustomerResponse.AccountId));

                // The read-only system generated account number that is used to identify the account in the Bing Ads web application.
                // The account number has the form xxxxxxxx, where xxxxxxxx is a series of any eight alphanumeric characters.
                OutputStatusMessage(string.Format("\tAccountNumber: {0}", signupCustomerResponse.AccountNumber));
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Customer Management service exceptions
            catch (FaultException <Microsoft.BingAds.V11.CustomerManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V11.CustomerManagement.ApiFault> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
 private Authenticator CreateAuthenticator(
     KerberosTicket ticket,
     AuthorizationData data,
     EncryptionKey subkey
     )
 {
     Authenticator plaintextAuthenticator = new Authenticator();
     plaintextAuthenticator.authenticator_vno = new Asn1Integer(KerberosConstValue.KERBEROSV5);
     plaintextAuthenticator.crealm = Context.CName.Realm;
     plaintextAuthenticator.cusec = new Microseconds(0);
     plaintextAuthenticator.ctime = KerberosUtility.CurrentKerberosTime;
     plaintextAuthenticator.seq_number = new KerbUInt32(0);
     plaintextAuthenticator.cname = ticket.TicketOwner;
     plaintextAuthenticator.subkey = subkey;
     plaintextAuthenticator.authorization_data = data;
     return plaintextAuthenticator;
 }
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                CampaignService = new ServiceClient <ICampaignManagementService>(authorizationData);

                // Add a campaign that will later be associated with negative keywords.

                var campaigns = new[] {
                    new Campaign
                    {
                        Name        = "Women's Shoes " + DateTime.UtcNow,
                        Description = "Red shoes line.",

                        // You must choose to set either the shared  budget ID or daily amount.
                        // You can set one or the other, but you may not set both.
                        BudgetId      = null,
                        DailyBudget   = 50,
                        BudgetType    = BudgetLimitType.DailyBudgetStandard,
                        BiddingScheme = new EnhancedCpcBiddingScheme(),

                        TimeZone = "PacificTimeUSCanadaTijuana",
                    }
                };

                AddCampaignsResponse addCampaignsResponse = await AddCampaignsAsync(authorizationData.AccountId, campaigns);

                long?[]      campaignIds    = addCampaignsResponse.CampaignIds.ToArray();
                BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray();
                OutputIds(campaignIds);
                OutputPartialErrors(campaignErrors);
                long campaignId = (long)campaignIds[0];

                // You may choose to associate an exclusive set of negative keywords to an individual campaign
                // or ad group. An exclusive set of negative keywords cannot be shared with other campaigns
                // or ad groups. This example only associates negative keywords with a campaign.

                var entityNegativeKeywords = new[]
                {
                    new EntityNegativeKeyword
                    {
                        EntityId         = campaignId,
                        EntityType       = "Campaign",
                        NegativeKeywords = new[]
                        {
                            new NegativeKeyword
                            {
                                MatchType = MatchType.Phrase,
                                Text      = "auto"
                            },
                            new NegativeKeyword
                            {
                                MatchType = MatchType.Phrase,
                                Text      = "auto"
                            },
                        }
                    }
                };

                AddNegativeKeywordsToEntitiesResponse addNegativeKeywordsToEntitiesResponse =
                    await AddNegativeKeywordsToEntitiesAsync(entityNegativeKeywords);

                OutputNegativeKeywordIds(addNegativeKeywordsToEntitiesResponse.NegativeKeywordIds);
                OutputBatchErrorCollections(addNegativeKeywordsToEntitiesResponse.NestedPartialErrors);
                if (addNegativeKeywordsToEntitiesResponse.NestedPartialErrors == null ||
                    addNegativeKeywordsToEntitiesResponse.NestedPartialErrors.Count == 0)
                {
                    OutputStatusMessage("Added an exclusive set of negative keywords to the Campaign.\n");
                    OutputNegativeKeywordIds(addNegativeKeywordsToEntitiesResponse.NegativeKeywordIds);
                }
                else
                {
                    OutputBatchErrorCollections(addNegativeKeywordsToEntitiesResponse.NestedPartialErrors);
                }

                GetNegativeKeywordsByEntityIdsResponse getNegativeKeywordsByEntityIdsResponse =
                    await GetNegativeKeywordsByEntityIdsAsync(new[] { campaignId }, "Campaign", authorizationData.AccountId);

                OutputEntityNegativeKeywords(getNegativeKeywordsByEntityIdsResponse.EntityNegativeKeywords);
                OutputPartialErrors(getNegativeKeywordsByEntityIdsResponse.PartialErrors);
                if (getNegativeKeywordsByEntityIdsResponse.PartialErrors == null ||
                    getNegativeKeywordsByEntityIdsResponse.PartialErrors.Count == 0)
                {
                    OutputStatusMessage("Retrieved an exclusive set of negative keywords for the Campaign.\n");
                    OutputEntityNegativeKeywords(getNegativeKeywordsByEntityIdsResponse.EntityNegativeKeywords);
                }
                else
                {
                    OutputPartialErrors(getNegativeKeywordsByEntityIdsResponse.PartialErrors);
                }

                // If you attempt to delete a negative keyword without an identifier the operation will
                // succeed but will return partial errors corresponding to the index of the negative keyword
                // that was not deleted.
                var nestedPartialErrors = (BatchErrorCollection[])(await DeleteNegativeKeywordsFromEntitiesAsync(entityNegativeKeywords)).NestedPartialErrors;
                if (nestedPartialErrors == null || nestedPartialErrors.Length == 0)
                {
                    OutputStatusMessage("Deleted an exclusive set of negative keywords from the Campaign.\n");
                }
                else
                {
                    OutputStatusMessage("Attempt to DeleteNegativeKeywordsFromEntities without NegativeKeyword identifier partially fails by design.");
                    OutputBatchErrorCollections(nestedPartialErrors);
                }

                // Delete the negative keywords with identifiers that were returned above.
                nestedPartialErrors = (BatchErrorCollection[])(await DeleteNegativeKeywordsFromEntitiesAsync(
                                                                   getNegativeKeywordsByEntityIdsResponse.EntityNegativeKeywords)).NestedPartialErrors;
                if (nestedPartialErrors == null || nestedPartialErrors.Length == 0)
                {
                    OutputStatusMessage("Deleted an exclusive set of negative keywords from the Campaign.\n");
                }
                else
                {
                    OutputBatchErrorCollections(nestedPartialErrors);
                }

                // Negative keywords can also be added and deleted from a shared negative keyword list.
                // The negative keyword list can be shared or associated with multiple campaigns.
                // NegativeKeywordList inherits from SharedList which inherits from SharedEntity.

                var negativeKeywordList = new NegativeKeywordList
                {
                    Name = "My Negative Keyword List" + DateTime.UtcNow,
                    Type = "NegativeKeywordList"
                };

                SharedListItem[] negativeKeywords =
                {
                    new NegativeKeyword
                    {
                        Text      = "car",
                        Type      = "NegativeKeyword",
                        MatchType = MatchType.Exact
                    },
                    new NegativeKeyword
                    {
                        Text      = "car",
                        Type      = "NegativeKeyword",
                        MatchType = MatchType.Phrase
                    }
                };

                // You can create a new list for negative keywords with or without negative keywords.

                var addSharedEntityResponse = await AddSharedEntityAsync(negativeKeywordList, negativeKeywords);

                var    sharedEntityId = addSharedEntityResponse.SharedEntityId;
                long[] listItemIds    = addSharedEntityResponse.ListItemIds.ToArray();

                OutputStatusMessage(string.Format("NegativeKeywordList successfully added to account library and assigned identifer {0}\n", sharedEntityId));

                OutputNegativeKeywordsWithPartialErrors(
                    sharedEntityId,
                    negativeKeywords,
                    listItemIds,
                    addSharedEntityResponse.PartialErrors.ToArray());

                OutputStatusMessage("Negative keywords currently in NegativeKeywordList:");
                negativeKeywords = (SharedListItem[])(await GetListItemsBySharedListAsync(new NegativeKeywordList {
                    Id = sharedEntityId
                })).ListItems;
                if (negativeKeywords == null || negativeKeywords.Length == 0)
                {
                    OutputStatusMessage("None\n");
                }
                else
                {
                    OutputNegativeKeywords(negativeKeywords.Cast <NegativeKeyword>());
                }

                // To update the list of negative keywords, you must either add or remove from the list
                // using the respective AddListItemsToSharedList or DeleteListItemsFromSharedList operations.
                // To remove the negative keywords from the list pass the negative keyword identifers
                // and negative keyword list (SharedEntity) identifer.

                var partialErrors = (await DeleteListItemsFromSharedListAsync(listItemIds, new NegativeKeywordList {
                    Id = sharedEntityId
                }))?.PartialErrors;
                if (partialErrors == null || !partialErrors.Any())
                {
                    OutputStatusMessage("Deleted most recently added negative keywords from negative keyword list.\n");
                }
                else
                {
                    OutputPartialErrors(partialErrors);
                }

                OutputStatusMessage("Negative keywords currently in NegativeKeywordList:");
                negativeKeywords = (SharedListItem[])(await GetListItemsBySharedListAsync(new NegativeKeywordList {
                    Id = sharedEntityId
                })).ListItems;
                if (negativeKeywords == null || negativeKeywords.Length == 0)
                {
                    OutputStatusMessage("None\n");
                }
                else
                {
                    OutputNegativeKeywords(negativeKeywords.Cast <NegativeKeyword>());
                }

                // Whether you created the list with or without negative keywords, more can be added
                // using the AddListItemsToSharedList operation.

                negativeKeywords = new SharedListItem[]
                {
                    new NegativeKeyword
                    {
                        Text      = "auto",
                        Type      = "NegativeKeyword",
                        MatchType = MatchType.Exact
                    },
                    new NegativeKeyword
                    {
                        Text      = "auto",
                        Type      = "NegativeKeyword",
                        MatchType = MatchType.Phrase
                    }
                };

                var addListItemsToSharedListResponse = await AddListItemsToSharedListAsync(
                    negativeKeywords,
                    new NegativeKeywordList { Id = sharedEntityId });

                listItemIds = addListItemsToSharedListResponse.ListItemIds.ToArray();

                OutputNegativeKeywordsWithPartialErrors(
                    sharedEntityId,
                    negativeKeywords,
                    listItemIds,
                    addListItemsToSharedListResponse.PartialErrors.ToArray());

                OutputStatusMessage("Negative keywords currently in NegativeKeywordList:");
                negativeKeywords = (SharedListItem[])(await GetListItemsBySharedListAsync(new NegativeKeywordList {
                    Id = sharedEntityId
                })).ListItems;
                if (negativeKeywords == null || negativeKeywords.Length == 0)
                {
                    OutputStatusMessage("None\n");
                }
                else
                {
                    OutputNegativeKeywords(negativeKeywords.Cast <NegativeKeyword>());
                }

                // You can update the name of the negative keyword list.

                negativeKeywordList = new NegativeKeywordList
                {
                    Id   = sharedEntityId,
                    Name = "My Updated Negative Keyword List",
                    Type = "NegativeKeywordList"
                };

                partialErrors = (await UpdateSharedEntitiesAsync(new SharedEntity[] { negativeKeywordList })).PartialErrors;
                if (partialErrors == null || !partialErrors.Any())
                {
                    OutputStatusMessage(string.Format("Updated Negative Keyword List Name to {0}.\n", negativeKeywordList.Name));
                }
                else
                {
                    OutputPartialErrors(partialErrors);
                }

                // Get and output the negative keyword lists and store the list of identifiers.

                const string sharedEntityType = "NegativeKeywordList";
                var          sharedEntities   = (await GetSharedEntitiesByAccountIdAsync(sharedEntityType)).SharedEntities;
                OutputSharedEntityIdentifiersAsync(sharedEntities);
                var sharedEntityIds = new long[sharedEntities.Count];
                for (int index = 0; index < sharedEntities.Count; index++)
                {
                    if (sharedEntities[index].Id != null)
                    {
                        sharedEntityIds[index] = (long)sharedEntities[index].Id;
                    }
                }

                // Negative keywords were added to the negative keyword list above. You can associate the
                // shared list of negative keywords with a campaign with or without negative keywords.
                // Shared negative keyword lists cannot be associated with an ad group. An ad group can only
                // be assigned an exclusive set of negative keywords.

                var associations = new[]
                {
                    new SharedEntityAssociation
                    {
                        EntityId         = campaignId,
                        EntityType       = "Campaign",
                        SharedEntityId   = sharedEntityId,
                        SharedEntityType = "NegativeKeywordList"
                    }
                };

                partialErrors = (await SetSharedEntityAssociationsAsync(associations)).PartialErrors;
                if (partialErrors == null || !partialErrors.Any())
                {
                    OutputStatusMessage(string.Format("Associated CampaignId {0} with Negative Keyword List Id {1}.\n",
                                                      campaignId, sharedEntityId));
                }
                else
                {
                    OutputPartialErrors(partialErrors);
                }

                // Get and output the associations either by Campaign or NegativeKeywordList identifier.
                GetSharedEntityAssociationsByEntityIdsResponse getSharedEntityAssociationsByEntityIdsResponse =
                    await GetSharedEntityAssociationsByEntityIdsAsync(new[] { campaignId }, "Campaign", "NegativeKeywordList");

                OutputSharedEntityAssociations(getSharedEntityAssociationsByEntityIdsResponse.Associations);
                OutputPartialErrors(getSharedEntityAssociationsByEntityIdsResponse.PartialErrors);

                // Currently the GetSharedEntityAssociationsBySharedEntityIds operation accepts only one shared entity identifier in the list.
                GetSharedEntityAssociationsBySharedEntityIdsResponse getSharedEntityAssociationsBySharedEntityIdsResponse =
                    await GetSharedEntityAssociationsBySharedEntityIdsAsync("Campaign", new[] { sharedEntityIds[sharedEntityIds.Length - 1] }, "NegativeKeywordList");

                OutputSharedEntityAssociations(getSharedEntityAssociationsBySharedEntityIdsResponse.Associations);
                OutputPartialErrors(getSharedEntityAssociationsBySharedEntityIdsResponse.PartialErrors);

                // Explicitly delete the association between the campaign and the negative keyword list.

                partialErrors = (await DeleteSharedEntityAssociationsAsync(associations)).PartialErrors;
                if (partialErrors == null || !partialErrors.Any())
                {
                    OutputStatusMessage("Deleted NegativeKeywordList associations\n");
                }
                else
                {
                    OutputPartialErrors(partialErrors);
                }

                // Delete the campaign and any remaining assocations.

                await DeleteCampaignsAsync(authorizationData.AccountId, new[] { campaignId });

                OutputStatusMessage(string.Format("Deleted Campaign Id {0}\n", campaignId));

                // DeleteCampaigns does not delete the negative keyword list from the account's library.
                // Call the DeleteSharedEntities operation to delete the shared entities.

                partialErrors = (await DeleteSharedEntitiesAsync(new SharedEntity[] { new NegativeKeywordList {
                                                                                          Id = sharedEntityId
                                                                                      } }))?.PartialErrors;
                if (partialErrors == null || !partialErrors.Any())
                {
                    OutputStatusMessage(string.Format("Deleted Negative Keyword List (SharedEntity) Id {0}\n", sharedEntityId));
                }
                else
                {
                    OutputPartialErrors(partialErrors);
                }
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
        private Authenticator CreateAuthenticator(
            KerberosTicket ticket,
            AuthorizationData data,
            EncryptionKey subkey,
            ChecksumType checksumType,
            byte[] checksumBody
            )
        {
            Authenticator plaintextAuthenticator = CreateAuthenticator(ticket, data, subkey);

            byte[] checkData = KerberosUtility.GetChecksum(ticket.SessionKey.keyvalue.ByteArrayValue,
                checksumBody, (int)KeyUsageNumber.TGS_REQ_PA_TGS_REQ_adataOR_AP_REQ_Authenticator_cksum, checksumType);

            plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)checksumType), new Asn1OctetString(checkData));
            return plaintextAuthenticator;
        }
Exemplo n.º 34
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                Service = new ServiceClient <ICampaignManagementService>(authorizationData);

                // Get a list of all Bing Merchant Center stores associated with your CustomerId

                IList <BMCStore> stores = await GetBMCStoresByCustomerIdAsync();

                if (stores == null)
                {
                    OutputStatusMessage(
                        String.Format("You do not have any BMC stores registered for CustomerId {0}.\n", authorizationData.CustomerId)
                        );
                    return;
                }

                #region ManageCampaign

                /* Add a new Bing Shopping campaign that will be associated with a ProductScope criterion.
                 *  - Set the CampaignType element of the Campaign to Shopping.
                 *  - Create a ShoppingSetting instance and set its Priority (0, 1, or 2), SalesCountryCode, and StoreId elements.
                 *    Add this shopping setting to the Settings list of the Campaign.
                 */

                var campaign = new Campaign
                {
                    CampaignType = CampaignType.Shopping,
                    Settings     = new[] {
                        new ShoppingSetting()
                        {
                            Priority         = 0,
                            SalesCountryCode = "US",
                            StoreId          = (int)stores[0].Id
                        }
                    },
                    Name           = "Bing Shopping Campaign " + DateTime.UtcNow,
                    Description    = "Bing Shopping Campaign Example.",
                    BudgetType     = BudgetLimitType.MonthlyBudgetSpendUntilDepleted,
                    MonthlyBudget  = 1000.00,
                    TimeZone       = "PacificTimeUSCanadaTijuana",
                    DaylightSaving = true,
                };

                var campaignIds = await AddCampaignsAsync(authorizationData.AccountId, new[] { campaign });

                OutputCampaignIdentifiers(campaignIds);

                /* Optionally, you can create a ProductScope criterion that will be associated with your Bing Shopping campaign.
                 * Use the product scope criterion to include a subset of your product catalog, for example a specific brand,
                 * category, or product type. A campaign can only be associated with one ProductScope, which contains a list
                 * of up to 7 ProductCondition. You'll also be able to specify more specific product conditions for each ad group.
                 */

                var campaignCriterions = new CampaignCriterion[] {
                    new CampaignCriterion()
                    {
                        CampaignId    = campaignIds[0],
                        BidAdjustment = null,  // Reserved for future use
                        Criterion     = new ProductScope()
                        {
                            Conditions = new ProductCondition[] {
                                new ProductCondition {
                                    Operand   = "Condition",
                                    Attribute = "New"
                                },
                                new ProductCondition {
                                    Operand   = "CustomLabel0",
                                    Attribute = "MerchantDefinedCustomLabel"
                                },
                            }
                        },
                    }
                };

                var addCampaignCriterionsResponse = await(AddCampaignCriterionsAsync(
                                                              campaignCriterions,
                                                              CampaignCriterionType.ProductScope)
                                                          );

                #endregion ManageCampaign

                #region ManageAdGroup

                // Specify one or more ad groups.

                var adGroup = new AdGroup
                {
                    Name           = "Product Categories",
                    AdDistribution = AdDistribution.Search,
                    BiddingModel   = BiddingModel.Keyword,
                    PricingModel   = PricingModel.Cpc,
                    StartDate      = null,
                    EndDate        = new Date {
                        Month = 12, Day = 31, Year = 2016
                    },
                    Language = "English"
                };

                var adGroupIds = (long[]) await AddAdGroupsAsync(campaignIds[0], new[] { adGroup });

                OutputAdGroupIdentifiers(adGroupIds);

                #region BidAllProducts

                var helper = new PartitionActionHelper(adGroupIds[0]);

                var root = helper.AddUnit(
                    null,
                    new ProductCondition {
                    Operand = "All", Attribute = null
                },
                    0.35,
                    false
                    );

                OutputStatusMessage("Applying only the root as a Unit with a bid . . . \n");
                var applyProductPartitionActionsResponse = await ApplyProductPartitionActionsAsync(helper.PartitionActions);

                var adGroupCriterions = await GetAdGroupCriterionsByAdGroupIdAsync(
                    adGroupIds[0],
                    CriterionType.ProductPartition
                    );

                OutputStatusMessage("The ad group's product partition only has a tree root node: \n");
                OutputProductPartitions(adGroupCriterions);

                /*
                 * Let's update the bid of the root Unit we just added.
                 */

                BiddableAdGroupCriterion updatedRoot = new BiddableAdGroupCriterion
                {
                    Id           = applyProductPartitionActionsResponse.AdGroupCriterionIds[0],
                    CriterionBid = new FixedBid
                    {
                        Bid = new Bid
                        {
                            Amount = 0.45
                        }
                    }
                };

                helper = new PartitionActionHelper(adGroupIds[0]);
                helper.UpdatePartition(updatedRoot);

                OutputStatusMessage("Updating the bid for the tree root node . . . \n");
                await ApplyProductPartitionActionsAsync(helper.PartitionActions);

                adGroupCriterions = await GetAdGroupCriterionsByAdGroupIdAsync(
                    adGroupIds[0],
                    CriterionType.ProductPartition
                    );

                OutputStatusMessage("Updated the bid for the tree root node: \n");
                OutputProductPartitions(adGroupCriterions);

                #endregion BidAllProducts

                #region InitializeTree

                /*
                 * Now we will overwrite any existing tree root, and build a product partition group tree structure in multiple steps.
                 * You could build the entire tree in a single call since there are less than 5,000 nodes; however,
                 * we will build it in steps to demonstrate how to use the results from ApplyProductPartitionActions to update the tree.
                 *
                 * For a list of validation rules, see the Bing Shopping Campaigns technical guide:
                 * https://msdn.microsoft.com/en-US/library/bing-ads-campaign-management-bing-shopping-campaigns.aspx
                 */

                helper = new PartitionActionHelper(adGroupIds[0]);

                /*
                 * Check whether a root node exists already.
                 */
                adGroupCriterions = await GetAdGroupCriterionsByAdGroupIdAsync(
                    adGroupIds[0],
                    CriterionType.ProductPartition
                    );

                var existingRoot = GetRootNode(adGroupCriterions);
                if (existingRoot != null)
                {
                    helper.DeletePartition(existingRoot);
                }

                root = helper.AddSubdivision(
                    null,
                    new ProductCondition {
                    Operand = "All", Attribute = null
                }
                    );

                /*
                 * The direct children of any node must have the same Operand.
                 * For this example we will use CategoryL1 nodes as children of the root.
                 * For a list of valid CategoryL1 through CategoryL5 values, see the Bing Category Taxonomy:
                 * http://advertise.bingads.microsoft.com/en-us/WWDocs/user/search/en-us/Bing_Category_Taxonomy.txt
                 */
                var animalsSubdivision = helper.AddSubdivision(
                    root,
                    new ProductCondition {
                    Operand = "CategoryL1", Attribute = "Animals & Pet Supplies"
                }
                    );

                /*
                 * If you use a CategoryL2 node, it must be a descendant (child or later) of a CategoryL1 node.
                 * In other words you cannot have a CategoryL2 node as parent of a CategoryL1 node.
                 * For this example we will a CategoryL2 node as child of the CategoryL1 Animals & Pet Supplies node.
                 */
                var petSuppliesSubdivision = helper.AddSubdivision(
                    animalsSubdivision,
                    new ProductCondition {
                    Operand = "CategoryL2", Attribute = "Pet Supplies"
                }
                    );

                var brandA = helper.AddUnit(
                    petSuppliesSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = "Brand A"
                },
                    0.35,
                    false
                    );

                /*
                 * If you won't bid on Brand B, set the helper method's bidAmount to '0' and isNegative to true.
                 * The helper method will create a NegativeAdGroupCriterion and apply the condition.
                 */
                var brandB = helper.AddUnit(
                    petSuppliesSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = "Brand B"
                },
                    0,
                    true
                    );

                var otherBrands = helper.AddUnit(
                    petSuppliesSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = null
                },
                    0.35,
                    false
                    );

                var otherPetSupplies = helper.AddUnit(
                    animalsSubdivision,
                    new ProductCondition {
                    Operand = "CategoryL2", Attribute = null
                },
                    0.35,
                    false
                    );

                var electronics = helper.AddUnit(
                    root,
                    new ProductCondition {
                    Operand = "CategoryL1", Attribute = "Electronics"
                },
                    0.35,
                    false
                    );

                var otherCategoryL1 = helper.AddUnit(
                    root,
                    new ProductCondition {
                    Operand = "CategoryL1", Attribute = null
                },
                    0.35,
                    false
                    );

                OutputStatusMessage("Applying product partitions to the ad group . . . \n");
                applyProductPartitionActionsResponse = await ApplyProductPartitionActionsAsync(helper.PartitionActions);

                // To retrieve product partitions after they have been applied, call GetAdGroupCriterionsByAdGroupId.
                // The product partition with ParentCriterionId set to null is the root node.

                adGroupCriterions = await GetAdGroupCriterionsByAdGroupIdAsync(
                    adGroupIds[0],
                    CriterionType.ProductPartition
                    );

                /*
                 * The product partition group tree now has 9 nodes.
                 *
                 * All other (Root Node)
                 |
                 +-- Animals & Pet Supplies (CategoryL1)
                 |    |
                 |    +-- Pet Supplies (CategoryL2)
                 |    |    |
                 |    |    +-- Brand A
                 |    |    |
                 |    |    +-- Brand B
                 |    |    |
                 |    |    +-- All other (Brand)
                 |    |
                 |    +-- All other (CategoryL2)
                 |
                 +-- Electronics (CategoryL1)
                 |
                 +-- All other (CategoryL1)
                 |
                 */

                OutputStatusMessage("The product partition group tree now has 9 nodes: \n");
                OutputProductPartitions(adGroupCriterions);

                #endregion InitializeTree

                #region UpdateTree

                /*
                 * Let's replace the Electronics (CategoryL1) node created above with an Electronics (CategoryL1) node that
                 * has children i.e. Brand C (Brand), Brand D (Brand), and All other (Brand) as follows:
                 *
                 *  Electronics (CategoryL1)
                 |
                 +-- Brand C (Brand)
                 |
                 +-- Brand D (Brand)
                 |
                 +-- All other (Brand)
                 |
                 */

                helper = new PartitionActionHelper(adGroupIds[0]);

                /*
                 * To replace a node we must know its Id and its ParentCriterionId. In this case the parent of the node
                 * we are replacing is All other (Root Node), and was created at Index 1 of the previous ApplyProductPartitionActions call.
                 * The node that we are replacing is Electronics (CategoryL1), and was created at Index 8.
                 */
                var rootId = applyProductPartitionActionsResponse.AdGroupCriterionIds[1];
                electronics.Id = applyProductPartitionActionsResponse.AdGroupCriterionIds[8];
                helper.DeletePartition(electronics);

                var parent = new BiddableAdGroupCriterion()
                {
                    Id = rootId
                };

                var electronicsSubdivision = helper.AddSubdivision(
                    parent,
                    new ProductCondition {
                    Operand = "CategoryL1", Attribute = "Electronics"
                }
                    );

                var brandC = helper.AddUnit(
                    electronicsSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = "Brand C"
                },
                    0.35,
                    false
                    );

                var brandD = helper.AddUnit(
                    electronicsSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = "Brand D"
                },
                    0.35,
                    false
                    );

                var otherElectronicsBrands = helper.AddUnit(
                    electronicsSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = null
                },
                    0.35,
                    false
                    );

                OutputStatusMessage(
                    "Updating the product partition group to refine Electronics (CategoryL1) with 3 child nodes . . . \n"
                    );
                applyProductPartitionActionsResponse = await ApplyProductPartitionActionsAsync(helper.PartitionActions);

                adGroupCriterions = await GetAdGroupCriterionsByAdGroupIdAsync(
                    adGroupIds[0],
                    CriterionType.ProductPartition
                    );

                /*
                 * The product partition group tree now has 12 nodes, including the children of Electronics (CategoryL1):
                 *
                 * All other (Root Node)
                 |
                 +-- Animals & Pet Supplies (CategoryL1)
                 |    |
                 |    +-- Pet Supplies (CategoryL2)
                 |    |    |
                 |    |    +-- Brand A
                 |    |    |
                 |    |    +-- Brand B
                 |    |    |
                 |    |    +-- All other (Brand)
                 |    |
                 |    +-- All other (CategoryL2)
                 |
                 +-- Electronics (CategoryL1)
                 |    |
                 |    +-- Brand C (Brand)
                 |    |
                 |    +-- Brand D (Brand)
                 |    |
                 |    +-- All other (Brand)
                 |
                 +-- All other (CategoryL1)
                 |
                 */

                OutputStatusMessage(
                    "The product partition group tree now has 12 nodes, including the children of Electronics (CategoryL1): \n"
                    );
                OutputProductPartitions(adGroupCriterions);

                #endregion UpdateTree

                #endregion ManageAdGroup

                #region ManageAds

                /*
                 * Create a product ad. You must add at least one ProductAd to the corresponding ad group.
                 * A ProductAd is not used directly for delivered ad copy. Instead, the delivery engine generates
                 * product ads from the product details that it finds in your Bing Merchant Center store's product catalog.
                 * The primary purpose of the ProductAd object is to provide promotional text that the delivery engine
                 * adds to the product ads that it generates. For example, if the promotional text is set to
                 * “Free shipping on $99 purchases”, the delivery engine will set the product ad’s description to
                 * “Free shipping on $99 purchases.”
                 */

                var ads = new Ad[] {
                    new ProductAd
                    {
                        PromotionalText = "Free shipping on $99 purchases."
                    },
                };

                AddAdsResponse addAdsResponse = await AddAdsAsync(adGroupIds[0], ads);

                OutputAdResults(ads, addAdsResponse.AdIds, addAdsResponse.PartialErrors);

                #endregion ManageAds

                #region CleanUp

                /* Delete the campaign, ad group, criterion, and ad that were previously added.
                 * You should remove this region if you want to view the added entities in the
                 * Bing Ads web application or another tool.
                 */

                DeleteCampaignsAsync(authorizationData.AccountId, new[] { campaignIds[0] });
                OutputStatusMessage(String.Format("Deleted CampaignId {0}\n", campaignIds[0]));

                #endregion CleanUp
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
 internal BulkDownloadOperation(string requestId, AuthorizationData authorizationData, string trackingId, ApiEnvironment?apiEnvironment)
     : base(requestId, authorizationData, new DownloadStatusProvider(requestId), trackingId, apiEnvironment)
 {
 }
Exemplo n.º 36
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                OutputStatusMessage("You must edit the ManageClient.cs file to provide the ClientAccountId for " +
                                    "the client link.");
                OutputStatusMessage("When adding a client link, the client link's ManagingCustomerId is set to the CustomerId of the current " +
                                    "authenticated user, who must be a Super Admin of the agency.");
                OutputStatusMessage("Login as an agency Super Admin user to send a client link invitation, " +
                                    "or unlink an existing client link.");
                OutputStatusMessage("Login as a client Super Admin user to accept a client link invitation.\n");


                Service = new ServiceClient <ICustomerManagementService>(authorizationData);

                UpdateClientLinksResponse updateClientLinksResponse = null;

                // Specify the client link search criteria

                var pageInfo = new Paging
                {
                    Index = 0,  // The first page
                    Size  = 100 // The first 100 client links for this page of results
                };

                var ordering = new OrderBy
                {
                    Field = OrderByField.Number,
                    Order = SortOrder.Ascending
                };

                var predicate = new Predicate
                {
                    Field    = "ClientAccountId",
                    Operator = PredicateOperator.In,
                    Value    = ClientAccountId.ToString(CultureInfo.InvariantCulture)
                };

                // Search for client links that match the specified criteria.

                var clientLinks = await SearchClientLinksAsync(
                    new[] { ordering },
                    pageInfo,
                    new[] { predicate });

                // Determine whether the agency is already managing the specified client account.
                // If a link exists with status either Active, LinkInProgress, LinkPending,
                // UnlinkInProgress, or UnlinkPending, the agency may not initiate a duplicate client link.

                ClientLink clientLink;
                var        newLinkRequired = true;

                if (clientLinks.Count > 0)
                {
                    clientLink = clientLinks[0];
                    OutputStatusMessage(String.Format("Current ClientLink Status: {0}.\n", clientLink.Status));

                    switch (clientLink.Status)
                    {
                    // The agency may choose to initiate the unlink process,
                    // which would terminate the existing relationship with the client.
                    case ClientLinkStatus.Active:
                        clientLink.Status         = ClientLinkStatus.UnlinkRequested;
                        updateClientLinksResponse = await UpdateClientLinksAsync(new[] { clientLink });

                        OutputStatusMessage("UpdateClientLinks : UnlinkRequested.\n");
                        newLinkRequired = false;
                        break;

                    // Waiting on a system status transition or waiting for the StartDate.
                    case ClientLinkStatus.LinkAccepted:
                        OutputStatusMessage("The status is transitioning towards LinkInProgress.\n");
                        newLinkRequired = false;
                        break;

                    // Waiting on a system status transition.
                    case ClientLinkStatus.LinkInProgress:
                        OutputStatusMessage("The status is transitioning towards Active.\n");
                        newLinkRequired = false;
                        break;

                    // When the status is LinkPending, either the agency or client may update the status.
                    // The agency may choose to cancel the client link invitation; however, in this example
                    // the client will accept the invitation.
                    // If the client does not accept or decline the invitation within 30 days, and if the agency
                    // does not update the status to LinkCanceled, the system updates the status to LinkExpired.
                    case ClientLinkStatus.LinkPending:
                        /*
                         * clientLink.Status = ClientLinkStatus.LinkCanceled;
                         * updateClientLinksResponse = UpdateClientLinks(new[] { clientLink });
                         * WriteMessage(String.Format("The agency updated status: LinkCanceled.\n");
                         */
                        clientLink.Status         = ClientLinkStatus.LinkAccepted;
                        updateClientLinksResponse = await UpdateClientLinksAsync(new[] { clientLink });

                        OutputStatusMessage("UpdateClientLinks: LinkAccepted.\n");
                        newLinkRequired = false;
                        break;

                    // Waiting on a system status transition.
                    case ClientLinkStatus.UnlinkInProgress:
                        OutputStatusMessage("The status is transitioning towards Inactive.\n");
                        newLinkRequired = false;
                        break;

                    // Waiting on a system status transition.
                    case ClientLinkStatus.UnlinkPending:
                        OutputStatusMessage("The status is transitioning towards Inactive.\n");
                        newLinkRequired = false;
                        break;

                    // The link lifecycle has ended.
                    default:
                        OutputStatusMessage("A new client link invitation is required.\n");
                        break;
                    }

                    // Print errors if any occurred when updating the client link.
                    if (updateClientLinksResponse != null)
                    {
                        PrintPartialErrors(updateClientLinksResponse.OperationErrors,
                                           updateClientLinksResponse.PartialErrors);
                    }
                }

                // If no links exist between the agency and specified client account, or a link exists with status
                // either Inactive, LinkCanceled, LinkDeclined, LinkExpired, or LinkFailed, then the agency must
                // initiate a new client link.

                if (newLinkRequired)
                {
                    clientLink = new ClientLink
                    {
                        ClientAccountId    = ClientAccountId,
                        ManagingCustomerId = authorizationData.CustomerId,
                        IsBillToClient     = true,
                        Name                 = "My Client Link",
                        StartDate            = null,
                        SuppressNotification = true
                    };

                    var addClientLinksResponse = await AddClientLinksAsync(new[] { clientLink });

                    // Print errors if any occurred when adding the client link.

                    PrintPartialErrors(addClientLinksResponse.OperationErrors.ToArray(), addClientLinksResponse.PartialErrors.ToArray());
                    OutputStatusMessage(string.Format("The user attempted to add a new ClientLink.\n"));
                    OutputStatusMessage(string.Format("Login as the client Super Admin to accept the agency's request to manage AccountId {0}.\n", ClientAccountId));
                }

                // Get and print the current client link

                clientLinks = await SearchClientLinksAsync(
                    new[] { ordering },
                    pageInfo,
                    new[] { predicate });

                PrintClientLinks(clientLinks);
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Customer Management service exceptions
            catch (FaultException <Microsoft.BingAds.CustomerManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.CustomerManagement.ApiFault> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
Exemplo n.º 37
0
        public KileTgsRequest CreateTgsRequest(
            Realm cRealm,
            PrincipalName cName,
            PrincipalName sName,
            KRBFlags kdcOptions,
            KerbUInt32 nonce,
            Realm realm,
            Asn1SequenceOf <PA_DATA> paData,
            ChecksumType checksumType,
            Ticket additionalTicket,
            AuthorizationData authorizationData)
        {
            if (cRealm == null)
            {
                throw new ArgumentNullException("cRealm");
            }
            if (cName == null)
            {
                throw new ArgumentNullException("cName");
            }
            if (sName == null)
            {
                throw new ArgumentNullException("sName");
            }
            if (realm == null)
            {
                throw new ArgumentNullException("realm");
            }

            KileTgsRequest request = new KileTgsRequest(context);

            request.Request.msg_type = new Asn1Integer((int)MsgType.KRB_TGS_REQ);
            request.Request.pvno     = new Asn1Integer(ConstValue.KERBEROSV5);

            #region construct req_body
            request.Request.req_body             = new KDC_REQ_BODY();
            request.Request.req_body.kdc_options = new KDCOptions(KileUtility.ConvertInt2Flags((int)kdcOptions));
            request.Request.req_body.nonce       = nonce;
            request.Request.req_body.till        = new KerberosTime(ConstValue.TGT_TILL_TIME);
            request.Request.req_body.etype       = context.ClientEncryptionTypes;
            request.Request.req_body.realm       = realm;

            if (additionalTicket != null)
            {
                request.Request.req_body.additional_tickets = new Asn1SequenceOf <Ticket>(new Ticket[] { additionalTicket });
            }
            request.Request.req_body.sname = sName;
            request.EncAuthorizationData   = authorizationData;

            if (authorizationData != null)
            {
                Asn1BerEncodingBuffer asnBuffer = new Asn1BerEncodingBuffer();
                authorizationData.BerEncode(asnBuffer, true);

                request.Request.req_body.enc_authorization_data       = new EncryptedData();
                request.Request.req_body.enc_authorization_data.etype = new KerbInt32(0);
                byte[] encAsnEncoded = asnBuffer.Data;
                if (context.TgsSessionKey != null && context.TgsSessionKey.keytype != null &&
                    context.TgsSessionKey.keyvalue != null && context.TgsSessionKey.keyvalue.Value != null)
                {
                    encAsnEncoded = KileUtility.Encrypt((EncryptionType)context.TgsSessionKey.keytype.Value,
                                                        context.TgsSessionKey.keyvalue.ByteArrayValue,
                                                        asnBuffer.Data,
                                                        (int)KeyUsageNumber.TGS_REQ_KDC_REQ_BODY_AuthorizationData);
                    request.Request.req_body.enc_authorization_data.etype =
                        new KerbInt32(context.TgsSessionKey.keytype.Value);
                }

                request.Request.req_body.enc_authorization_data.cipher = new Asn1OctetString(encAsnEncoded);
            }
            #endregion construct req_body

            #region construct PA_DATA
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();
            request.Request.req_body.BerEncode(bodyBuffer);
            PA_DATA tgsPaData = ConstructTgsPaData(cRealm, cName, checksumType, bodyBuffer.Data);

            request.Request.padata = new Asn1SequenceOf <PA_DATA>();
            if (paData == null || paData.Elements == null || paData.Elements.Length == 0)
            {
                request.Request.padata.Elements = new PA_DATA[] { tgsPaData };
            }
            else
            {
                request.Request.padata.Elements = new PA_DATA[paData.Elements.Length + 1];
                Array.Copy(paData.Elements, request.Request.padata.Elements, paData.Elements.Length);
                request.Request.padata.Elements[paData.Elements.Length] = tgsPaData;
            }
            #endregion construct PA_DATA

            return(request);
        }
Exemplo n.º 38
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                AdInsightExampleHelper AdInsightExampleHelper =
                    new AdInsightExampleHelper(this.OutputStatusMessage);
                AdInsightExampleHelper.AdInsightService =
                    new ServiceClient <IAdInsightService>(authorizationData, environment);

                CampaignManagementExampleHelper CampaignManagementExampleHelper =
                    new CampaignManagementExampleHelper(this.OutputStatusMessage);

                BulkServiceManager = new BulkServiceManager(authorizationData, environment);

                var progress = new Progress <BulkOperationProgressInfo>(x =>
                                                                        OutputStatusMessage(String.Format("{0} % Complete",
                                                                                                          x.PercentComplete.ToString(CultureInfo.InvariantCulture))));

                var uploadEntities = new List <BulkEntity>();

                #region Add

                // To get started with dynamic search ads, first you'll need to add a new Campaign
                // with its type set to DynamicSearchAds. When you create the campaign, you'll need to
                // include a DynamicSearchAdsSetting that specifies the target website domain and language.

                var bulkCampaign = new BulkCampaign
                {
                    ClientId = "YourClientIdGoesHere",
                    Campaign = new Campaign
                    {
                        Id           = campaignIdKey,
                        CampaignType = CampaignType.DynamicSearchAds,
                        Settings     = new[] {
                            new DynamicSearchAdsSetting
                            {
                                DomainName = "contoso.com",
                                Language   = "English"
                            }
                        },

                        Name        = "Women's Shoes " + DateTime.UtcNow,
                        Description = "Red shoes line.",

                        // You must choose to set either the shared  budget ID or daily amount.
                        // You can set one or the other, but you may not set both.
                        BudgetId    = null,
                        DailyBudget = 50,
                        BudgetType  = Microsoft.BingAds.V12.CampaignManagement.BudgetLimitType.DailyBudgetStandard,

                        // You can set your campaign bid strategy to Enhanced CPC (EnhancedCpcBiddingScheme)
                        // and then, at any time, set an individual ad group bid strategy to
                        // Manual CPC (ManualCpcBiddingScheme).
                        BiddingScheme = new EnhancedCpcBiddingScheme {
                        },

                        TimeZone = "PacificTimeUSCanadaTijuana",

                        // Used with CustomParameters defined in lower level entities such as ads.
                        TrackingUrlTemplate =
                            "http://tracker.example.com/?season={_season}&promocode={_promocode}&u={lpurl}"
                    },
                };

                uploadEntities.Add(bulkCampaign);

                // Next, create a new AdGroup within the dynamic search ads campaign.

                var bulkAdGroup = new BulkAdGroup
                {
                    CampaignId = campaignIdKey,
                    AdGroup    = new AdGroup
                    {
                        Id        = adGroupIdKey,
                        Name      = "Women's Red Shoe Sale",
                        StartDate = null,
                        EndDate   = new Microsoft.BingAds.V12.CampaignManagement.Date
                        {
                            Month = 12,
                            Day   = 31,
                            Year  = DateTime.UtcNow.Year + 1
                        },
                        Language = "English",
                        Status   = AdGroupStatus.Active,

                        // For ad groups you can use either of the InheritFromParentBiddingScheme or ManualCpcBiddingScheme objects.
                        // If you do not set this element, then InheritFromParentBiddingScheme is used by default.
                        BiddingScheme = new ManualCpcBiddingScheme {
                        },
                    },
                };

                uploadEntities.Add(bulkAdGroup);

                // You can add one or more Webpage criterion to each ad group that helps determine
                // whether or not to serve dynamic search ads.

                var adGroupWebpagePositivePageContent = new BulkAdGroupDynamicSearchAdTarget
                {
                    BiddableAdGroupCriterion = new BiddableAdGroupCriterion
                    {
                        AdGroupId    = adGroupIdKey,
                        CriterionBid = new FixedBid
                        {
                            Amount = 0.50
                        },
                        Criterion = new Webpage
                        {
                            Parameter = new WebpageParameter
                            {
                                Conditions = new[]
                                {
                                    new WebpageCondition
                                    {
                                        Argument = "flowers",
                                        Operand  = WebpageConditionOperand.PageContent,
                                    }
                                },
                                CriterionName = "Ad Group Webpage Positive Page Content Criterion"
                            },
                        },
                        // DestinationUrl and FinalUrls are not supported with Webpage criterion.
                        // The Final URL is dynamically created at the ad level.
                        DestinationUrl = null,
                        FinalUrls      = null,

                        // In this example we are deferring to the campaign level tracking template.
                        TrackingUrlTemplate = null,

                        // Set custom parameters that are specific to this webpage criterion.
                        UrlCustomParameters = new CustomParameters
                        {
                            Parameters = new[] {
                                new CustomParameter()
                                {
                                    Key   = "promoCode",
                                    Value = "PROMO1"
                                },
                                new CustomParameter()
                                {
                                    Key   = "season",
                                    Value = "summer"
                                },
                            }
                        }
                    }
                };
                uploadEntities.Add(adGroupWebpagePositivePageContent);

                // To discover the categories that you can use for Webpage criterion (positive or negative),
                // use the GetDomainCategories operation with the Ad Insight service.

                var getDomainCategoriesResponse = await AdInsightExampleHelper.GetDomainCategoriesAsync(
                    categoryName : null,
                    domainName : DOMAIN_NAME,
                    language : LANGUAGE);

                var categories = getDomainCategoriesResponse.Categories;

                // If any categories are available let's use one as a condition.
                if (categories.Count > 0)
                {
                    var adGroupWebpagePositiveCategory = new BulkAdGroupDynamicSearchAdTarget
                    {
                        BiddableAdGroupCriterion = new BiddableAdGroupCriterion
                        {
                            AdGroupId    = adGroupIdKey,
                            CriterionBid = new FixedBid
                            {
                                Amount = 0.50
                            },
                            Criterion = new Webpage
                            {
                                Parameter = new WebpageParameter
                                {
                                    Conditions = new[]
                                    {
                                        new WebpageCondition
                                        {
                                            Argument = categories[0].CategoryName,
                                            Operand  = WebpageConditionOperand.Category,
                                        }
                                    },
                                    CriterionName = "Ad Group Webpage Positive Category Criterion"
                                },
                            }
                        }
                    };
                    uploadEntities.Add(adGroupWebpagePositiveCategory);
                }

                // If you want to exclude certain portions of your website, you can add negative Webpage
                // criterion at the campaign and ad group level.

                var adGroupWebpageNegativeUrl = new BulkAdGroupNegativeDynamicSearchAdTarget
                {
                    NegativeAdGroupCriterion = new NegativeAdGroupCriterion
                    {
                        AdGroupId = adGroupIdKey,
                        Criterion = new Webpage
                        {
                            Parameter = new WebpageParameter
                            {
                                // You can choose whether you want the criterion argument to match partial URLs,
                                // page content, page title, or categories that Bing thinks applies to your website.
                                Conditions = new[]
                                {
                                    new WebpageCondition
                                    {
                                        Argument = DOMAIN_NAME,
                                        Operand  = WebpageConditionOperand.Url,
                                    }
                                },
                                // If you do not specify any name, then it will be set to a concatenated list of conditions.
                                CriterionName = null
                            }
                        }
                    }
                };
                uploadEntities.Add(adGroupWebpageNegativeUrl);

                // The negative Webpage criterion at the campaign level applies to all ad groups
                // within the campaign; however, if you define ad group level negative Webpage criterion,
                // the campaign criterion is ignored for that ad group.

                var campaignWebpageNegative = new BulkCampaignNegativeDynamicSearchAdTarget
                {
                    NegativeCampaignCriterion = new NegativeCampaignCriterion
                    {
                        CampaignId = campaignIdKey,
                        Criterion  = new Webpage
                        {
                            Parameter = new WebpageParameter
                            {
                                Conditions = new[]
                                {
                                    new WebpageCondition
                                    {
                                        Argument = DOMAIN_NAME + "\\seattle",
                                        Operand  = WebpageConditionOperand.Url,
                                    }
                                },
                                CriterionName = "Campaign Negative Webpage Url Criterion"
                            }
                        }
                    }
                };
                uploadEntities.Add(campaignWebpageNegative);


                // Finally you can add a DynamicSearchAd into the ad group. The ad title and display URL
                // are generated automatically based on the website domain and language that you want to target.

                var bulkDynamicSearchAd = new BulkDynamicSearchAd
                {
                    ClientId        = "here",
                    AdGroupId       = adGroupIdKey,
                    DynamicSearchAd = new DynamicSearchAd
                    {
                        Text  = "Find New Customers & Increase Sales! Start Advertising on Contoso Today.",
                        Path1 = "seattle",
                        Path2 = "shoe sale",

                        // You cannot set FinalUrls. The Final URL will be a dynamically selected landing page.
                        // The final URL is distinct from the path that customers will see and click on in your ad.
                        FinalUrls = null,

                        // In this example we are deferring to the campaign level tracking template.
                        TrackingUrlTemplate = null,

                        // Set custom parameters that are specific to this ad.
                        UrlCustomParameters = new CustomParameters
                        {
                            Parameters = new[] {
                                new CustomParameter()
                                {
                                    Key   = "promoCode",
                                    Value = "PROMO1"
                                },
                                new CustomParameter()
                                {
                                    Key   = "season",
                                    Value = "summer"
                                },
                            }
                        }
                    },
                };

                uploadEntities.Add(bulkDynamicSearchAd);

                // Upload and write the output

                OutputStatusMessage("Adding campaign, ad group, criterions, and ads . . .\n");

                var Reader = await WriteEntitiesAndUploadFileAsync(uploadEntities);

                var downloadEntities = Reader.ReadEntities().ToList();

                var campaignResults = downloadEntities.OfType <BulkCampaign>().ToList();
                OutputBulkCampaigns(campaignResults);

                var adGroupResults = downloadEntities.OfType <BulkAdGroup>().ToList();
                OutputBulkAdGroups(adGroupResults);

                var campaignNegativeDynamicSearchAdTargetResults = downloadEntities.OfType <BulkCampaignNegativeDynamicSearchAdTarget>().ToList();
                OutputBulkCampaignNegativeDynamicSearchAdTargets(campaignNegativeDynamicSearchAdTargetResults);

                var adGroupDynamicSearchAdTargetResults = downloadEntities.OfType <BulkAdGroupDynamicSearchAdTarget>().ToList();
                OutputBulkAdGroupDynamicSearchAdTargets(adGroupDynamicSearchAdTargetResults);

                var adGroupNegativeDynamicSearchAdTargetResults = downloadEntities.OfType <BulkAdGroupNegativeDynamicSearchAdTarget>().ToList();
                OutputBulkAdGroupNegativeDynamicSearchAdTargets(adGroupNegativeDynamicSearchAdTargetResults);

                var dynamicSearchAdResults = downloadEntities.OfType <BulkDynamicSearchAd>().ToList();
                OutputBulkDynamicSearchAds(dynamicSearchAdResults);

                Reader.Dispose();

                #endregion Add

                #region Update

                uploadEntities = new List <BulkEntity>();

                // You can update the bid for BiddableAdGroupCriterion

                var updateBid = new FixedBid
                {
                    Amount = 0.75
                };

                // You can update the Webpage criterion name but cannot update the conditions.
                // To update the conditions you must delete the criterion and add a new criterion.
                // This update attempt will return an error.

                var updateCriterionAttemptFailure = new Webpage
                {
                    Parameter = new WebpageParameter
                    {
                        Conditions = new[]
                        {
                            new WebpageCondition
                            {
                                Argument = "Books",
                                Operand  = WebpageConditionOperand.PageContent,
                            }
                        },
                        CriterionName = "Update Attempt Failure"
                    },
                };

                var updateCriterionAttemptSuccess = new Webpage
                {
                    Parameter = new WebpageParameter
                    {
                        CriterionName = "Update Attempt Success"
                    },
                };

                foreach (var adGroupDynamicSearchAdTargetResult in adGroupDynamicSearchAdTargetResults)
                {
                    var biddableAdGroupCriterion = adGroupDynamicSearchAdTargetResult.BiddableAdGroupCriterion as BiddableAdGroupCriterion;
                    if (biddableAdGroupCriterion != null)
                    {
                        ((BiddableAdGroupCriterion)adGroupDynamicSearchAdTargetResult.BiddableAdGroupCriterion).CriterionBid = updateBid;
                        adGroupDynamicSearchAdTargetResult.BiddableAdGroupCriterion.Criterion = updateCriterionAttemptSuccess;
                        uploadEntities.Add(adGroupDynamicSearchAdTargetResult);
                    }
                }

                foreach (var adGroupNegativeDynamicSearchAdTargetResult in adGroupNegativeDynamicSearchAdTargetResults)
                {
                    var negativeAdGroupCriterion = adGroupNegativeDynamicSearchAdTargetResult.NegativeAdGroupCriterion as NegativeAdGroupCriterion;
                    if (negativeAdGroupCriterion != null)
                    {
                        adGroupNegativeDynamicSearchAdTargetResult.NegativeAdGroupCriterion.Criterion = updateCriterionAttemptFailure;
                        uploadEntities.Add(adGroupNegativeDynamicSearchAdTargetResult);
                    }
                }

                OutputStatusMessage("Updating Ad Group Webpage Criterion . . . \n");

                Reader = await WriteEntitiesAndUploadFileAsync(uploadEntities);

                downloadEntities = Reader.ReadEntities().ToList();

                adGroupDynamicSearchAdTargetResults = downloadEntities.OfType <BulkAdGroupDynamicSearchAdTarget>().ToList();
                OutputBulkAdGroupDynamicSearchAdTargets(adGroupDynamicSearchAdTargetResults);

                adGroupNegativeDynamicSearchAdTargetResults = downloadEntities.OfType <BulkAdGroupNegativeDynamicSearchAdTarget>().ToList();
                OutputBulkAdGroupNegativeDynamicSearchAdTargets(adGroupNegativeDynamicSearchAdTargetResults);

                Reader.Dispose();


                #endregion Update

                #region Get

                var entities = new[] {
                    DownloadEntity.AdGroupDynamicSearchAdTargets,
                    DownloadEntity.AdGroupNegativeDynamicSearchAdTargets
                };

                var downloadParameters = new DownloadParameters
                {
                    CampaignIds = null,
                    DataScope   = DataScope.EntityData | DataScope.EntityPerformanceData,
                    PerformanceStatsDateRange = new PerformanceStatsDateRange {
                        PredefinedTime = ReportTimePeriod.LastFourWeeks
                    },
                    DownloadEntities    = entities,
                    FileType            = FileType,
                    LastSyncTimeInUTC   = null,
                    ResultFileDirectory = FileDirectory,
                    ResultFileName      = DownloadFileName,
                    OverwriteResultFile = true
                };

                // You may optionally cancel the DownloadFileAsync operation after a specified time interval.
                var tokenSource = new CancellationTokenSource();
                tokenSource.CancelAfter(TimeoutInMilliseconds);

                var resultFilePath = await BulkServiceManager.DownloadFileAsync(downloadParameters, progress, tokenSource.Token);

                OutputStatusMessage(String.Format("Download result file: {0}\n", resultFilePath));

                #endregion Get

                #region CleanUp

                // Delete the campaign, ad group, criterion, and ad that were previously added.
                // You should remove this operation if you want to view the added entities in the
                // Bing Ads web application or another tool.

                // You must set the Id field to the corresponding entity identifier, and the Status field to Deleted.

                // When you delete a BulkCampaign, the dependent entities such as BulkAdGroup
                // are deleted without being specified explicitly.

                uploadEntities = new List <BulkEntity>();

                foreach (var campaignResult in campaignResults)
                {
                    campaignResult.Campaign.Status = CampaignStatus.Deleted;
                    uploadEntities.Add(campaignResult);
                }

                OutputStatusMessage("\nDeleting DSA campaign, criterions, and ad . . .\n");

                Reader = await WriteEntitiesAndUploadFileAsync(uploadEntities);

                downloadEntities = Reader.ReadEntities().ToList();
                campaignResults  = downloadEntities.OfType <BulkCampaign>().ToList();
                OutputBulkCampaigns(campaignResults);

                Reader.Dispose();

                #endregion Cleanup
            }
            // Catch Microsoft Account authorization exceptions.
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Bulk service exceptions
            catch (FaultException <Microsoft.BingAds.V12.Bulk.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V12.Bulk.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationInProgressException ex)
            {
                OutputStatusMessage("The result file for the bulk operation is not yet available for download.");
                OutputStatusMessage(ex.Message);
            }
            catch (BulkOperationCouldNotBeCompletedException <DownloadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationCouldNotBeCompletedException <UploadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
            finally
            {
                if (Reader != null)
                {
                    Reader.Dispose();
                }
                if (Writer != null)
                {
                    Writer.Dispose();
                }
            }
        }
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                CampaignManagementExampleHelper = new CampaignManagementExampleHelper(this.OutputStatusMessage);

                BulkServiceManager = new BulkServiceManager(authorizationData);

                var progress = new Progress <BulkOperationProgressInfo>(x =>
                                                                        OutputStatusMessage(string.Format("{0} % Complete",
                                                                                                          x.PercentComplete.ToString(CultureInfo.InvariantCulture))));

                #region Add

                // Prepare the bulk entities that you want to upload. Each bulk entity contains the corresponding campaign management object,
                // and additional elements needed to read from and write to a bulk file.

                var bulkCampaign = new BulkCampaign
                {
                    // ClientId may be used to associate records in the bulk upload file with records in the results file. The value of this field
                    // is not used or stored by the server; it is simply copied from the uploaded record to the corresponding result record.
                    // Note: This bulk file Client Id is not related to an application Client Id for OAuth.
                    ClientId = "YourClientIdGoesHere",
                    Campaign = new Campaign
                    {
                        // When using the Campaign Management service, the Id cannot be set. In the context of a BulkCampaign, the Id is optional
                        // and may be used as a negative reference key during bulk upload. For example the same negative value set for the campaign Id
                        // will be used when associating this new campaign with a new negative keyword in the BulkCampaignNegativeKeyword object below.
                        Id          = campaignIdKey,
                        Name        = "Women's Shoes " + DateTime.UtcNow,
                        Description = "Red shoes line.",

                        // You must choose to set either the shared  budget ID or daily amount.
                        // You can set one or the other, but you may not set both.
                        BudgetId      = null,
                        DailyBudget   = 50,
                        BudgetType    = BudgetLimitType.DailyBudgetStandard,
                        BiddingScheme = new EnhancedCpcBiddingScheme(),

                        TimeZone = "PacificTimeUSCanadaTijuana",
                    }
                };

                var bulkCampaignNegativeKeywords = new BulkCampaignNegativeKeyword[] {
                    new BulkCampaignNegativeKeyword {
                        CampaignId      = campaignIdKey,
                        NegativeKeyword = new NegativeKeyword
                        {
                            MatchType = MatchType.Phrase,
                            Text      = "auto",
                        }
                    },
                    new BulkCampaignNegativeKeyword {
                        CampaignId      = campaignIdKey,
                        NegativeKeyword = new NegativeKeyword
                        {
                            MatchType = MatchType.Exact,
                            Text      = "auto",
                        }
                    },
                    new BulkCampaignNegativeKeyword {
                        CampaignId      = campaignIdKey,
                        NegativeKeyword = new NegativeKeyword
                        {
                            MatchType = MatchType.Phrase,
                            Text      = "car",
                        }
                    },
                    new BulkCampaignNegativeKeyword {
                        CampaignId      = campaignIdKey,
                        NegativeKeyword = new NegativeKeyword
                        {
                            MatchType = MatchType.Exact,
                            Text      = "car",
                        }
                    },
                };

                // Negative keywords can be added and deleted from a shared negative keyword list. The negative keyword list can be shared or associated with multiple campaigns.
                // You can create up to 20 negative keyword lists per account and share or associate them with any campaign in the same account.
                // To create a negative keyword list, upload a BulkNegativeKeywordList (Negative Keyword List record type).
                // For each negative keyword that you want to add to the list, upload a BulkSharedNegativeKeyword (Shared Negative Keyword record type).
                // To associate the negative keyword list with a campaign, also upload a BulkCampaignNegativeKeywordList (Campaign Negative Keyword List Association record type).

                var bulkNegativeKeywordList = new BulkNegativeKeywordList
                {
                    NegativeKeywordList = new NegativeKeywordList
                    {
                        // Since we are adding the list and the negative keywords during the same upload,
                        // we will use a reference key to the negative keyword list identifier.
                        Id   = negativeKeywordListIdKey,
                        Name = "My NKW List",
                    },
                };

                var bulkSharedNegativeKeywords = new BulkSharedNegativeKeyword[] {
                    new BulkSharedNegativeKeyword {
                        NegativeKeyword = new NegativeKeyword
                        {
                            MatchType = MatchType.Phrase,
                            Text      = "mobile",
                        },
                        NegativeKeywordListId = negativeKeywordListIdKey,
                    },
                    new BulkSharedNegativeKeyword {
                        NegativeKeyword = new NegativeKeyword
                        {
                            MatchType = MatchType.Exact,
                            Text      = "mobile",
                        },
                        NegativeKeywordListId = negativeKeywordListIdKey,
                    },
                };

                var bulkCampaignNegativeKeywordList = new BulkCampaignNegativeKeywordList
                {
                    SharedEntityAssociation = new SharedEntityAssociation
                    {
                        EntityId         = campaignIdKey,
                        EntityType       = "Campaign",
                        SharedEntityId   = negativeKeywordListIdKey,
                        SharedEntityType = "NegativeKeywordList",
                    }
                };

                var uploadEntities = new List <BulkEntity>();
                uploadEntities.Add(bulkCampaign);

                foreach (var bulkCampaignNegativeKeyword in bulkCampaignNegativeKeywords)
                {
                    uploadEntities.Add(bulkCampaignNegativeKeyword);
                }

                uploadEntities.Add(bulkNegativeKeywordList);
                foreach (var bulkSharedNegativeKeyword in bulkSharedNegativeKeywords)
                {
                    uploadEntities.Add(bulkSharedNegativeKeyword);
                }
                uploadEntities.Add(bulkCampaignNegativeKeywordList);

                // Upload and write the output

                Reader = await WriteEntitiesAndUploadFileAsync(uploadEntities);

                var downloadEntities = Reader.ReadEntities().ToList();

                var campaignResults = downloadEntities.OfType <BulkCampaign>().ToList();
                OutputBulkCampaigns(campaignResults);

                var campaignNegativeKeywordResults = downloadEntities.OfType <BulkCampaignNegativeKeyword>().ToList();
                OutputBulkCampaignNegativeKeywords(campaignNegativeKeywordResults);

                var negativeKeywordListResults = downloadEntities.OfType <BulkNegativeKeywordList>().ToList();
                OutputBulkNegativeKeywordLists(negativeKeywordListResults);

                var sharedNegativeKeywordListResults = downloadEntities.OfType <BulkSharedNegativeKeyword>().ToList();
                OutputBulkSharedNegativeKeywords(sharedNegativeKeywordListResults);

                var campaignNegativeKeywordListResults = downloadEntities.OfType <BulkCampaignNegativeKeywordList>().ToList();
                OutputBulkCampaignNegativeKeywordLists(campaignNegativeKeywordListResults);

                Reader.Dispose();

                #endregion Add

                #region CleanUp

                //Delete the campaign and negative keywords that were previously added.
                //You should remove this region if you want to view the added entities in the
                //Bing Ads web application or another tool.

                //You must set the Id field to the corresponding entity identifier, and the Status field to Deleted.

                //When you delete a BulkCampaign, the dependent entities such as BulkCampaignNegativeKeyword
                //are deleted without being specified explicitly.
                //When you delete a BulkNegativeKeywordList, the dependent entities such as BulkSharedNegativeKeyword
                //are deleted without being specified explicitly.

                uploadEntities = new List <BulkEntity>();

                foreach (var campaignResult in campaignResults)
                {
                    campaignResult.Campaign.Status = CampaignStatus.Deleted;
                    uploadEntities.Add(campaignResult);
                }

                foreach (var negativeKeywordListResult in negativeKeywordListResults)
                {
                    negativeKeywordListResult.Status = Status.Deleted;
                    uploadEntities.Add(negativeKeywordListResult);
                }

                // Upload and write the output

                OutputStatusMessage("\nDeleting campaign and negative keywords . . .\n");

                Reader = await WriteEntitiesAndUploadFileAsync(uploadEntities);

                downloadEntities = Reader.ReadEntities().ToList();
                OutputBulkCampaigns(downloadEntities.OfType <BulkCampaign>().ToList());
                OutputBulkNegativeKeywordLists(downloadEntities.OfType <BulkNegativeKeywordList>().ToList());
                Reader.Dispose();

                #endregion Cleanup
            }
            // Catch Microsoft Account authorization exceptions.
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Bulk service exceptions
            catch (FaultException <Microsoft.BingAds.V12.Bulk.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V12.Bulk.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationInProgressException ex)
            {
                OutputStatusMessage("The result file for the bulk operation is not yet available for download.");
                OutputStatusMessage(ex.Message);
            }
            catch (BulkOperationCouldNotBeCompletedException <DownloadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationCouldNotBeCompletedException <UploadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
            finally
            {
                if (Reader != null)
                {
                    Reader.Dispose();
                }
                if (Writer != null)
                {
                    Writer.Dispose();
                }
            }
        }
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                // Used to output the Campaign Management objects within Bulk entities.
                CampaignManagementExampleHelper = new CampaignManagementExampleHelper(
                    OutputStatusMessageDefault: this.OutputStatusMessage);

                BulkServiceManager = new BulkServiceManager(
                    authorizationData: authorizationData,
                    apiEnvironment: environment);

                var progress = new Progress <BulkOperationProgressInfo>(x =>
                                                                        OutputStatusMessage(string.Format("{0} % Complete",
                                                                                                          x.PercentComplete.ToString(CultureInfo.InvariantCulture))));

                var tokenSource = new CancellationTokenSource();
                tokenSource.CancelAfter(TimeoutInMilliseconds);

                // In this example we will download all ad groups in the account.

                var downloadParameters = new DownloadParameters
                {
                    DataScope           = DataScope.EntityData,
                    DownloadEntities    = new[] { DownloadEntity.AdGroups },
                    FileType            = FileType,
                    LastSyncTimeInUTC   = null,
                    ResultFileDirectory = FileDirectory,
                    ResultFileName      = DownloadFileName,
                    OverwriteResultFile = true
                };

                OutputStatusMessage("-----\nDownloading all ad groups in the account.");

                var bulkFilePath = await BulkServiceManager.DownloadFileAsync(
                    parameters : downloadParameters,
                    progress : progress,
                    cancellationToken : tokenSource.Token);

                OutputStatusMessage("Download results:");

                Reader = new BulkFileReader(
                    filePath: bulkFilePath,
                    resultFileType: ResultFileType.FullDownload,
                    fileFormat: FileType);

                var bulkAdGroups = Reader.ReadEntities().ToList().OfType <BulkAdGroup>().ToList();
                OutputBulkAdGroups(bulkAdGroups);

                Writer = new BulkFileWriter(FileDirectory + UploadFileName);

                // We will activate ad groups for one month starting from today as an example.

                var nextMonth = DateTime.UtcNow.AddMonths(1);

                // Within the downloaded records, find all ad groups that you want to update.

                foreach (var bulkAdGroup in bulkAdGroups)
                {
                    var adGroup = bulkAdGroup.AdGroup;
                    if (adGroup != null && bulkAdGroup.AdGroup.Status.ToString().CompareTo("Active") != 0)
                    {
                        // For best performance, only upload the properties that you want to update.

                        Writer.WriteEntity(new BulkAdGroup
                        {
                            CampaignId = bulkAdGroup.CampaignId,
                            AdGroup    = new AdGroup
                            {
                                Id      = adGroup.Id,
                                EndDate = new Microsoft.BingAds.V12.CampaignManagement.Date
                                {
                                    Month = nextMonth.Month,
                                    Day   = nextMonth.Day,
                                    Year  = nextMonth.Year
                                },
                                Status = AdGroupStatus.Active,
                            }
                        });
                    }
                }

                Reader.Dispose();
                Writer.Dispose();

                // Upload the local file that we already prepared

                var fileUploadParameters = new FileUploadParameters
                {
                    ResultFileDirectory = FileDirectory,
                    CompressUploadFile  = true,
                    ResultFileName      = ResultFileName,
                    OverwriteResultFile = true,
                    UploadFilePath      = FileDirectory + UploadFileName,
                    ResponseMode        = ResponseMode.ErrorsAndResults
                };

                OutputStatusMessage("-----\nActivating the ad groups...");

                var resultFilePath = await BulkServiceManager.UploadFileAsync(
                    parameters : fileUploadParameters,
                    progress : progress,
                    cancellationToken : tokenSource.Token);

                Reader = new BulkFileReader(
                    filePath: resultFilePath,
                    resultFileType: ResultFileType.Upload,
                    fileFormat: FileType);

                OutputStatusMessage("Upload results:");

                bulkAdGroups = Reader.ReadEntities().ToList().OfType <BulkAdGroup>().ToList();
                OutputBulkAdGroups(bulkAdGroups);

                Reader.Dispose();
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Bulk service exceptions
            catch (FaultException <Microsoft.BingAds.V12.Bulk.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V12.Bulk.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationInProgressException ex)
            {
                OutputStatusMessage("The result file for the bulk operation is not yet available for download.");
                OutputStatusMessage(ex.Message);
            }
            catch (BulkOperationCouldNotBeCompletedException <DownloadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationCouldNotBeCompletedException <UploadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                BulkService = new BulkServiceManager(authorizationData);
                BulkService.StatusPollIntervalInMilliseconds = 5000;

                var progress = new Progress <BulkOperationProgressInfo>(x =>
                                                                        OutputStatusMessage(String.Format("{0} % Complete",
                                                                                                          x.PercentComplete.ToString(CultureInfo.InvariantCulture))));

                // In this example we will download all ads and keywords in the account.
                var entities = BulkDownloadEntity.Ads |
                               BulkDownloadEntity.Keywords;

                // DownloadParameters is used for Option A below.
                var downloadParameters = new DownloadParameters
                {
                    CampaignIds = null,
                    DataScope   = DataScope.EntityData | DataScope.EntityPerformanceData,
                    PerformanceStatsDateRange = new PerformanceStatsDateRange {
                        PredefinedTime = ReportTimePeriod.LastFourWeeks
                    },
                    Entities            = entities,
                    FileType            = FileType,
                    LastSyncTimeInUTC   = null,
                    ResultFileDirectory = FileDirectory,
                    ResultFileName      = DownloadFileName,
                    OverwriteResultFile = true
                };

                // SubmitDownloadParameters is used for Option B and Option C below.
                var submitDownloadParameters = new SubmitDownloadParameters
                {
                    CampaignIds = null,
                    DataScope   = DataScope.EntityData | DataScope.EntityPerformanceData,
                    PerformanceStatsDateRange = new PerformanceStatsDateRange {
                        PredefinedTime = ReportTimePeriod.LastFourWeeks
                    },
                    Entities          = entities,
                    FileType          = FileType,
                    LastSyncTimeInUTC = null
                };

                // Option A - Background Completion with BulkServiceManager
                // You can submit a download or upload request and the BulkServiceManager will automatically
                // return results. The BulkServiceManager abstracts the details of checking for result file
                // completion, and you don't have to write any code for results polling.

                OutputStatusMessage("Awaiting Background Completion . . .");
                await BackgroundCompletionAsync(downloadParameters, progress);

                // Option B - Submit and Download with BulkServiceManager
                // Submit the download request and then use the BulkDownloadOperation result to
                // track status until the download is complete e.g. either using
                // TrackAsync or GetStatusAsync.

                //OutputStatusMessage("Awaiting Submit and Download . . .");
                //await SubmitAndDownloadAsync(submitDownloadParameters);

                // Option C - Download Results with BulkServiceManager
                // If for any reason you have to resume from a previous application state,
                // you can use an existing download request identifier and use it
                // to download the result file.

                // For example you might have previously retrieved a request ID using SubmitDownloadAsync.
                //var bulkDownloadOperation = await BulkService.SubmitDownloadAsync(submitDownloadParameters);
                //var requestId = bulkDownloadOperation.RequestId;

                // Given the request ID above, you can resume the workflow and download the bulk file.
                // The download request identifier is valid for two days.
                // If you do not download the bulk file within two days, you must request it again.
                //OutputStatusMessage("Awaiting Download Results . . .");
                //await DownloadResultsAsync(requestId, authorizationData);
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(String.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Bulk service exceptions
            catch (FaultException <Microsoft.BingAds.V10.Bulk.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(String.Join("; ", ex.Detail.Errors.Select(error => String.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V10.Bulk.ApiFaultDetail> ex)
            {
                OutputStatusMessage(String.Join("; ", ex.Detail.OperationErrors.Select(error => String.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(String.Join("; ", ex.Detail.BatchErrors.Select(error => String.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationInProgressException ex)
            {
                OutputStatusMessage("The result file for the bulk operation is not yet available for download.");
                OutputStatusMessage(ex.Message);
            }
            catch (BulkOperationCouldNotBeCompletedException <DownloadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationCouldNotBeCompletedException <UploadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
Exemplo n.º 42
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper(
                    OutputStatusMessageDefault: this.OutputStatusMessage);
                CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient <ICampaignManagementService>(
                    authorizationData: authorizationData,
                    environment: environment);

                // Add an image to your media library.
                // The image asset is needed later to create the responsive ad.

                var landscapeImageMedia = GetImageMedia(
                    "Image191x100",
                    MediaFilePath + ResponsiveAdMediaFileName,
                    System.Drawing.Imaging.ImageFormat.Png);

                var media = new Media[]
                {
                    landscapeImageMedia,
                };

                OutputStatusMessage("-----\nAddMedia:");
                AddMediaResponse addMediaResponse = await CampaignManagementExampleHelper.AddMediaAsync(
                    accountId : authorizationData.AccountId,
                    media : media);

                long[] mediaIds = addMediaResponse.MediaIds.ToArray();
                OutputStatusMessage("MediaIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(mediaIds);

                // Create an Audience campaign with one ad group and a responsive ad.

                var campaigns = new[] {
                    new Campaign
                    {
                        BudgetType = BudgetLimitType.DailyBudgetStandard,
                        // CampaignType must be set for Audience campaigns
                        CampaignType = CampaignType.Audience,
                        DailyBudget  = 50,
                        // Languages must be set for Audience campaigns
                        Languages = new string[] { "All" },
                        Name      = "Women's Shoes " + DateTime.UtcNow,
                        TimeZone  = "PacificTimeUSCanadaTijuana",
                    },
                };

                OutputStatusMessage("-----\nAddCampaigns:");
                AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync(
                    accountId : authorizationData.AccountId,
                    campaigns : campaigns);

                long?[]      campaignIds    = addCampaignsResponse.CampaignIds.ToArray();
                BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray();
                OutputStatusMessage("CampaignIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors);

                // Add an ad group within the campaign.

                var adGroups = new[] {
                    new AdGroup
                    {
                        Name      = "Women's Red Shoe Sale",
                        StartDate = null,
                        EndDate   = new Date {
                            Month = 12,
                            Day   = 31,
                            Year  = DateTime.UtcNow.Year + 1
                        },
                        CpcBid = new Bid {
                            Amount = 0.09
                        },
                        // Network cannot be set for ad groups in Audience campaigns
                        Network = null,
                    }
                };

                OutputStatusMessage("-----\nAddAdGroups:");
                AddAdGroupsResponse addAdGroupsResponse = await CampaignManagementExampleHelper.AddAdGroupsAsync(
                    campaignId : (long)campaignIds[0],
                    adGroups : adGroups,
                    returnInheritedBidStrategyTypes : false);

                long?[]      adGroupIds    = addAdGroupsResponse.AdGroupIds.ToArray();
                BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray();
                OutputStatusMessage("AdGroupIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(adGroupIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(adGroupErrors);

                // Add a responsive ad within the ad group.

                var ads = new Ad[] {
                    new ResponsiveAd
                    {
                        BusinessName = "Contoso",
                        CallToAction = CallToAction.AddToCart,
                        FinalUrls    = new[] {
                            "https://www.contoso.com/womenshoesale"
                        },
                        Headline = "Fast & Easy Setup",
                        Images   = new []
                        {
                            // You are only required to provide a landscape image asset.
                            // Optionally you can include additional asset links, i.e., one image asset for each supported sub type.
                            // For any image asset sub types that you do not explicitly set,
                            // the service will automatically create image asset links by cropping the LandscapeImageMedia.
                            new AssetLink
                            {
                                Asset = new ImageAsset
                                {
                                    CropHeight = null,
                                    CropWidth  = null,
                                    CropX      = null,
                                    CropY      = null,
                                    Id         = mediaIds[0],
                                    Name       = "My LandscapeImageMedia",
                                    SubType    = "LandscapeImageMedia",
                                },
                            },
                        },
                        LongHeadlineString = "Find New Customers & Increase Sales!",
                        Text = "Find New Customers & Increase Sales! Start Advertising on Contoso Today.",
                    },
                };

                OutputStatusMessage("-----\nAddAds:");
                AddAdsResponse addAdsResponse = await CampaignManagementExampleHelper.AddAdsAsync(
                    adGroupId : (long)adGroupIds[0],
                    ads : ads);

                long?[]      adIds    = addAdsResponse.AdIds.ToArray();
                BatchError[] adErrors = addAdsResponse.PartialErrors.ToArray();
                OutputStatusMessage("AdIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(adIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(adErrors);

                // Delete the account's media.

                OutputStatusMessage("-----\nDeleteMedia:");
                await CampaignManagementExampleHelper.DeleteMediaAsync(
                    accountId : authorizationData.AccountId,
                    mediaIds : mediaIds);

                foreach (var id in mediaIds)
                {
                    OutputStatusMessage(string.Format("Deleted Media Id {0}", id));
                }

                // Delete the campaign and everything it contains e.g., ad groups and ads.

                OutputStatusMessage("-----\nDeleteCampaigns:");
                await CampaignManagementExampleHelper.DeleteCampaignsAsync(
                    accountId : authorizationData.AccountId,
                    campaignIds : new[] { (long)campaignIds[0] });

                OutputStatusMessage(string.Format("Deleted Campaign Id {0}", campaignIds[0]));
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.V13.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V13.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V13.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
Exemplo n.º 43
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                BulkService = new BulkServiceManager(authorizationData);

                var progress = new Progress <BulkOperationProgressInfo>(x =>
                                                                        OutputStatusMessage(String.Format("{0} % Complete",
                                                                                                          x.PercentComplete.ToString(CultureInfo.InvariantCulture))));

                #region Add

                const int targetIdKey   = -1;
                const int campaignIdKey = -123;

                // Prepare the bulk entities that you want to upload. Each bulk entity contains the corresponding campaign management object,
                // and additional elements needed to read from and write to a bulk file.

                var bulkCampaign = new BulkCampaign
                {
                    // ClientId may be used to associate records in the bulk upload file with records in the results file. The value of this field
                    // is not used or stored by the server; it is simply copied from the uploaded record to the corresponding result record.
                    // Note: This bulk file Client Id is not related to an application Client Id for OAuth.
                    ClientId = "YourClientIdGoesHere",
                    Campaign = new Campaign
                    {
                        // When using the Campaign Management service, the Id cannot be set. In the context of a BulkCampaign, the Id is optional
                        // and may be used as a negative reference key during bulk upload. For example the same negative value set for the campaign Id
                        // will be used when associating this new campaign with a new call ad extension in the BulkCampaignCallAdExtension object below.
                        Id             = campaignIdKey,
                        Name           = "Women's Shoes " + DateTime.UtcNow,
                        Description    = "Red shoes line.",
                        BudgetType     = BudgetLimitType.MonthlyBudgetSpendUntilDepleted,
                        MonthlyBudget  = 1000.00,
                        TimeZone       = "PacificTimeUSCanadaTijuana",
                        DaylightSaving = true
                    }
                };

                // Prepare targets for upload

                var bulkCampaignDayTimeTarget = new BulkCampaignDayTimeTarget
                {
                    CampaignId    = campaignIdKey,
                    TargetId      = targetIdKey,
                    DayTimeTarget = new DayTimeTarget
                    {
                        Bids = new List <DayTimeTargetBid>
                        {
                            new DayTimeTargetBid
                            {
                                BidAdjustment = 10,
                                Day           = Day.Friday,
                                FromHour      = 11,
                                FromMinute    = Minute.Zero,
                                ToHour        = 13,
                                ToMinute      = Minute.Fifteen
                            },
                            new DayTimeTargetBid
                            {
                                BidAdjustment = 20,
                                Day           = Day.Saturday,
                                FromHour      = 11,
                                FromMinute    = Minute.Zero,
                                ToHour        = 13,
                                ToMinute      = Minute.Fifteen
                            }
                        }
                    }
                };

                var bulkCampaignLocationTarget = new BulkCampaignLocationTarget
                {
                    CampaignId = campaignIdKey,
                    TargetId   = targetIdKey,

                    IntentOption = IntentOption.PeopleIn,
                    CityTarget   = new CityTarget
                    {
                        Bids = new List <CityTargetBid>
                        {
                            new CityTargetBid
                            {
                                BidAdjustment = 15,
                                City          = "Toronto, Toronto ON CA",
                                IsExcluded    = false
                            }
                        }
                    },
                    CountryTarget = new CountryTarget
                    {
                        Bids = new List <CountryTargetBid>
                        {
                            new CountryTargetBid
                            {
                                BidAdjustment    = 15,
                                CountryAndRegion = "CA",
                                IsExcluded       = false
                            }
                        }
                    },
                    MetroAreaTarget = new MetroAreaTarget
                    {
                        Bids = new List <MetroAreaTargetBid>
                        {
                            new MetroAreaTargetBid
                            {
                                BidAdjustment = 15,
                                MetroArea     = "Seattle-Tacoma, WA, WA US",
                                IsExcluded    = false
                            }
                        }
                    },
                    StateTarget = new StateTarget
                    {
                        Bids = new List <StateTargetBid>
                        {
                            new StateTargetBid
                            {
                                BidAdjustment = 15,
                                State         = "US-WA",
                                IsExcluded    = false
                            }
                        }
                    },
                    PostalCodeTarget = new PostalCodeTarget
                    {
                        Bids = new List <PostalCodeTargetBid>
                        {
                            new PostalCodeTargetBid
                            {
                                // Bid adjustments are not allowed for location exclusions.
                                // If IsExcluded is true, this element will be ignored.
                                BidAdjustment = 10,
                                PostalCode    = "98052, WA US",
                                IsExcluded    = false
                            }
                        }
                    }
                };

                var bulkCampaignRadiusTarget = new BulkCampaignRadiusTarget
                {
                    CampaignId = campaignIdKey,
                    TargetId   = targetIdKey,

                    RadiusTarget = new RadiusTarget2
                    {
                        Bids = new List <RadiusTargetBid2>
                        {
                            new RadiusTargetBid2
                            {
                                BidAdjustment    = 50,
                                LatitudeDegrees  = 47.755367,
                                LongitudeDegrees = -122.091827,
                                Radius           = 11,
                                RadiusUnit       = DistanceUnit.Kilometers
                            }
                        }
                    }
                };


                // Write the entities created above, to the specified file.
                // Dependent entities such as BulkCampaignLocationTarget must be written after any dependencies,
                // for example a BulkCampaign.

                Writer = new BulkFileWriter(FileDirectory + UploadFileName);

                Writer.WriteEntity(bulkCampaign);

                Writer.WriteEntity(bulkCampaignDayTimeTarget);
                Writer.WriteEntity(bulkCampaignLocationTarget);
                Writer.WriteEntity(bulkCampaignRadiusTarget);

                Writer.Dispose();

                var fileUploadParameters = new FileUploadParameters
                {
                    ResultFileDirectory = FileDirectory,
                    ResultFileName      = ResultFileName,
                    OverwriteResultFile = true,
                    UploadFilePath      = FileDirectory + UploadFileName,
                    ResponseMode        = ResponseMode.ErrorsAndResults
                };

                // UploadFileAsync will upload the file you finished writing and will download the results file

                OutputStatusMessage("Starting UploadFileAsync . . .\n");
                var bulkFilePath =
                    await BulkService.UploadFileAsync(fileUploadParameters, progress, CancellationToken.None);

                Reader = new BulkFileReader(bulkFilePath, ResultFileType.Upload, FileType);
                OutputStatusMessage("Upload Results Bulk File Path" + Reader.BulkFilePath + "\n");
                OutputStatusMessage("Added Entities\n");

                // Write the upload output

                var bulkEntities = Reader.ReadEntities().ToList();

                var campaignResults = bulkEntities.OfType <BulkCampaign>().ToList();
                OutputBulkCampaigns(campaignResults);

                var campaignDayTimeTargetResults = bulkEntities.OfType <BulkCampaignDayTimeTarget>().ToList();
                OutputBulkCampaignDayTimeTargets(campaignDayTimeTargetResults);

                var campaignLocationTargetResults = bulkEntities.OfType <BulkCampaignLocationTarget>().ToList();
                OutputBulkCampaignLocationTargets(campaignLocationTargetResults);

                var campaignRadiusTargetResults = bulkEntities.OfType <BulkCampaignRadiusTarget>().ToList();
                OutputBulkCampaignRadiusTargets(campaignRadiusTargetResults);

                Reader.Dispose();

                #endregion Add

                #region Update

                // Update the day and time target.
                // Do not create a BulkAdGroupDayTimeTarget for update, unless you want to replace all existing DayTime target bids
                // with the specified day and time target set for the current bulk upload.
                // Instead you should upload one or more bids as a list of BulkCampaignDayTimeTargetBid.

                var bulkCampaignDayTimeTargetBids = new List <BulkCampaignDayTimeTargetBid>
                {
                    new BulkCampaignDayTimeTargetBid
                    {
                        CampaignId       = campaignDayTimeTargetResults[0].CampaignId,
                        TargetId         = targetIdKey,
                        DayTimeTargetBid = new DayTimeTargetBid
                        {
                            BidAdjustment = 15,
                            Day           = Day.Friday,
                            FromHour      = 11,
                            FromMinute    = Minute.Zero,
                            ToHour        = 13,
                            ToMinute      = Minute.Fifteen
                        }
                    }
                };

                // Write the updated target to the file

                Writer = new BulkFileWriter(FileDirectory + UploadFileName);

                foreach (var bulkCampaignDayTimeTargetBid in bulkCampaignDayTimeTargetBids)
                {
                    Writer.WriteEntity(bulkCampaignDayTimeTargetBid);
                }

                Writer.Dispose();

                fileUploadParameters = new FileUploadParameters
                {
                    ResultFileDirectory = FileDirectory,
                    ResultFileName      = ResultFileName,
                    OverwriteResultFile = true,
                    UploadFilePath      = FileDirectory + UploadFileName,
                    ResponseMode        = ResponseMode.ErrorsAndResults
                };

                // UploadFileAsync will upload the file you finished writing and will download the results file

                OutputStatusMessage("Starting UploadFileAsync . . .\n");
                bulkFilePath = await BulkService.UploadFileAsync(fileUploadParameters, progress, CancellationToken.None);

                Reader = new BulkFileReader(bulkFilePath, ResultFileType.Upload, FileType);
                OutputStatusMessage("Upload Results Bulk File Path: " + Reader.BulkFilePath + "\n");
                OutputStatusMessage("Updated Entities\n");


                // Write any upload errors

                var campaignDayTimeTargetBidResults =
                    Reader.ReadEntities().OfType <BulkCampaignDayTimeTargetBid>().ToList();
                OutputBulkCampaignDayTimeTargetBids(campaignDayTimeTargetBidResults);

                Reader.Dispose();

                #endregion Update

                #region Delete

                // Prepare the bulk entities that you want to delete. You must set the Id field to the corresponding
                // entity identifier, and the Status field to Deleted.

                var campaignId = campaignResults[0].Campaign.Id;
                bulkCampaign = new BulkCampaign
                {
                    Campaign = new Campaign
                    {
                        Id     = campaignId,
                        Status = CampaignStatus.Deleted
                    }
                };

                var targetId = campaignDayTimeTargetResults[0].TargetId;

                bulkCampaignDayTimeTarget = new BulkCampaignDayTimeTarget
                {
                    Status     = Status.Deleted,
                    CampaignId = campaignId,
                    TargetId   = targetId
                };

                bulkCampaignLocationTarget = new BulkCampaignLocationTarget
                {
                    Status     = Status.Deleted,
                    CampaignId = campaignId,
                    TargetId   = targetId
                };

                bulkCampaignRadiusTarget = new BulkCampaignRadiusTarget
                {
                    Status     = Status.Deleted,
                    CampaignId = campaignId,
                    TargetId   = targetId
                };


                // Write the entities that you want deleted, to the specified file.

                Writer = new BulkFileWriter(FileDirectory + UploadFileName);

                Writer.WriteEntity(bulkCampaign);

                Writer.WriteEntity(bulkCampaignDayTimeTarget);
                Writer.WriteEntity(bulkCampaignLocationTarget);
                Writer.WriteEntity(bulkCampaignRadiusTarget);

                Writer.Dispose();

                fileUploadParameters = new FileUploadParameters
                {
                    ResultFileDirectory = FileDirectory,
                    ResultFileName      = ResultFileName,
                    OverwriteResultFile = true,
                    UploadFilePath      = FileDirectory + UploadFileName,
                    ResponseMode        = ResponseMode.ErrorsAndResults
                };

                // UploadFileAsync will upload the file you finished writing and will download the results file

                OutputStatusMessage("Starting UploadFileAsync . . .\n");
                bulkFilePath = await BulkService.UploadFileAsync(fileUploadParameters, progress, CancellationToken.None);

                Reader = new BulkFileReader(bulkFilePath, ResultFileType.Upload, FileType);
                OutputStatusMessage("Upload Results Bulk File Path" + Reader.BulkFilePath + "\n");
                OutputStatusMessage("Deleted Entities\n");

                // Write the upload output

                bulkEntities = Reader.ReadEntities().ToList();

                campaignResults = bulkEntities.OfType <BulkCampaign>().ToList();
                OutputBulkCampaigns(campaignResults);

                campaignDayTimeTargetResults = bulkEntities.OfType <BulkCampaignDayTimeTarget>().ToList();
                OutputBulkCampaignDayTimeTargets(campaignDayTimeTargetResults);

                campaignLocationTargetResults = bulkEntities.OfType <BulkCampaignLocationTarget>().ToList();
                OutputBulkCampaignLocationTargets(campaignLocationTargetResults);

                campaignRadiusTargetResults = bulkEntities.OfType <BulkCampaignRadiusTarget>().ToList();
                OutputBulkCampaignRadiusTargets(campaignRadiusTargetResults);

                Reader.Dispose();

                #endregion Delete
            }
            // Catch Microsoft Account authorization exceptions.
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Bulk service exceptions
            catch (FaultException <Microsoft.BingAds.Bulk.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.Bulk.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationInProgressException ex)
            {
                OutputStatusMessage("The result file for the bulk operation is not yet available for download.");
                OutputStatusMessage(ex.Message);
            }
            catch (BulkOperationCouldNotBeCompletedException <DownloadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationCouldNotBeCompletedException <UploadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
            finally
            {
                if (Reader != null)
                {
                    Reader.Dispose();
                }
                if (Writer != null)
                {
                    Writer.Dispose();
                }
            }
        }
Exemplo n.º 44
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                Service = new ServiceClient <ICampaignManagementService>(authorizationData);

                // Specify a campaign.
                var campaign = new Campaign
                {
                    Name           = "Women's Shoes" + DateTime.UtcNow,
                    Description    = "Red shoes line.",
                    BudgetType     = BudgetLimitType.MonthlyBudgetSpendUntilDepleted,
                    MonthlyBudget  = 1000.00,
                    TimeZone       = "PacificTimeUSCanadaTijuana",
                    DaylightSaving = true
                };

                // Specify an ad group.
                var adGroup = new AdGroup
                {
                    Name           = "Women's Red Shoe Sale",
                    AdDistribution = AdDistribution.Search,
                    BiddingModel   = BiddingModel.Keyword,
                    PricingModel   = PricingModel.Cpc,
                    StartDate      = null,
                    EndDate        = new Date {
                        Month = 12, Day = 31, Year = 2015
                    },
                    ExactMatchBid = new Bid {
                        Amount = 0.09
                    },
                    PhraseMatchBid = new Bid {
                        Amount = 0.07
                    },
                    Language = "English"
                };

                // Add the campaign and ad group
                var campaignIds = (long[]) await AddCampaignsAsync(authorizationData.AccountId, new[] { campaign });

                var adGroupIds = (long[]) await AddAdGroupsAsync(campaignIds[0], new[] { adGroup });

                // Print the new assigned campaign and ad group identifiers
                PrintCampaignIdentifiers(campaignIds);
                PrintAdGroupIdentifiers(adGroupIds);

                // Bing Ads API Version 9 supports both Target and Target2 objects. You should use Target2.
                // This example compares Target and Target2, and demonstrates the impact of updating the
                // DayTimeTarget, IntentOption, and RadiusTarget2 nested in a Target2 object.

                var campaignTarget = new Target
                {
                    Name = "My Campaign Target",
                    Day  = new DayTarget
                    {
                        Bids = new[]
                        {
                            new DayTargetBid
                            {
                                BidAdjustment = 10,
                                Day           = Day.Friday
                            }
                        }
                    },
                    Hour = new HourTarget
                    {
                        Bids = new[]
                        {
                            new HourTargetBid
                            {
                                BidAdjustment = 10,
                                Hour          = HourRange.ElevenAMToTwoPM
                            }
                        }
                    },
                    Location = new LocationTarget
                    {
                        HasPhysicalIntent = true,
                        MetroAreaTarget   = new MetroAreaTarget
                        {
                            Bids = new List <MetroAreaTargetBid>
                            {
                                new MetroAreaTargetBid
                                {
                                    BidAdjustment = 15,
                                    MetroArea     = "Seattle-Tacoma, WA, WA US",
                                    IsExcluded    = false
                                }
                            }
                        },
                        RadiusTarget = new RadiusTarget
                        {
                            Bids = new[]
                            {
                                new RadiusTargetBid
                                {
                                    BidAdjustment    = 50,
                                    LatitudeDegrees  = 47.755367,
                                    LongitudeDegrees = -122.091827,
                                    Radius           = 5
                                }
                            }
                        }
                    }
                };

                var adGroupTarget = new Target
                {
                    Name = "My Ad Group Target",
                    Hour = new HourTarget
                    {
                        Bids = new[]
                        {
                            new HourTargetBid
                            {
                                BidAdjustment = 10,
                                Hour          = HourRange.SixPMToElevenPM
                            }
                        }
                    }
                };

                // Each customer has a target library that can be used to set up targeting for any campaign
                // or ad group within the specified customer.

                // Add a target to the library and associate it with the campaign.
                var campaignTargetId = (await AddTargetsToLibraryAsync(new[] { campaignTarget }))[0];
                OutputStatusMessage(String.Format("Added Target Id: {0}\n", campaignTargetId));
                SetTargetToCampaignAsync(campaignIds[0], campaignTargetId);
                OutputStatusMessage(String.Format("Associated CampaignId {0} with TargetId {1}.\n", campaignIds[0], campaignTargetId));

                // Get and print the Target with the legacy GetTargetsByIds operation
                OutputStatusMessage("Get Campaign Target: \n");
                var targets = await GetTargetsByIdsAsync(new[] { campaignTargetId });

                PrintTarget(targets[0]);

                // Get and print the Target2 with the new GetTargetsByIds2 operation
                OutputStatusMessage("Get Campaign Target2: \n");
                var targets2 = await GetTargetsByIds2Async(new[] { campaignTargetId });

                PrintTarget2(targets2[0]);

                // Add a target to the library and associate it with the ad group.
                var adGroupTargetId = (await AddTargetsToLibraryAsync(new[] { adGroupTarget }))[0];
                OutputStatusMessage(String.Format("Added Target Id: {0}\n", adGroupTargetId));
                SetTargetToAdGroupAsync(adGroupIds[0], adGroupTargetId);
                OutputStatusMessage(String.Format("Associated AdGroupId {0} with TargetId {1}.\n", adGroupIds[0], adGroupTargetId));

                // Get and print the Target with the legacy GetTargetsByIds operation
                OutputStatusMessage("Get AdGroup Target: \n");
                targets = await GetTargetsByIdsAsync(new[] { adGroupTargetId });

                PrintTarget(targets[0]);

                // Get and print the Target2 with the new GetTargetsByIds2 operation
                OutputStatusMessage("Get AdGroup Target2: \n");
                targets2 = await GetTargetsByIds2Async(new[] { adGroupTargetId });

                PrintTarget2(targets2[0]);

                // Update the ad group's target as a Target2 object with additional target types.
                // Existing target types such as DayTime, Location, and Radius must be specified
                // or they will not be included in the updated target.

                var target2 = new Target2
                {
                    Id   = adGroupTargetId,
                    Name = "My Target2",
                    Age  = new AgeTarget
                    {
                        Bids = new[]
                        {
                            new AgeTargetBid
                            {
                                BidAdjustment = 10,
                                Age           = AgeRange.EighteenToTwentyFive
                            }
                        }
                    },
                    DayTime = new DayTimeTarget
                    {
                        Bids = new[]
                        {
                            new DayTimeTargetBid
                            {
                                BidAdjustment = 10,
                                Day           = Day.Friday,
                                FromHour      = 1,
                                ToHour        = 12,
                                FromMinute    = Minute.Zero,
                                ToMinute      = Minute.FortyFive
                            }
                        }
                    },
                    DeviceOS = new DeviceOSTarget
                    {
                        Bids = new[]
                        {
                            new DeviceOSTargetBid
                            {
                                BidAdjustment = 20,
                                DeviceName    = "Tablets",
                            }
                        },
                    },
                    Gender = new GenderTarget
                    {
                        Bids = new[]
                        {
                            new GenderTargetBid
                            {
                                BidAdjustment = 10,
                                Gender        = GenderType.Female
                            }
                        }
                    },
                    Location = new LocationTarget2
                    {
                        IntentOption  = IntentOption.PeopleSearchingForOrViewingPages,
                        CountryTarget = new CountryTarget
                        {
                            Bids = new[]
                            {
                                new CountryTargetBid
                                {
                                    BidAdjustment    = 10,
                                    CountryAndRegion = "US",
                                    IsExcluded       = false
                                }
                            }
                        },
                        MetroAreaTarget = new MetroAreaTarget
                        {
                            Bids = new List <MetroAreaTargetBid>
                            {
                                new MetroAreaTargetBid
                                {
                                    BidAdjustment = 15,
                                    MetroArea     = "Seattle-Tacoma, WA, WA US",
                                    IsExcluded    = false
                                }
                            }
                        },
                        PostalCodeTarget = new PostalCodeTarget
                        {
                            Bids = new[]
                            {
                                new PostalCodeTargetBid
                                {
                                    // Bid adjustments are not allowed for location exclusions.
                                    // If IsExcluded is true, this element will be ignored.
                                    BidAdjustment = 10,
                                    PostalCode    = "98052, WA US",
                                    IsExcluded    = true
                                }
                            }
                        },
                        RadiusTarget = new RadiusTarget2
                        {
                            Bids = new[]
                            {
                                new RadiusTargetBid2
                                {
                                    BidAdjustment    = 50,
                                    LatitudeDegrees  = 47.755367,
                                    LongitudeDegrees = -122.091827,
                                    Radius           = 11,
                                    RadiusUnit       = DistanceUnit.Kilometers
                                }
                            }
                        }
                    }
                };

                // Update the same identified target as a Target2 object.
                // Going forward when getting the specified target Id, the Day and Hour elements of the legacy
                // Target object will be nil, since the target is being updated with a DayTime target.
                UpdateTargetsInLibrary2Async(new[] { target2 });
                OutputStatusMessage("Updated the ad group level target as a Target2 object.\n");

                // Get and print the Target with the legacy GetTargetsByIds operation
                OutputStatusMessage("Get Campaign Target: \n");
                targets = await GetTargetsByIdsAsync(new[] { campaignTargetId });

                PrintTarget(targets[0]);

                // Get and print the Target2 with the new GetTargetsByIds2 operation
                OutputStatusMessage("Get Campaign Target2: \n");
                targets2 = await GetTargetsByIds2Async(new[] { campaignTargetId });

                PrintTarget2(targets2[0]);

                // Get and print the Target with the legacy GetTargetsByIds operation
                OutputStatusMessage("Get AdGroup Target: \n");
                targets = await GetTargetsByIdsAsync(new[] { adGroupTargetId });

                PrintTarget(targets[0]);

                // Get and print the Target2 with the new GetTargetsByIds2 operation
                OutputStatusMessage("Get AdGroup Target2: \n");
                targets2 = await GetTargetsByIds2Async(new[] { adGroupTargetId });

                PrintTarget2(targets2[0]);

                // Get all new and existing targets in the customer library, whether or not they are
                // associated with campaigns or ad groups.

                var allTargetsInfo = await GetTargetsInfoFromLibraryAsync();

                OutputStatusMessage("All target identifiers and names from the customer library: \n");
                PrintTargetsInfo(allTargetsInfo);

                // Delete the campaign, ad group, and targets that were previously added.
                // DeleteCampaigns would remove the campaign and ad group, as well as the association
                // between ad groups and campaigns. To explicitly delete the association between an entity
                // and the target, use DeleteTargetFromCampaign and DeleteTargetFromAdGroup respectively.

                DeleteTargetFromCampaignAsync(campaignIds[0]);
                DeleteTargetFromAdGroupAsync(adGroupIds[0]);

                DeleteCampaignsAsync(authorizationData.AccountId, new[] { campaignIds[0] });
                OutputStatusMessage(String.Format("Deleted CampaignId {0}\n", campaignIds[0]));

                // DeleteCampaigns deletes the association between the campaign and target, but does not
                // delete the target from the customer library.
                // Call the DeleteTargetsFromLibrary operation for each target that you want to delete.
                // You must specify an array with exactly one item.

                DeleteTargetsFromLibraryAsync(new[] { campaignTargetId });
                OutputStatusMessage(String.Format("Deleted TargetId {0}\n", campaignTargetId));

                DeleteTargetsFromLibraryAsync(new[] { adGroupTargetId });
                OutputStatusMessage(String.Format("Deleted TargetId {0}\n", adGroupTargetId));
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
Exemplo n.º 45
0
        private Authenticator CreateAuthenticator(PrincipalName cname, Realm realm, EncryptionKey subkey = null, AuthorizationData data = null)
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create authenticator");
            Random r      = new Random();
            int    seqNum = r.Next();

            Authenticator plaintextAuthenticator = new Authenticator
            {
                authenticator_vno  = new Asn1Integer(KerberosConstValue.KERBEROSV5),
                crealm             = realm,
                cusec              = new Microseconds(0),
                ctime              = KerberosUtility.CurrentKerberosTime,
                seq_number         = new KerbUInt32(seqNum),
                cname              = cname,
                subkey             = subkey,
                authorization_data = data
            };

            AuthCheckSum checksum = new AuthCheckSum {
                Lgth = KerberosConstValue.AUTHENTICATOR_CHECKSUM_LENGTH
            };

            checksum.Bnd   = new byte[checksum.Lgth];
            checksum.Flags = (int)(ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG);
            byte[] checkData = ArrayUtility.ConcatenateArrays(BitConverter.GetBytes(checksum.Lgth),
                                                              checksum.Bnd, BitConverter.GetBytes(checksum.Flags));
            plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)ChecksumType.ap_authenticator_8003), new Asn1OctetString(checkData));

            return(plaintextAuthenticator);
        }
 /// <summary>
 /// Initializes a new instance of this class with the specified <paramref name="requestId"/>, <see cref="BingAds.AuthorizationData"/> and <paramref name="apiEnvironment"/>.
 /// </summary>
 /// <param name="requestId">The identifier of a download request that has previously been submitted.</param>
 /// <param name="authorizationData">
 /// Represents a user who intends to access the corresponding customer and account.
 /// </param>
 /// <param name="apiEnvironment">Bing Ads API environment</param>
 public ReportingDownloadOperation(string requestId, AuthorizationData authorizationData, ApiEnvironment?apiEnvironment)
     : this(requestId, authorizationData, null, apiEnvironment)
 {
 }
Exemplo n.º 47
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                CampaignService = new ServiceClient <ICampaignManagementService>(authorizationData);

                // Specify one or more campaigns.

                var campaigns = new[] {
                    new Campaign
                    {
                        Name        = "Women's Shoes " + DateTime.UtcNow,
                        Description = "Red shoes line.",
                        DailyBudget = 50,
                        BudgetType  = BudgetLimitType.DailyBudgetStandard,
                        TimeZone    = "PacificTimeUSCanadaTijuana",
                    },
                };

                var adGroups = new[] {
                    new AdGroup
                    {
                        Name           = "Women's Red Shoe Sale",
                        AdDistribution = AdDistribution.Search,
                        StartDate      = null,
                        EndDate        = new Microsoft.BingAds.V11.CampaignManagement.Date {
                            Month = 12,
                            Day   = 31,
                            Year  = DateTime.UtcNow.Year + 1
                        },
                        SearchBid = new Bid {
                            Amount = 0.09
                        },
                        Language = "English",
                    }
                };

                var keywords = new[]
                {
                    new Keyword
                    {
                        Bid = new Bid {
                            Amount = 0.47
                        },
                        Param2    = "10% Off",
                        MatchType = MatchType.Phrase,
                        Text      = "Brand-A Shoes",
                    },
                };

                var ads = new Ad[] {
                    new ExpandedTextAd
                    {
                        TitlePart1 = "Contoso",
                        TitlePart2 = "Fast & Easy Setup",
                        Text       = "Find New Customers & Increase Sales! Start Advertising on Contoso Today.",
                        Path1      = "seattle",
                        Path2      = "shoe sale",
                        FinalUrls  = new[] {
                            "http://www.contoso.com/womenshoesale"
                        },
                    },
                };

                var random = new Random();
                var labels = new List <Label>();

                for (var labelIndex = 0; labelIndex < 50; labelIndex++)
                {
                    var color = string.Format("#{0:X6}", random.Next(0x100000));
                    labels.Add(new Label
                    {
                        ColorCode   = color,
                        Description = "Label Description",
                        Name        = "Label Name " + color + " " + DateTime.UtcNow
                    });
                }

                AddLabelsResponse addLabelsResponse = await AddLabelsAsync(labels);

                long?[]      nullableLabelIds = addLabelsResponse.LabelIds.ToArray();
                BatchError[] labelErrors      = addLabelsResponse.PartialErrors.ToArray();
                OutputStatusMessage("New Label Ids:");
                OutputIds(nullableLabelIds);
                OutputPartialErrors(labelErrors);

                AddCampaignsResponse addCampaignsResponse = await AddCampaignsAsync(authorizationData.AccountId, campaigns);

                long?[]      nullableCampaignIds = addCampaignsResponse.CampaignIds.ToArray();
                BatchError[] campaignErrors      = addCampaignsResponse.PartialErrors.ToArray();
                OutputStatusMessage("New Campaign Ids:");
                OutputIds(nullableCampaignIds);
                OutputPartialErrors(campaignErrors);

                AddAdGroupsResponse addAdGroupsResponse = await AddAdGroupsAsync((long)nullableCampaignIds[0], adGroups);

                long?[]      nullableAdGroupIds = addAdGroupsResponse.AdGroupIds.ToArray();
                BatchError[] adGroupErrors      = addAdGroupsResponse.PartialErrors.ToArray();
                OutputStatusMessage("New Ad Group Ids:");
                OutputIds(nullableAdGroupIds);
                OutputPartialErrors(adGroupErrors);

                AddKeywordsResponse addKeywordsResponse = await AddKeywordsAsync((long)nullableAdGroupIds[0], keywords);

                long?[]      nullableKeywordIds = addKeywordsResponse.KeywordIds.ToArray();
                BatchError[] keywordErrors      = addKeywordsResponse.PartialErrors.ToArray();
                OutputStatusMessage("New Keyword Ids:");
                OutputIds(nullableKeywordIds);
                OutputPartialErrors(keywordErrors);

                AddAdsResponse addAdsResponse = await AddAdsAsync((long)nullableAdGroupIds[0], ads);

                long?[]      nullableAdIds = addAdsResponse.AdIds.ToArray();
                BatchError[] adErrors      = addAdsResponse.PartialErrors.ToArray();
                OutputStatusMessage("New Ad Ids:");
                OutputIds(nullableAdIds);
                OutputPartialErrors(adErrors);

                var labelIds = GetNonNullableIds(nullableLabelIds);

                OutputStatusMessage("\nGet all the labels that we added above...");

                var getLabelsByIdsResponse = await GetLabelsByIdsAsync(
                    labelIds,
                    new Paging
                {
                    Index = 0,
                    Size  = MaxGetLabelsByIds
                }
                    );

                OutputLabels(getLabelsByIdsResponse.Labels);

                OutputStatusMessage("\nUpdate the label color and then retrieve the labels again to confirm the changes....");

                var updateLabels = new List <Label>();
                foreach (var label in getLabelsByIdsResponse.Labels)
                {
                    label.ColorCode = string.Format("#{0:X6}", random.Next(0x100000));
                    updateLabels.Add(label);
                }
                var updateLabelsResponse = await UpdateLabelsAsync(updateLabels);

                getLabelsByIdsResponse = await GetLabelsByIdsAsync(
                    labelIds,
                    new Paging
                {
                    Index = 0,
                    Size  = MaxGetLabelsByIds
                }
                    );

                OutputLabels(getLabelsByIdsResponse.Labels);

                var campaignLabelAssociations = CreateExampleLabelAssociationsByEntityId((long)nullableCampaignIds[0], labelIds);
                OutputStatusMessage("\nAssociating all of the labels with a campaign...");
                OutputLabelAssociations(campaignLabelAssociations);
                var setLabelAssociationsResponse = await SetLabelAssociationsAsync(campaignLabelAssociations, EntityType.Campaign);

                var adGroupLabelAssociations = CreateExampleLabelAssociationsByEntityId((long)nullableAdGroupIds[0], labelIds);
                OutputStatusMessage("\nAssociating all of the labels with an ad group...");
                OutputLabelAssociations(adGroupLabelAssociations);
                setLabelAssociationsResponse = await SetLabelAssociationsAsync(adGroupLabelAssociations, EntityType.AdGroup);

                var keywordLabelAssociations = CreateExampleLabelAssociationsByEntityId((long)nullableKeywordIds[0], labelIds);
                OutputStatusMessage("\nAssociating all of the labels with a keyword...");
                OutputLabelAssociations(keywordLabelAssociations);
                setLabelAssociationsResponse = await SetLabelAssociationsAsync(keywordLabelAssociations, EntityType.Keyword);

                var adLabelAssociations = CreateExampleLabelAssociationsByEntityId((long)nullableAdIds[0], labelIds);
                OutputStatusMessage("\nAssociating all of the labels with an ad...");
                OutputLabelAssociations(adLabelAssociations);
                setLabelAssociationsResponse = await SetLabelAssociationsAsync(adLabelAssociations, EntityType.Ad);


                OutputStatusMessage("\nUse paging to get all campaign label associations...");
                var getLabelAssociationsByLabelIds = await GetLabelAssociationsByLabelIdsHelperAsync(labelIds, EntityType.Campaign);

                OutputLabelAssociations(getLabelAssociationsByLabelIds);

                OutputStatusMessage("\nUse paging to get all ad group label associations...");
                getLabelAssociationsByLabelIds = await GetLabelAssociationsByLabelIdsHelperAsync(labelIds, EntityType.AdGroup);

                OutputLabelAssociations(getLabelAssociationsByLabelIds);

                OutputStatusMessage("\nUse paging to get all keyword label associations...");
                getLabelAssociationsByLabelIds = await GetLabelAssociationsByLabelIdsHelperAsync(labelIds, EntityType.Keyword);

                OutputLabelAssociations(getLabelAssociationsByLabelIds);

                OutputStatusMessage("\nUse paging to get all ad label associations...");
                getLabelAssociationsByLabelIds = await GetLabelAssociationsByLabelIdsHelperAsync(labelIds, EntityType.Ad);

                OutputLabelAssociations(getLabelAssociationsByLabelIds);

                OutputStatusMessage("\nGet all label associations for all specified campaigns...");
                var getLabelAssociationsByEntityIds = await GetLabelAssociationsByEntityIdsHelperAsync(
                    GetNonNullableIds(nullableCampaignIds),
                    EntityType.Campaign
                    );

                OutputLabelAssociations(getLabelAssociationsByEntityIds);

                OutputStatusMessage("\nGet all label associations for all specified ad groups...");
                getLabelAssociationsByEntityIds = await GetLabelAssociationsByEntityIdsHelperAsync(
                    GetNonNullableIds(nullableAdGroupIds),
                    EntityType.AdGroup
                    );

                OutputLabelAssociations(getLabelAssociationsByEntityIds);

                OutputStatusMessage("\nGet all label associations for all specified keywords...");
                getLabelAssociationsByEntityIds = await GetLabelAssociationsByEntityIdsHelperAsync(
                    GetNonNullableIds(nullableKeywordIds),
                    EntityType.Keyword
                    );

                OutputLabelAssociations(getLabelAssociationsByEntityIds);

                OutputStatusMessage("\nGet all label associations for all specified ads...");
                getLabelAssociationsByEntityIds = await GetLabelAssociationsByEntityIdsHelperAsync(
                    GetNonNullableIds(nullableAdIds),
                    EntityType.Ad
                    );

                OutputLabelAssociations(getLabelAssociationsByEntityIds);

                OutputStatusMessage("\nDelete all label associations that we set above....");

                // This is not necessary if you are deleting the corresponding campaign(s), as the
                // contained ad groups, keywords, ads, and associations would also be deleted.

                var deleteLabelAssociationsResponse = await DeleteLabelAssociationsAsync(campaignLabelAssociations, EntityType.Campaign);

                deleteLabelAssociationsResponse = await DeleteLabelAssociationsAsync(adGroupLabelAssociations, EntityType.AdGroup);

                deleteLabelAssociationsResponse = await DeleteLabelAssociationsAsync(keywordLabelAssociations, EntityType.Keyword);

                deleteLabelAssociationsResponse = await DeleteLabelAssociationsAsync(adLabelAssociations, EntityType.Ad);

                OutputStatusMessage("\nDelete all labels that we added above....");

                // Deleting the campaign(s) removes the corresponding label associations but not remove the labels.

                var deleteLabelsResponse = await DeleteLabelsAsync(labelIds);

                OutputStatusMessage("\nDelete the campaign, ad group, keyword, and ad that were added above....");

                await DeleteCampaignsAsync(authorizationData.AccountId, new[] { (long)nullableCampaignIds[0] });
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V11.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
        public void AdFxFastUsedInAuthenticator()
        {
            base.Logging();

            client = new KerberosTestClient(
                this.testConfig.LocalRealm.RealmName,
                this.testConfig.LocalRealm.ClientComputer.NetBiosName,
                this.testConfig.LocalRealm.ClientComputer.Password,
                KerberosAccountType.Device,
                testConfig.LocalRealm.KDC[0].IPAddress,
                testConfig.LocalRealm.KDC[0].Port,
                testConfig.TransportType,
                testConfig.SupportedOid,
               testConfig.LocalRealm.ClientComputer.AccountSalt);

            // Kerberos Proxy Service is used
            if (this.testConfig.UseProxy)
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client .");
                KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig);
                proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName;
                client.UseProxy = true;
                client.ProxyClient = proxyClient;
            }

            // AS_REQ and KRB-ERROR using device principal
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;
            client.SendAsRequest(options, null);
            METHOD_DATA methodData;
            KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData);

            // AS_REQ and AS_REP using device principal
            string timeStamp = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(
                timeStamp,
                0,
                client.Context.SelectedEType,
                this.client.Context.CName.Password,
                this.client.Context.CName.Salt);
            Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data });
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();
            BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT.");
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                string.Format("The type of AS-REP encrypted part is {0}.", asResponse.EncPart.GetType().Name));

            // Switch to user principal
            client = new KerberosTestClient(
                this.testConfig.LocalRealm.RealmName,
                this.testConfig.LocalRealm.User[1].Username,
                this.testConfig.LocalRealm.User[1].Password,
                KerberosAccountType.User,
                client.Context.Ticket,
                client.Context.SessionKey,
                testConfig.LocalRealm.KDC[0].IPAddress,
                testConfig.LocalRealm.KDC[0].Port,
                testConfig.TransportType,
                testConfig.SupportedOid);

            // Kerberos Proxy Service is used
            if (this.testConfig.UseProxy)
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client .");
                KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig);
                proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName;
                client.UseProxy = true;
                client.ProxyClient = proxyClient;
            }

            // FAST armored AS_REQ and KRB-ERROR using user principal
            //Create a "random" key.
            var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt");
            var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0));
            var apOptions = ApOptions.None;

            Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { new PA_DATA(new KerbInt32((long)PaDataType.PA_FX_FAST), null) });
            client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions);
            KerberosKrbError krbError2 = client.ExpectKrbError();
            BaseTestSite.Assert.AreEqual(krbError2.ErrorCode, KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, "Pre-authentication required.");

            // FAST armored AS_REQ and AS_REP using user principal
            var userKey = KerberosUtility.MakeKey(
                client.Context.SelectedEType,
                client.Context.CName.Password,
                client.Context.CName.Salt);
            PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge(
                client.Context.SelectedEType,
                KerberosUtility.CurrentKerberosTime.Value,
                0,
                client.Context.FastArmorkey,
                userKey);
            Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data });
            client.SendAsRequestWithFast(options, seqOfPaData3, null, subkey, fastOptions, apOptions);
            KerberosAsResponse userKrbAsRep = client.ExpectAsResponse();
            BaseTestSite.Assert.IsNotNull(userKrbAsRep.Response.ticket, "AS response should contain a TGT.");
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                string.Format("The type of AS-REP encrypted part is {0}.", userKrbAsRep.EncPart.GetType().Name));

            // FAST armored TGS_REQ and TGS_REP using user principal
            subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt");
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send unarmored TGS request with AD-fx-fast-used.");
            AdFxFastUsed adFxFastUsed = new AdFxFastUsed();
            AuthorizationData authData = new AuthorizationData(new AuthorizationDataElement[] { adFxFastUsed.AuthDataElement });
            client.SendTgsRequest(testConfig.LocalRealm.ClientComputer.DefaultServiceName, options, null, null, authData);
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Receive TGS Error, KDC MUST reject the request.");
            KerberosKrbError krbError = client.ExpectKrbError();
        }
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                CampaignManagementExampleHelper CampaignManagementExampleHelper =
                    new CampaignManagementExampleHelper(this.OutputStatusMessage);
                CampaignManagementExampleHelper.CampaignManagementService =
                    new ServiceClient <ICampaignManagementService>(authorizationData, environment);

                // Get a list of all Bing Merchant Center stores associated with your CustomerId

                IList <BMCStore> stores = (await CampaignManagementExampleHelper.GetBMCStoresByCustomerIdAsync())?.BMCStores;
                if (stores == null)
                {
                    OutputStatusMessage(
                        string.Format("You do not have any BMC stores registered for CustomerId {0}.\n", authorizationData.CustomerId)
                        );
                    return;
                }

                #region ManageCampaign

                /* Add a new Bing Shopping campaign that will be associated with a ProductScope criterion.
                 *  - Set the CampaignType element of the Campaign to Shopping.
                 *  - Create a ShoppingSetting instance and set its Priority (0, 1, or 2), SalesCountryCode, and StoreId elements.
                 *    Add this shopping setting to the Settings list of the Campaign.
                 */

                var campaigns = new[] {
                    new Campaign
                    {
                        CampaignType = CampaignType.Shopping,
                        Settings     = new[] {
                            new ShoppingSetting()
                            {
                                Priority         = 0,
                                SalesCountryCode = "US",
                                StoreId          = (int)stores[0].Id
                            }
                        },
                        Name        = "Bing Shopping Campaign " + DateTime.UtcNow,
                        Description = "Bing Shopping Campaign Example.",

                        // You must choose to set either the shared  budget ID or daily amount.
                        // You can set one or the other, but you may not set both.
                        BudgetId    = null,
                        DailyBudget = 50,
                        BudgetType  = BudgetLimitType.DailyBudgetStandard,

                        TimeZone = "PacificTimeUSCanadaTijuana",

                        // Used with CustomParameters defined in lower level entities such as ad group criterion.
                        TrackingUrlTemplate =
                            "http://tracker.example.com/?season={_season}&promocode={_promocode}&u={lpurl}"
                    }
                };

                AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync(authorizationData.AccountId, campaigns);

                long?[]      campaignIds    = addCampaignsResponse.CampaignIds.ToArray();
                BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray();
                CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds);
                CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors);
                long campaignId = (long)campaignIds[0];

                /* Optionally, you can create a ProductScope criterion that will be associated with your Bing Shopping campaign.
                 * Use the product scope criterion to include a subset of your product catalog, for example a specific brand,
                 * category, or product type. A campaign can only be associated with one ProductScope, which contains a list
                 * of up to 7 ProductCondition. You'll also be able to specify more specific product conditions for each ad group.
                 */

                var campaignCriterions = new BiddableCampaignCriterion[] {
                    new BiddableCampaignCriterion()
                    {
                        CampaignId   = campaignId,
                        CriterionBid = null,  // Not applicable for product scope
                        Criterion    = new ProductScope()
                        {
                            Conditions = new ProductCondition[] {
                                new ProductCondition {
                                    Operand   = "Condition",
                                    Attribute = "New"
                                },
                                new ProductCondition {
                                    Operand   = "CustomLabel0",
                                    Attribute = "MerchantDefinedCustomLabel"
                                },
                            }
                        },
                    }
                };

                var addCampaignCriterionsResponse = await(CampaignManagementExampleHelper.AddCampaignCriterionsAsync(
                                                              campaignCriterions,
                                                              CampaignCriterionType.ProductScope)
                                                          );

                #endregion ManageCampaign

                #region ManageAdGroup

                // Create the ad group that will have the product partitions.

                var adGroups = new[] {
                    new AdGroup
                    {
                        Name      = "Product Categories",
                        StartDate = null,
                        EndDate   = new Microsoft.BingAds.V12.CampaignManagement.Date {
                            Month = 12,
                            Day   = 31,
                            Year  = DateTime.UtcNow.Year + 1
                        },
                        Language = "English",
                        CpcBid   = new Bid {
                            Amount = 0.090
                        }
                    }
                };

                AddAdGroupsResponse addAdGroupsResponse = await CampaignManagementExampleHelper.AddAdGroupsAsync((long)campaignId, adGroups, null);

                long?[]      adGroupIds    = addAdGroupsResponse.AdGroupIds.ToArray();
                BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray();
                CampaignManagementExampleHelper.OutputArrayOfLong(adGroupIds);
                CampaignManagementExampleHelper.OutputArrayOfBatchError(adGroupErrors);
                long adGroupId = (long)adGroupIds[0];

                #region BidAllProducts

                var helper = new PartitionActionHelper(adGroupId);

                var root = helper.AddUnit(
                    null,
                    new ProductCondition {
                    Operand = "All", Attribute = null
                },
                    0.35,
                    false
                    );

                OutputStatusMessage("Applying only the root as a Unit with a bid . . . \n");
                var applyProductPartitionActionsResponse = await CampaignManagementExampleHelper.ApplyProductPartitionActionsAsync(helper.PartitionActions);

                var adGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
                    null,
                    adGroupId,
                    AdGroupCriterionType.ProductPartition
                    );

                OutputStatusMessage("The ad group's product partition only has a tree root node: \n");
                OutputProductPartitions(adGroupCriterions?.AdGroupCriterions);

                /*
                 * Let's update the bid of the root Unit we just added.
                 */

                BiddableAdGroupCriterion updatedRoot = new BiddableAdGroupCriterion
                {
                    Id           = applyProductPartitionActionsResponse.AdGroupCriterionIds[0],
                    CriterionBid = new FixedBid
                    {
                        Amount = 0.45
                    }
                };

                helper = new PartitionActionHelper(adGroupId);
                helper.UpdatePartition(updatedRoot);

                OutputStatusMessage("Updating the bid for the tree root node . . . \n");
                await CampaignManagementExampleHelper.ApplyProductPartitionActionsAsync(helper.PartitionActions);

                adGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
                    null,
                    adGroupId,
                    AdGroupCriterionType.ProductPartition
                    );

                OutputStatusMessage("Updated the bid for the tree root node: \n");
                OutputProductPartitions(adGroupCriterions?.AdGroupCriterions);

                #endregion BidAllProducts

                #region InitializeTree

                /*
                 * Now we will overwrite any existing tree root, and build a product partition group tree structure in multiple steps.
                 * You could build the entire tree in a single call since there are less than 5,000 nodes; however,
                 * we will build it in steps to demonstrate how to use the results from ApplyProductPartitionActions to update the tree.
                 *
                 * For a list of validation rules, see the Product Ads technical guide:
                 * https://docs.microsoft.com/en-us/bingads/guides/product-ads
                 */

                helper = new PartitionActionHelper(adGroupId);

                /*
                 * Check whether a root node exists already.
                 */
                adGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
                    null,
                    adGroupId,
                    AdGroupCriterionType.ProductPartition
                    );

                var existingRoot = GetRootNode(adGroupCriterions?.AdGroupCriterions);
                if (existingRoot != null)
                {
                    helper.DeletePartition(existingRoot);
                }

                root = helper.AddSubdivision(
                    null,
                    new ProductCondition {
                    Operand = "All", Attribute = null
                }
                    );

                /*
                 * The direct children of any node must have the same Operand.
                 * For this example we will use CategoryL1 nodes as children of the root.
                 * For a list of valid CategoryL1 through CategoryL5 values, see the Bing Category Taxonomy:
                 * http://go.microsoft.com/fwlink?LinkId=507666
                 */
                var animalsSubdivision = helper.AddSubdivision(
                    root,
                    new ProductCondition {
                    Operand = "CategoryL1", Attribute = "Animals & Pet Supplies"
                }
                    );

                /*
                 * If you use a CategoryL2 node, it must be a descendant (child or later) of a CategoryL1 node.
                 * In other words you cannot have a CategoryL2 node as parent of a CategoryL1 node.
                 * For this example we will a CategoryL2 node as child of the CategoryL1 Animals & Pet Supplies node.
                 */
                var petSuppliesSubdivision = helper.AddSubdivision(
                    animalsSubdivision,
                    new ProductCondition {
                    Operand = "CategoryL2", Attribute = "Pet Supplies"
                }
                    );

                var brandA = helper.AddUnit(
                    petSuppliesSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = "Brand A"
                },
                    0.35,
                    false
                    );

                /*
                 * If you won't bid on Brand B, set the helper method's bidAmount to '0' and isNegative to true.
                 * The helper method will create a NegativeAdGroupCriterion and apply the condition.
                 */
                var brandB = helper.AddUnit(
                    petSuppliesSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = "Brand B"
                },
                    0,
                    true
                    );

                var otherBrands = helper.AddUnit(
                    petSuppliesSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = null
                },
                    0.35,
                    false
                    );

                var otherPetSupplies = helper.AddUnit(
                    animalsSubdivision,
                    new ProductCondition {
                    Operand = "CategoryL2", Attribute = null
                },
                    0.35,
                    false
                    );

                var electronics = helper.AddUnit(
                    root,
                    new ProductCondition {
                    Operand = "CategoryL1", Attribute = "Electronics"
                },
                    0.35,
                    false
                    );

                var otherCategoryL1 = helper.AddUnit(
                    root,
                    new ProductCondition {
                    Operand = "CategoryL1", Attribute = null
                },
                    0.35,
                    false
                    );

                OutputStatusMessage("Applying product partitions to the ad group . . . \n");
                applyProductPartitionActionsResponse = await CampaignManagementExampleHelper.ApplyProductPartitionActionsAsync(helper.PartitionActions);

                // To retrieve product partitions after they have been applied, call GetAdGroupCriterionsByIds.
                // The product partition with ParentCriterionId set to null is the root node.

                adGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
                    null,
                    adGroupId,
                    AdGroupCriterionType.ProductPartition
                    );

                /*
                 * The product partition group tree now has 9 nodes.
                 *
                 * All other (Root Node)
                 |
                 +-- Animals & Pet Supplies (CategoryL1)
                 |    |
                 |    +-- Pet Supplies (CategoryL2)
                 |    |    |
                 |    |    +-- Brand A
                 |    |    |
                 |    |    +-- Brand B
                 |    |    |
                 |    |    +-- All other (Brand)
                 |    |
                 |    +-- All other (CategoryL2)
                 |
                 +-- Electronics (CategoryL1)
                 |
                 +-- All other (CategoryL1)
                 |
                 */

                OutputStatusMessage("The product partition group tree now has 9 nodes: \n");
                OutputProductPartitions(adGroupCriterions?.AdGroupCriterions);

                #endregion InitializeTree

                #region UpdateTree

                /*
                 * Let's replace the Electronics (CategoryL1) node created above with an Electronics (CategoryL1) node that
                 * has children i.e. Brand C (Brand), Brand D (Brand), and All other (Brand) as follows:
                 *
                 *  Electronics (CategoryL1)
                 |
                 +-- Brand C (Brand)
                 |
                 +-- Brand D (Brand)
                 |
                 +-- All other (Brand)
                 |
                 */

                helper = new PartitionActionHelper(adGroupId);

                /*
                 * To replace a node we must know its Id and its ParentCriterionId. In this case the parent of the node
                 * we are replacing is All other (Root Node), and was created at Index 1 of the previous ApplyProductPartitionActions call.
                 * The node that we are replacing is Electronics (CategoryL1), and was created at Index 8.
                 */
                var rootId = applyProductPartitionActionsResponse.AdGroupCriterionIds[1];
                electronics.Id = applyProductPartitionActionsResponse.AdGroupCriterionIds[8];
                helper.DeletePartition(electronics);

                var parent = new BiddableAdGroupCriterion()
                {
                    Id = rootId
                };

                var electronicsSubdivision = helper.AddSubdivision(
                    parent,
                    new ProductCondition {
                    Operand = "CategoryL1", Attribute = "Electronics"
                }
                    );

                var brandC = helper.AddUnit(
                    electronicsSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = "Brand C"
                },
                    0.35,
                    false
                    );

                var brandD = helper.AddUnit(
                    electronicsSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = "Brand D"
                },
                    0.35,
                    false
                    );

                var otherElectronicsBrands = helper.AddUnit(
                    electronicsSubdivision,
                    new ProductCondition {
                    Operand = "Brand", Attribute = null
                },
                    0.35,
                    false
                    );

                OutputStatusMessage(
                    "Updating the product partition group to refine Electronics (CategoryL1) with 3 child nodes . . . \n"
                    );
                applyProductPartitionActionsResponse = await CampaignManagementExampleHelper.ApplyProductPartitionActionsAsync(helper.PartitionActions);

                adGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
                    null,
                    adGroupId,
                    AdGroupCriterionType.ProductPartition
                    );

                /*
                 * The product partition group tree now has 12 nodes, including the children of Electronics (CategoryL1):
                 *
                 * All other (Root Node)
                 |
                 +-- Animals & Pet Supplies (CategoryL1)
                 |    |
                 |    +-- Pet Supplies (CategoryL2)
                 |    |    |
                 |    |    +-- Brand A
                 |    |    |
                 |    |    +-- Brand B
                 |    |    |
                 |    |    +-- All other (Brand)
                 |    |
                 |    +-- All other (CategoryL2)
                 |
                 +-- Electronics (CategoryL1)
                 |    |
                 |    +-- Brand C (Brand)
                 |    |
                 |    +-- Brand D (Brand)
                 |    |
                 |    +-- All other (Brand)
                 |
                 +-- All other (CategoryL1)
                 |
                 */

                OutputStatusMessage(
                    "The product partition group tree now has 12 nodes, including the children of Electronics (CategoryL1): \n"
                    );
                OutputProductPartitions(adGroupCriterions?.AdGroupCriterions);

                #endregion UpdateTree

                #endregion ManageAdGroup

                #region ManageAds

                /*
                 * Create a product ad. You must add at least one product ad to the ad group.
                 * The product ad identifier can be used for reporting analytics.
                 * Use Merchant Promotions if you want tags to appear at the bottom of your product ad
                 * as "special offer" links, helping to increase customer engagement. For details
                 * on Merchant Promotions see https://help.bingads.microsoft.com/#apex/3/en/56805/0.
                 */

                var ads = new Ad[] {
                    new ProductAd {
                    }
                };

                AddAdsResponse addAdsResponse = await CampaignManagementExampleHelper.AddAdsAsync((long)adGroupIds[0], ads);

                long?[]      adIds    = addAdsResponse.AdIds.ToArray();
                BatchError[] adErrors = addAdsResponse.PartialErrors.ToArray();
                CampaignManagementExampleHelper.OutputArrayOfLong(adIds);
                CampaignManagementExampleHelper.OutputArrayOfBatchError(adErrors);

                #endregion ManageAds

                #region CleanUp

                /* Delete the campaign, ad group, criterion, and ad that were previously added.
                 * You should remove this region if you want to view the added entities in the
                 * Bing Ads web application or another tool.
                 */

                await CampaignManagementExampleHelper.DeleteCampaignsAsync(authorizationData.AccountId, new[] { campaignId });

                OutputStatusMessage(string.Format("Deleted Campaign Id {0}\n", campaignId));

                #endregion CleanUp
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
Exemplo n.º 50
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                CampaignManagementExampleHelper = new CampaignManagementExampleHelper(this.OutputStatusMessage);

                BulkServiceManager = new BulkServiceManager(authorizationData);

                var progress = new Progress <BulkOperationProgressInfo>(x =>
                                                                        OutputStatusMessage(string.Format("{0} % Complete",
                                                                                                          x.PercentComplete.ToString(CultureInfo.InvariantCulture))));

                var downloadParameters = new DownloadParameters
                {
                    DownloadEntities    = new[] { DownloadEntity.AdGroupProductPartitions },
                    ResultFileDirectory = FileDirectory,
                    ResultFileName      = DownloadFileName,
                    OverwriteResultFile = true,
                    LastSyncTimeInUTC   = null
                };

                // Download all product partitions across all ad groups in the account.
                var bulkFilePath = await BulkServiceManager.DownloadFileAsync(downloadParameters);

                OutputStatusMessage("Downloaded all product partitions across all ad groups in the account.\n");

                Reader = new BulkFileReader(bulkFilePath, ResultFileType.FullDownload, FileType);
                var bulkAdGroupProductPartitions = Reader.ReadEntities().ToList().OfType <BulkAdGroupProductPartition>().ToList();
                OutputBulkAdGroupProductPartitions(bulkAdGroupProductPartitions);

                var uploadEntities = new List <BulkEntity>();

                // Within the downloaded records, find all product partition leaf nodes that have bids.

                foreach (var bulkAdGroupProductPartition in bulkAdGroupProductPartitions)
                {
                    var biddableAdGroupCriterion = (bulkAdGroupProductPartition).AdGroupCriterion as BiddableAdGroupCriterion;
                    if (biddableAdGroupCriterion != null &&
                        (((ProductPartition)biddableAdGroupCriterion.Criterion).PartitionType == ProductPartitionType.Unit))
                    {
                        // We will increase all bids by some predetermined amount or percentage as an example.
                        // For best performance, only upload the properties that you want to update.

                        uploadEntities.Add(new BulkAdGroupProductPartition
                        {
                            AdGroupCriterion = new BiddableAdGroupCriterion
                            {
                                AdGroupId    = bulkAdGroupProductPartition.AdGroupCriterion.AdGroupId,
                                CriterionBid = new FixedBid
                                {
                                    Amount = ((FixedBid)biddableAdGroupCriterion.CriterionBid).Amount + 0.01
                                },
                                Id = bulkAdGroupProductPartition.AdGroupCriterion.Id,
                            }
                        });
                    }
                }

                Reader.Dispose();

                if (uploadEntities.Count > 0)
                {
                    OutputStatusMessage("Changed local bid of all product partitions. Starting upload.\n");

                    Reader = await WriteEntitiesAndUploadFileAsync(uploadEntities);

                    bulkAdGroupProductPartitions = Reader.ReadEntities().ToList().OfType <BulkAdGroupProductPartition>().ToList();
                    OutputBulkAdGroupProductPartitions(bulkAdGroupProductPartitions);
                    Reader.Dispose();
                }
                else
                {
                    OutputStatusMessage("No product partitions in account. \n");
                }

                OutputStatusMessage("Program execution completed\n");
            }
            // Catch Microsoft Account authorization exceptions.
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Bulk service exceptions
            catch (FaultException <Microsoft.BingAds.V12.Bulk.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V12.Bulk.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationInProgressException ex)
            {
                OutputStatusMessage("The result file for the bulk operation is not yet available for download.");
                OutputStatusMessage(ex.Message);
            }
            catch (BulkOperationCouldNotBeCompletedException <DownloadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (BulkOperationCouldNotBeCompletedException <UploadStatus> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
            finally
            {
                if (Reader != null)
                {
                    Reader.Dispose();
                }
                if (Writer != null)
                {
                    Writer.Dispose();
                }
            }
        }
Exemplo n.º 51
0
        private void DAC_Smb2_AccessFile(string RealmName, User user, Computer kdc, TransportType transportType, FileServer fileserver, string filePath, string fileName, bool expectAccessDeny)
        {
            base.Logging();

            client = new KerberosTestClient(RealmName,
                                            user.Username,
                                            user.Password,
                                            KerberosAccountType.User,
                                            kdc.IPAddress,
                                            kdc.Port,
                                            transportType,
                                            testConfig.SupportedOid);

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            client.SendAsRequest(options, null);
            //Recieve preauthentication required error
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               client.Context.SelectedEType,
                                                               this.client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });

            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();

            BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT.");

            //Create and send TGS request
            client.SendTgsRequest(fileserver.Smb2ServiceName, options);
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Assert.AreEqual(fileserver.Smb2ServiceName,
                                         KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname),
                                         "Service principal name in service ticket should match expected.");
            EncryptionKey key = testConfig.QueryKey(fileserver.Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType);

            tgsResponse.DecryptTicket(key);

            BaseTestSite.Assert.AreEqual(RealmName.ToLower(),
                                         tgsResponse.TicketEncPart.crealm.Value.ToLower(),
                                         "Realm name in service ticket encrypted part should match expected.");
            BaseTestSite.Assert.AreEqual(user.Username.ToLower(),
                                         KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(),
                                         "User name in service ticket encrypted part should match expected.");

            //Assert authorization data
            if (this.testConfig.IsKileImplemented)
            {
                BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data.");
                AdWin2KPac adWin2kPac = FindOneInAuthData <AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements);
                BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac.");
            }

            AuthorizationData data   = null;
            EncryptionKey     subkey = KerberosUtility.GenerateKey(client.Context.SessionKey);

            byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired,
                                                    data,
                                                    subkey,
                                                    ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Logon to fileserver and Access File.");
            AccessFile(filePath, fileName, fileserver, token, tgsResponse.EncPart.key, expectAccessDeny);
        }
 /// <summary>
 /// Initializes a new instance of this class with the specified <paramref name="requestId"/>, <see cref="BingAds.AuthorizationData"/> and <paramref name="apiEnvironment"/>.
 /// </summary>
 /// <param name="requestId">The identifier of a download request that has previously been submitted.</param>
 /// <param name="authorizationData">
 /// Represents a user who intends to access the corresponding customer and account. 
 /// </param>
 /// <param name="apiEnvironment">Bing Ads API environment</param>
 public ReportingDownloadOperation(string requestId, AuthorizationData authorizationData, ApiEnvironment? apiEnvironment)
     : this(requestId, authorizationData, null, apiEnvironment)
 {
 }
Exemplo n.º 53
0
        private void CBAC_Smb2_AccessFile(string RealmName, User user, Computer kdc, TransportType transportType, FileServer fileserver, string filePath, string fileName, bool expectAccessDeny)
        {
            base.Logging();

            client = new KerberosTestClient(RealmName,
                                            user.Username,
                                            user.Password,
                                            KerberosAccountType.User,
                                            kdc.IPAddress,
                                            kdc.Port,
                                            transportType,
                                            testConfig.SupportedOid);

            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            client.SendAsRequest(options, null);
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with PaEncTimeStamp, PaPacRequest and paPacOptions.");
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               client.Context.SelectedEType,
                                                               client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            PaPacOptions             paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data });

            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();

            //Verify encrypted padata
            PaSupportedEncTypes paSupportedEncTypes = null;

            BaseTestSite.Assert.IsNotNull(asResponse.EncPart, "The encrypted part of AS-REP is decrypted.");
            BaseTestSite.Assert.IsNotNull(asResponse.EncPart.pa_datas, "The encrypted padata is not null.");
            if (this.testConfig.IsKileImplemented)
            {
                foreach (var padata in asResponse.EncPart.pa_datas.Elements)
                {
                    var parsedPadata = PaDataParser.ParseRepPaData(padata);
                    if (parsedPadata is PaSupportedEncTypes)
                    {
                        paSupportedEncTypes = parsedPadata as PaSupportedEncTypes;
                    }
                }
                BaseTestSite.Assert.IsNotNull(paSupportedEncTypes, "The encrypted padata of AS-REP contains PA_SUPPORTED_ENCTYPES.");
                if (this.testConfig.IsClaimSupported)
                {
                    BaseTestSite.Assert.IsTrue(
                        paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.Claims_Supported),
                        "Claims is supported.");
                }
            }
            //TGS exchange
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored TGS request: {0}.", fileserver.Smb2ServiceName);
            Asn1SequenceOf <PA_DATA> seqOfPaData2 = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data });

            client.SendTgsRequest(fileserver.Smb2ServiceName, options, seqOfPaData2);
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();
            EncryptionKey       key         = testConfig.QueryKey(fileserver.Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType);

            tgsResponse.DecryptTicket(key);
            BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart, "The encrypted part of TGS-REP is decrypted.");

            //Verify TGS encryped padata
            paSupportedEncTypes = null;
            BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart, "The encrypted part of TGS-REP is decrypted.");
            BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart.pa_datas, "The encrypted padata of TGS-REP is not null.");
            if (this.testConfig.IsKileImplemented)
            {
                foreach (var padata in tgsResponse.EncPart.pa_datas.Elements)
                {
                    var parsedPadata = PaDataParser.ParseRepPaData(padata);
                    if (parsedPadata is PaSupportedEncTypes)
                    {
                        paSupportedEncTypes = parsedPadata as PaSupportedEncTypes;
                    }
                }
                BaseTestSite.Assert.IsNotNull(paSupportedEncTypes, "The encrypted padata of TGS-REP contains PA_SUPPORTED_ENCTYPES.");
            }

            if (this.testConfig.IsKileImplemented)
            {
                BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data.");
                AdWin2KPac adWin2kPac = FindOneInAuthData <AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements);
                BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac.");
            }

            AuthorizationData data   = null;
            EncryptionKey     subkey = KerberosUtility.GenerateKey(client.Context.SessionKey);

            byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired,
                                                    data,
                                                    subkey,
                                                    ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Logon to fileserver and Access File.");
            AccessFile(filePath, fileName, fileserver, token, tgsResponse.EncPart.key, expectAccessDeny);
        }
        internal ReportingDownloadOperation(string requestId, AuthorizationData authorizationData, ReportingStatusProvider statusProvider, string trackingId, ApiEnvironment? apiEnvironment)
        {
            RequestId = requestId;

            AuthorizationData = authorizationData;

            _statusProvider = statusProvider;

            TrackingId = trackingId;

            StatusPollIntervalInMilliseconds = ReportingServiceManager.DefaultStatusPollIntervalInMilliseconds;

            _reportingServiceClient = new ServiceClient<IReportingService>(authorizationData, apiEnvironment);

            ZipExtractor = new ZipExtractor();

            HttpService = new HttpService();

            FileSystem = new FileSystem();
        }
Exemplo n.º 55
0
        private void CrossRealm_Smb2_AccessFile(string localRealmName, string trustuedRealmName, User localUser, Computer localKDC, Computer trustedKDC, TransportType transportType, FileServer fileserverInTrustedRealm, string filePath, string fileName, bool expectAccessDeny)
        {
            base.Logging();

            client = new KerberosTestClient(localRealmName,
                                            localUser.Username,
                                            localUser.Password,
                                            KerberosAccountType.User,
                                            localKDC.IPAddress,
                                            localKDC.Port,
                                            transportType,
                                            testConfig.SupportedOid);

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            client.SendAsRequest(options, null);
            //Recieve preauthentication required error
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               this.client.Context.SelectedEType,
                                                               this.client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });

            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();

            //Create and send TGS request
            if (this.testConfig.TrustType == Adapter.TrustType.Forest)
            {
                client.SendTgsRequest(fileserverInTrustedRealm.Smb2ServiceName, options);
            }
            else if (this.testConfig.TrustType == Adapter.TrustType.Realm)
            {
                client.SendTgsRequest(trustedKDC.DefaultServiceName, options);
            }
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send TGS request");
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Receive a referral TGS response.");

            BaseTestSite.Assert.AreEqual(trustedKDC.DefaultServiceName,
                                         KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname),
                                         "The service principal name in referral ticket should match expected.");
            BaseTestSite.Assert.AreEqual(localRealmName.ToLower(),
                                         tgsResponse.Response.ticket.realm.Value.ToLower(),
                                         "The realm name in referral ticket should match expected.");

            //Change realm
            client.ChangeRealm(trustuedRealmName,
                               trustedKDC.IPAddress,
                               trustedKDC.Port,
                               this.testConfig.TransportType);

            //Create and send referral TGS request
            client.SendTgsRequest(fileserverInTrustedRealm.Smb2ServiceName, options);
            KerberosTgsResponse refTgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Assert.AreEqual(fileserverInTrustedRealm.Smb2ServiceName,
                                         KerberosUtility.PrincipalName2String(refTgsResponse.Response.ticket.sname),
                                         "The service principal name in service ticket should match expected.");
            BaseTestSite.Assert.AreEqual(trustuedRealmName.ToLower(),
                                         refTgsResponse.Response.ticket.realm.Value.ToLower(),
                                         "The realm name in service ticket should match expected.");

            EncryptionKey key = testConfig.QueryKey(fileserverInTrustedRealm.Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType);

            refTgsResponse.DecryptTicket(key);

            BaseTestSite.Assert.AreEqual(localRealmName.ToLower(),
                                         refTgsResponse.TicketEncPart.crealm.Value.ToLower(),
                                         "Realm name in service ticket encrypted part should match expected.");
            BaseTestSite.Assert.AreEqual(localUser.Username.ToLower(),
                                         KerberosUtility.PrincipalName2String(refTgsResponse.TicketEncPart.cname).ToLower(),
                                         "User name in service ticket encrypted part should match expected.");

            AuthorizationData data   = null;
            EncryptionKey     subkey = KerberosUtility.GenerateKey(client.Context.SessionKey);

            byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired,
                                                    data,
                                                    subkey,
                                                    ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Logon to fileserver and Access File.");
            AccessFile(filePath, fileName, fileserverInTrustedRealm, token, refTgsResponse.EncPart.key, expectAccessDeny);
        }
        public KileAsResponse CreateAsResponse(
            KileConnection kileConnection,
            KerberosAccountType accountType,
            string password,
            _SeqOfPA_DATA SeqofPaData,
            EncTicketFlags encTicketFlags,
            AuthorizationData ticketAuthorizationData)
        {
            KileServerContext serverContext = GetServerContextByKileConnection(kileConnection);
            string cName = serverContext.UserName.name_string.elements[0].mValue;
            string cRealm = serverContext.UserRealm.mValue;
            serverContext.Salt = GenerateSalt(cRealm, cName, accountType);
            serverContext.TicketEncryptKey = new EncryptionKey((int)EncryptionType.RC4_HMAC,
                GetEncryptionKeyByType(EncryptionType.RC4_HMAC));

            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            else
            {
                serverContext.Password = password;
            }
            KileAsResponse response = new KileAsResponse(serverContext);

            // Construct a Ticket
            Ticket ticket = new Ticket();
            ticket.tkt_vno = new Asn1Integer(ConstValue.KERBEROSV5);
            ticket.realm = new Realm(domain);
            ticket.sname = serverContext.SName;

            // Set EncTicketPart
            EncTicketPart encTicketPart = new EncTicketPart();
            EncryptionType encryptionType = (EncryptionType)serverContext.EncryptType.elements[0].mValue;

            encTicketPart.key = new EncryptionKey((int)encryptionType, GetEncryptionKeyByType(encryptionType));
            encTicketPart.flags = new TicketFlags(KileUtility.ConvertInt2Flags((int)encTicketFlags));
            encTicketPart.crealm = serverContext.UserRealm;
            encTicketPart.cname = serverContext.UserName;
            encTicketPart.transited = new TransitedEncoding(4, null);
            encTicketPart.authtime = KileUtility.CurrentKerberosTime;
            encTicketPart.starttime = KileUtility.CurrentKerberosTime;
            encTicketPart.endtime = serverContext.endTime;
            encTicketPart.renew_till = serverContext.rtime ?? encTicketPart.endtime;
            encTicketPart.caddr = serverContext.Addresses;
            encTicketPart.authorization_data = ticketAuthorizationData;
            response.TicketEncPart = encTicketPart;

            // Set AS_REP
            response.Response.pvno = new Asn1Integer(ConstValue.KERBEROSV5);
            response.Response.msg_type = new Asn1Integer((int)MsgType.KRB_AS_RESP);
            response.Response.padata = SeqofPaData;
            response.Response.crealm = serverContext.UserRealm;
            response.Response.cname = serverContext.UserName;
            response.Response.ticket = ticket;

            // Set EncASRepPart
            EncASRepPart encASRepPart = new EncASRepPart();
            encASRepPart.key = encTicketPart.key;
            LastReq_element element = new LastReq_element(new Int32(0), KileUtility.CurrentKerberosTime);
            encASRepPart.last_req = new LastReq(new LastReq_element[] { element });
            encASRepPart.nonce = serverContext.Nonce;
            encASRepPart.flags = encTicketPart.flags;
            encASRepPart.authtime = encTicketPart.authtime;
            encASRepPart.starttime = encTicketPart.starttime;
            encASRepPart.endtime = encTicketPart.endtime;
            encASRepPart.renew_till = encTicketPart.renew_till;
            encASRepPart.srealm = ticket.realm;
            encASRepPart.sname = ticket.sname;
            encASRepPart.caddr = encTicketPart.caddr;
            response.EncPart = encASRepPart;

            return response;
        }
Exemplo n.º 57
0
        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                Service = new ServiceClient <ICampaignManagementService>(authorizationData);

                // Specify one or more campaigns.

                var campaigns = new[] {
                    new Campaign
                    {
                        Name           = "Women's Shoes" + DateTime.UtcNow,
                        Description    = "Red shoes line.",
                        BudgetType     = BudgetLimitType.MonthlyBudgetSpendUntilDepleted,
                        MonthlyBudget  = 1000.00,
                        TimeZone       = "PacificTimeUSCanadaTijuana",
                        DaylightSaving = true,

                        // You can set your campaign bid strategy to Enhanced CPC (EnhancedCpcBiddingScheme)
                        // and then, at any time, set an individual ad group or keyword bid strategy to
                        // Manual CPC (ManualCpcBiddingScheme).
                        // For campaigns you can use either of the EnhancedCpcBiddingScheme or ManualCpcBiddingScheme objects.
                        // If you do not set this element, then ManualCpcBiddingScheme is used by default.
                        BiddingScheme = new EnhancedCpcBiddingScheme {
                        },

                        // Used with FinalUrls shown in the text ads that we will add below.
                        TrackingUrlTemplate =
                            "http://tracker.example.com/?season={_season}&promocode={_promocode}&u={lpurl}"
                    },
                };

                // Specify one or more ad groups.

                var adGroups = new[] {
                    new AdGroup
                    {
                        Name           = "Women's Red Shoe Sale",
                        AdDistribution = AdDistribution.Search,
                        BiddingModel   = BiddingModel.Keyword,
                        PricingModel   = PricingModel.Cpc,
                        StartDate      = null,
                        EndDate        = new Microsoft.BingAds.V10.CampaignManagement.Date {
                            Month = 12,
                            Day   = 31,
                            Year  = DateTime.UtcNow.Year + 1
                        },
                        SearchBid = new Bid {
                            Amount = 0.09
                        },
                        Language = "English",

                        // For ad groups you can use either of the InheritFromParentBiddingScheme or ManualCpcBiddingScheme objects.
                        // If you do not set this element, then InheritFromParentBiddingScheme is used by default.
                        BiddingScheme = new ManualCpcBiddingScheme {
                        },

                        // You could use a tracking template which would override the campaign level
                        // tracking template. Tracking templates defined for lower level entities
                        // override those set for higher level entities.
                        // In this example we are using the campaign level tracking template.
                        TrackingUrlTemplate = null,
                    }
                };

                // In this example only the second keyword should succeed. The Text of the first keyword exceeds the limit,
                // and the third keyword is a duplicate of the second keyword.

                var keywords = new[] {
                    new Keyword
                    {
                        Bid = new Bid {
                            Amount = 0.47
                        },
                        Param2    = "10% Off",
                        MatchType = MatchType.Broad,
                        Text      = "Brand-A Shoes Brand-A Shoes Brand-A Shoes Brand-A Shoes Brand-A Shoes " +
                                    "Brand-A Shoes Brand-A Shoes Brand-A Shoes Brand-A Shoes Brand-A Shoes " +
                                    "Brand-A Shoes Brand-A Shoes Brand-A Shoes Brand-A Shoes Brand-A Shoes",
                        // For keywords you can use either of the InheritFromParentBiddingScheme or ManualCpcBiddingScheme objects.
                        // If you do not set this element, then InheritFromParentBiddingScheme is used by default.
                        BiddingScheme = new InheritFromParentBiddingScheme {
                        },
                    },
                    new Keyword
                    {
                        Bid = new Bid {
                            Amount = 0.47
                        },
                        Param2    = "10% Off",
                        MatchType = MatchType.Phrase,
                        Text      = "Brand-A Shoes",
                        // For keywords you can use either of the InheritFromParentBiddingScheme or ManualCpcBiddingScheme objects.
                        // If you do not set this element, then InheritFromParentBiddingScheme is used by default.
                        BiddingScheme = new InheritFromParentBiddingScheme {
                        },
                    },
                    new Keyword
                    {
                        Bid = new Bid {
                            Amount = 0.47
                        },
                        Param2    = "10% Off",
                        MatchType = MatchType.Phrase,
                        Text      = "Brand-A Shoes",
                        // For keywords you can use either of the InheritFromParentBiddingScheme or ManualCpcBiddingScheme objects.
                        // If you do not set this element, then InheritFromParentBiddingScheme is used by default.
                        BiddingScheme = new InheritFromParentBiddingScheme {
                        },
                    }
                };

                // In this example only the first 3 ads should succeed.
                // The Title of the fourth ad is empty and not valid,
                // and the fifth ad is a duplicate of the second ad.

                var ads = new Ad[] {
                    new TextAd
                    {
                        Title      = "Women's Shoe Sale",
                        Text       = "Huge Savings on red shoes.",
                        DisplayUrl = "Contoso.com",

                        // If you are currently using Destination URLs, you must replace them with Final URLs.
                        // Here is an example of a DestinationUrl you might have used previously.
                        // DestinationUrl = "http://www.contoso.com/womenshoesale/?season=spring&promocode=PROMO123",

                        // To migrate from DestinationUrl to FinalUrls for existing ads, you can set DestinationUrl
                        // to an empty string when updating the ad. If you are removing DestinationUrl,
                        // then FinalUrls is required.
                        // DestinationUrl = "",

                        // With FinalUrls you can separate the tracking template, custom parameters, and
                        // landing page URLs.
                        FinalUrls = new[] {
                            "http://www.contoso.com/womenshoesale"
                        },
                        // Final Mobile URLs can also be used if you want to direct the user to a different page
                        // for mobile devices.
                        FinalMobileUrls = new[] {
                            "http://mobile.contoso.com/womenshoesale"
                        },
                        // You could use a tracking template which would override the campaign level
                        // tracking template. Tracking templates defined for lower level entities
                        // override those set for higher level entities.
                        // In this example we are using the campaign level tracking template.
                        TrackingUrlTemplate = null,

                        // Set custom parameters that are specific to this ad,
                        // and can be used by the ad, ad group, campaign, or account level tracking template.
                        // In this example we are using the campaign level tracking template.
                        UrlCustomParameters = new CustomParameters {
                            Parameters = new[] {
                                new CustomParameter()
                                {
                                    Key   = "promoCode",
                                    Value = "PROMO1"
                                },
                                new CustomParameter()
                                {
                                    Key   = "season",
                                    Value = "summer"
                                },
                            }
                        }
                    },
                    new TextAd {
                        Title      = "Women's Super Shoe Sale",
                        Text       = "Huge Savings on red shoes.",
                        DisplayUrl = "Contoso.com",

                        // If you are currently using Destination URLs, you must replace them with Final URLs.
                        // Here is an example of a DestinationUrl you might have used previously.
                        // DestinationUrl = "http://www.contoso.com/womenshoesale/?season=spring&promocode=PROMO123",

                        // To migrate from DestinationUrl to FinalUrls for existing ads, you can set DestinationUrl
                        // to an empty string when updating the ad. If you are removing DestinationUrl,
                        // then FinalUrls is required.
                        // DestinationUrl = "",

                        // With FinalUrls you can separate the tracking template, custom parameters, and
                        // landing page URLs.
                        FinalUrls = new[] {
                            "http://www.contoso.com/womenshoesale"
                        },
                        // Final Mobile URLs can also be used if you want to direct the user to a different page
                        // for mobile devices.
                        FinalMobileUrls = new[] {
                            "http://mobile.contoso.com/womenshoesale"
                        },
                        // You could use a tracking template which would override the campaign level
                        // tracking template. Tracking templates defined for lower level entities
                        // override those set for higher level entities.
                        // In this example we are using the campaign level tracking template.
                        TrackingUrlTemplate = null,

                        // Set custom parameters that are specific to this ad,
                        // and can be used by the ad, ad group, campaign, or account level tracking template.
                        // In this example we are using the campaign level tracking template.
                        UrlCustomParameters = new CustomParameters {
                            Parameters = new[] {
                                new CustomParameter()
                                {
                                    Key   = "promoCode",
                                    Value = "PROMO2"
                                },
                                new CustomParameter()
                                {
                                    Key   = "season",
                                    Value = "summer"
                                },
                            }
                        },
                    },
                    new TextAd {
                        Title      = "Women's Red Shoe Sale",
                        Text       = "Huge Savings on red shoes.",
                        DisplayUrl = "Contoso.com",

                        // If you are currently using Destination URLs, you must replace them with Final URLs.
                        // Here is an example of a DestinationUrl you might have used previously.
                        // DestinationUrl = "http://www.contoso.com/womenshoesale/?season=spring&promocode=PROMO123",

                        // To migrate from DestinationUrl to FinalUrls for existing ads, you can set DestinationUrl
                        // to an empty string when updating the ad. If you are removing DestinationUrl,
                        // then FinalUrls is required.
                        // DestinationUrl = "",

                        // With FinalUrls you can separate the tracking template, custom parameters, and
                        // landing page URLs.
                        FinalUrls = new[] {
                            "http://www.contoso.com/womenshoesale"
                        },
                        // Final Mobile URLs can also be used if you want to direct the user to a different page
                        // for mobile devices.
                        FinalMobileUrls = new[] {
                            "http://mobile.contoso.com/womenshoesale"
                        },
                        // You could use a tracking template which would override the campaign level
                        // tracking template. Tracking templates defined for lower level entities
                        // override those set for higher level entities.
                        // In this example we are using the campaign level tracking template.
                        TrackingUrlTemplate = null,

                        // Set custom parameters that are specific to this ad,
                        // and can be used by the ad, ad group, campaign, or account level tracking template.
                        // In this example we are using the campaign level tracking template.
                        UrlCustomParameters = new CustomParameters {
                            Parameters = new[] {
                                new CustomParameter()
                                {
                                    Key   = "promoCode",
                                    Value = "PROMO3"
                                },
                                new CustomParameter()
                                {
                                    Key   = "season",
                                    Value = "summer"
                                },
                            }
                        },
                    },
                    new TextAd {
                        Title      = "",
                        Text       = "Huge Savings on red shoes.",
                        DisplayUrl = "Contoso.com",

                        // If you are currently using Destination URLs, you must replace them with Final URLs.
                        // Here is an example of a DestinationUrl you might have used previously.
                        // DestinationUrl = "http://www.contoso.com/womenshoesale/?season=spring&promocode=PROMO123",

                        // To migrate from DestinationUrl to FinalUrls for existing ads, you can set DestinationUrl
                        // to an empty string when updating the ad. If you are removing DestinationUrl,
                        // then FinalUrls is required.
                        // DestinationUrl = "",

                        // With FinalUrls you can separate the tracking template, custom parameters, and
                        // landing page URLs.
                        FinalUrls = new[] {
                            "http://www.contoso.com/womenshoesale"
                        },
                        // Final Mobile URLs can also be used if you want to direct the user to a different page
                        // for mobile devices.
                        FinalMobileUrls = new[] {
                            "http://mobile.contoso.com/womenshoesale"
                        },
                        // You could use a tracking template which would override the campaign level
                        // tracking template. Tracking templates defined for lower level entities
                        // override those set for higher level entities.
                        // In this example we are using the campaign level tracking template.
                        TrackingUrlTemplate = null,

                        // Set custom parameters that are specific to this ad,
                        // and can be used by the ad, ad group, campaign, or account level tracking template.
                        // In this example we are using the campaign level tracking template.
                        UrlCustomParameters = new CustomParameters {
                            Parameters = new[] {
                                new CustomParameter()
                                {
                                    Key   = "promoCode",
                                    Value = "PROMO4"
                                },
                                new CustomParameter()
                                {
                                    Key   = "season",
                                    Value = "summer"
                                },
                            }
                        },
                    },
                    new TextAd {
                        Title      = "Women's Super Shoe Sale",
                        Text       = "Huge Savings on red shoes.",
                        DisplayUrl = "Contoso.com",

                        // If you are currently using Destination URLs, you must replace them with Final URLs.
                        // Here is an example of a DestinationUrl you might have used previously.
                        // DestinationUrl = "http://www.contoso.com/womenshoesale/?season=spring&promocode=PROMO123",

                        // To migrate from DestinationUrl to FinalUrls for existing ads, you can set DestinationUrl
                        // to an empty string when updating the ad. If you are removing DestinationUrl,
                        // then FinalUrls is required.
                        // DestinationUrl = "",

                        // With FinalUrls you can separate the tracking template, custom parameters, and
                        // landing page URLs.
                        FinalUrls = new[] {
                            "http://www.contoso.com/womenshoesale"
                        },
                        // Final Mobile URLs can also be used if you want to direct the user to a different page
                        // for mobile devices.
                        FinalMobileUrls = new[] {
                            "http://mobile.contoso.com/womenshoesale"
                        },
                        // You could use a tracking template which would override the campaign level
                        // tracking template. Tracking templates defined for lower level entities
                        // override those set for higher level entities.
                        // In this example we are using the campaign level tracking template.
                        TrackingUrlTemplate = null,

                        // Set custom parameters that are specific to this ad,
                        // and can be used by the ad, ad group, campaign, or account level tracking template.
                        // In this example we are using the campaign level tracking template.
                        UrlCustomParameters = new CustomParameters {
                            Parameters = new[] {
                                new CustomParameter()
                                {
                                    Key   = "promoCode",
                                    Value = "PROMO5"
                                },
                                new CustomParameter()
                                {
                                    Key   = "season",
                                    Value = "summer"
                                },
                            }
                        },
                    },
                };

                // Add the campaign, ad group, keywords, and ads

                AddCampaignsResponse addCampaignsResponse = await AddCampaignsAsync(authorizationData.AccountId, campaigns);

                long?[]      campaignIds    = addCampaignsResponse.CampaignIds.ToArray();
                BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray();

                AddAdGroupsResponse addAdGroupsResponse = await AddAdGroupsAsync((long)campaignIds[0], adGroups);

                long?[]      adGroupIds    = addAdGroupsResponse.AdGroupIds.ToArray();
                BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray();

                AddKeywordsResponse addKeywordsResponse = await AddKeywordsAsync((long)adGroupIds[0], keywords);

                long?[]      keywordIds    = addKeywordsResponse.KeywordIds.ToArray();
                BatchError[] keywordErrors = addKeywordsResponse.PartialErrors.ToArray();

                AddAdsResponse addAdsResponse = await AddAdsAsync((long)adGroupIds[0], ads);

                long?[]      adIds    = addAdsResponse.AdIds.ToArray();
                BatchError[] adErrors = addAdsResponse.PartialErrors.ToArray();


                // Output the new assigned entity identifiers, as well as any partial errors

                OutputCampaignsWithPartialErrors(campaigns, campaignIds, campaignErrors);
                OutputAdGroupsWithPartialErrors(adGroups, adGroupIds, adGroupErrors);
                OutputKeywordsWithPartialErrors(keywords, keywordIds, keywordErrors);
                OutputAdsWithPartialErrors(ads, adIds, adErrors);

                // Here is a simple example that updates the campaign budget.

                var updateCampaign = new Campaign
                {
                    Id            = campaignIds[0],
                    MonthlyBudget = 500,
                };

                // As an exercise you can step through using the debugger and view the results.

                await GetCampaignsByIdsAsync(
                    authorizationData.AccountId,
                    new [] { (long)campaignIds[0] },
                    CampaignType.SearchAndContent | CampaignType.Shopping,
                    CampaignAdditionalField.BiddingScheme
                    );
                await UpdateCampaignsAsync(authorizationData.AccountId, new[] { updateCampaign });
                await GetCampaignsByIdsAsync(
                    authorizationData.AccountId,
                    new[] { (long)campaignIds[0] },
                    CampaignType.SearchAndContent | CampaignType.Shopping,
                    CampaignAdditionalField.BiddingScheme
                    );

                // Update the Text for the 3 successfully created ads, and update some UrlCustomParameters.
                var updateAds = new Ad[] {
                    new TextAd {
                        Id   = adIds[0],
                        Text = "Huge Savings on All Red Shoes.",
                        // Set the UrlCustomParameters element to null or empty to retain any
                        // existing custom parameters.
                        UrlCustomParameters = null,
                    },
                    new TextAd {
                        Id   = adIds[1],
                        Text = "Huge Savings on All Red Shoes.",
                        // To remove all custom parameters, set the Parameters element of the
                        // CustomParameters object to null or empty.
                        UrlCustomParameters = new CustomParameters {
                            Parameters = null,
                        },
                    },
                    new TextAd {
                        Id   = adIds[2],
                        Text = "Huge Savings on All Red Shoes.",
                        // To remove a subset of custom parameters, specify the custom parameters that
                        // you want to keep in the Parameters element of the CustomParameters object.
                        UrlCustomParameters = new CustomParameters {
                            Parameters = new[] {
                                new CustomParameter()
                                {
                                    Key   = "promoCode",
                                    Value = "updatedpromo"
                                },
                            }
                        }
                    },
                };

                // As an exercise you can step through using the debugger and view the results.

                await GetAdsByAdGroupIdAsync((long)adGroupIds[0]);

                var updateAdsResponse = await UpdateAdsAsync((long)adGroupIds[0], updateAds);
                await GetAdsByAdGroupIdAsync((long)adGroupIds[0]);


                // Here is a simple example that updates the keyword bid to use the ad group bid.

                var updateKeyword = new Keyword
                {
                    // Set Bid.Amount null (new empty Bid) to use the ad group bid.
                    // If the Bid property is null, your keyword bid will not be updated.
                    Bid = new Bid(),
                    Id  = keywordIds[1],
                };

                // As an exercise you can step through using the debugger and view the results.

                await GetKeywordsByAdGroupIdAsync((long)adGroupIds[0], KeywordAdditionalField.BiddingScheme);
                await UpdateKeywordsAsync((long)adGroupIds[0], new[] { updateKeyword });
                await GetKeywordsByAdGroupIdAsync((long)adGroupIds[0], KeywordAdditionalField.BiddingScheme);

                // Delete the campaign, ad group, keyword, and ad that were previously added.
                // You should remove this line if you want to view the added entities in the
                // Bing Ads web application or another tool.

                await DeleteCampaignsAsync(authorizationData.AccountId, new[] { (long)campaignIds[0] });

                OutputStatusMessage(String.Format("Deleted CampaignId {0}\n", campaignIds[0]));
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException <Microsoft.BingAds.V10.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V10.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException <Microsoft.BingAds.V10.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
        /// <summary>
        /// Initializes a new instance of this class with the specified <see cref="AuthorizationData"/>.
        /// </summary>
        /// <param name="authorizationData">Represents a user who intends to access the corresponding customer and account. </param>
        public ReportingServiceManager(AuthorizationData authorizationData)
        {
            if (authorizationData == null)
            {
                throw new ArgumentNullException("authorizationData");
            }

            _authorizationData = authorizationData;

            HttpService = new HttpService();

            ZipExtractor = new ZipExtractor();

            FileSystem = new FileSystem();

            StatusPollIntervalInMilliseconds = DefaultStatusPollIntervalInMilliseconds;

            WorkingDirectory = Path.Combine(Path.GetTempPath(), "BingAdsSDK", "Reporting");
        }
        /// <summary>
        /// Initializes a new instance of this class with the specified <see cref="AuthorizationData"/> and <paramref name="apiEnvironment"/>.
        /// </summary>
        /// <param name="authorizationData">Represents a user who intends to access the corresponding customer and account. </param>
        /// <param name="apiEnvironment">Bing Ads API environment</param>
        public ReportingServiceManager(AuthorizationData authorizationData, ApiEnvironment? apiEnvironment)
        {
            if (authorizationData == null)
            {
                throw new ArgumentNullException("authorizationData");
            }

            _authorizationData = authorizationData;

            HttpService = new HttpService();

            ZipExtractor = new ZipExtractor();

            FileSystem = new FileSystem();

            StatusPollIntervalInMilliseconds = DefaultStatusPollIntervalInMilliseconds;

            DownloadHttpTimeout = TimeSpan.FromMilliseconds(DefaultHttpClientTimeoutInMillseconds);

            WorkingDirectory = Path.Combine(Path.GetTempPath(), "BingAdsSDK", "Reporting");

            if (apiEnvironment != null) _apiEnvironment = apiEnvironment.Value;
        }