зеркало из
1
0
Форкнуть 0

Refactor repo to open up room for quickstarts and other samples

This commit is contained in:
Will Smythe 2017-07-11 08:40:25 -04:00
Родитель 15a0aead89
Коммит 8b9d2d64dd
73 изменённых файлов: 944 добавлений и 83 удалений

Просмотреть файл

@ -0,0 +1,3 @@
# Quickstarts
Self-contained programs demonstrating a specific scenario, typically by calling multiple APIs.

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 14 KiB

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Просмотреть файл

@ -0,0 +1,88 @@
# Team Services client library snippets
This folder contains C# samples that show how to integrate with Team Services and Team Foundation Server using our [public client libraries](https://www.nuget.org/profiles/nugetvss). Most samples are short snippets that call just a single API.
You can use these snippets to jumpstart your own apps and services.
## Explore
Samples are organized by "area" (service) and "resource" within the `Microsoft.TeamServices.Samples.Client` project. Each sample class shows various ways for interacting with Team Services and Team Foundation Server.
## Run the samples
1. Clone this repository and open in Visual Studio (2015 or later)
2. Build the solution (you may need to restore the required NuGet packages first)
3. Run the `Microsoft.TeamServices.Samples.Client.Runner` project with the required arguments:
* `/url:{value}`: URL of the account/collection to run the samples against.
* `/area:{value}`: API area (work, wit, notification, git, core, build) to run the client samples for. Use * to include all areas.
* `/resource:{value}`: API resource to run the client samples for. Use * to include all resources.
> **IMPORTANT**: some samples are destructive. It is recommended that you run these samples against a test account.
### Examples of how to run different samples
#### Run all samples
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://fabrikam.visualstudio.com /area:* /resource:*
```
#### Run all work item tracking samples
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://fabrikam.visualstudio.com /area:wit /resource:*
```
#### Run all graph samples against vsts
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://fabrikam.vssps.visualstudio.com /area:graph /resource:*
```
#### Run all Git pull request samples
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://fabrikam.visualstudio.com /area:git /resource:pullrequests
```
#### Run all samples against a TFS on-premises collection
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://mytfs:8080/tfs/testcollection /area:git /resource:*
```
### Save request and response data to a JSON file
To persist the HTTP request/response as JSON for each client sample method that is run, set the `/outputPath:{value}` argument. For example:
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://fabrikam.visualstudio.com /area:* /resource:* /outputPath:c:\temp\http-output
```
This creates a folder for each area, a folder for each resource under the area folder, and a file for each client sample method that was run. The name of the JSON file is determined by the name of the client sample method. For example:
```
|-- temp
|-- http-output
|-- Notification
|-- EventTypes
|-- ...
|-- Subscriptions
|-- CreateSubscriptionForUser.json
|-- QuerySubscriptionsByEventType.json
|-- ...
```
Note: certain HTTP headers like `Authorization` are removed for security/privacy purposes.
## Contribute
For developers that want to contribute, learn how to [contribute a snippet sample](./contribute.md).

Просмотреть файл

148
README.md
Просмотреть файл

@ -1,100 +1,82 @@
# Team Services Samples for .NET
# .NET samples for Visual Studio Team Services
![buildstatus](https://mseng.visualstudio.com/_apis/public/build/definitions/b924d696-3eae-4116-8443-9a18392d8544/5045/badge)
[![buildstatus](https://mseng.visualstudio.com/_apis/public/build/definitions/b924d696-3eae-4116-8443-9a18392d8544/5045/badge)](https://mseng.visualstudio.com/VSOnline/Open%20ALM/_build/index?context=mine&path=%5C&definitionId=5045&_a=completed)
This repository contains C# samples that show how to integrate with Team Services and Team Foundation Server using our [public client libraries](https://www.nuget.org/profiles/nugetvss).
This repository contains C# samples that show how to integrate with Team Services and Team Foundation Server using our [public client libraries](https://www.nuget.org/profiles/nugetvss), service hooks, and more.
## Explore
## Explore the samples
Samples are organized by "area" (service) and "resource" within the `Microsoft.TeamServices.Samples.Client` project. Each sample class shows various ways for interacting with Team Services and Team Foundation Server.
Take a minute to explore the repo. It contains short snippets as well as longer examples that demonstrate how to integrate with Team Services and Team Foundation
## Run the samples
* **Snippets**: short reusable code blocks demonstrating how to call specific APIs.
* **Quickstarts**: self-contained programs demonstrating a specific scenario, typically by calling multiple APIs.
1. Clone this repository and open in Visual Studio (2015 or later)
## About the official client libraries
2. Build the solution (you may need to restore the required NuGet packages first)
For .NET developers, the primary (and highly recommended) way to integrate with Team Services and Team Foundation Server is via our public .NET client libraries available on Nuget. [Microsoft.TeamFoundationServer.Client](https://www.nuget.org/packages/Microsoft.TeamFoundationServer.Client) is the most popular Nuget package and contains clients for interacting with work item tracking, Git, version control, build, release management and other services.
3. Run the `Microsoft.TeamServices.Samples.Client.Runner` project with the required arguments:
* `/url:{value}`: URL of the account/collection to run the samples against.
* `/area:{value}`: API area (work, wit, notification, git, core, build) to run the client samples for. Use * to include all areas.
* `/resource:{value}`: API resource to run the client samples for. Use * to include all resources.
See the [Team Services client library documentation](https://www.visualstudio.com/docs/integrate/get-started/client-libraries/dotnet) for more details.
> **IMPORTANT**: some samples are destructive. It is recommended that you first run the samples against a test account.
### Sample console program
### Examples
Simple console program that connects to Team Services using a personal access token and displays the field values of a work item.
#### Run all samples
```cs
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using System;
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://fabrikam.visualstudio.com /area:* /resource:*
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 3)
{
Uri accountUri = new Uri(args[0]); // Account URL, for example: https://fabrikam.visualstudio.com
String personalAccessToken = args[1]; // See https://www.visualstudio.com/docs/integrate/get-started/authentication/pats
int workItemId = int.Parse(args[2]); // ID of a work item, for example: 12
// Create a connection to the account
VssConnection connection = new VssConnection(accountUri, new VssBasicCredential(string.Empty, personalAccessToken));
// Get an instance of the work item tracking client
WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
try
{
// Get the specified work item
WorkItem workitem = witClient.GetWorkItemAsync(workItemId).Result;
// Output the work item's field values
foreach (var field in workitem.Fields)
{
Console.WriteLine(" {0}: {1}", field.Key, field.Value);
}
}
catch (AggregateException aex)
{
VssServiceException vssex = aex.InnerException as VssServiceException;
if (vssex != null)
{
Console.WriteLine(vssex.Message);
}
}
}
else
{
Console.WriteLine("Usage: ConsoleApp {accountUri} {personalAccessToken} {workItemId}");
}
}
}
}
```
#### Run all work item tracking samples
## Request other samples
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://fabrikam.visualstudio.com /area:wit /resource:*
```
Not finding a sample that demonstrates something you are trying to do? Let us know by opening an issue.
#### Run all graph samples against vsts
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://fabrikam.vssps.visualstudio.com /area:graph /resource:*
```
#### Run all Git pull request samples
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://fabrikam.visualstudio.com /area:git /resource:pullrequests
```
#### Run all samples against a TFS on-premises collection
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://mytfs:8080/tfs/testcollection /area:git /resource:*
```
### Save request and response data to a JSON file
To persist the HTTP request/response as JSON for each client sample method that is run, set the `/outputPath:{value}` argument. For example:
```
Microsoft.TeamServices.Samples.Client.Runner.exe
/url:https://fabrikam.visualstudio.com /area:* /resource:* /outputPath:c:\temp\http-output
```
This creates a folder for each area, a folder for each resource under the area folder, and a file for each client sample method that was run. The name of the JSON file is determined by the name of the client sample method. For example:
```
|-- temp
|-- http-output
|-- Notification
|-- EventTypes
|-- ...
|-- Subscriptions
|-- CreateSubscriptionForUser.json
|-- QuerySubscriptionsByEventType.json
|-- ...
```
Note: certain HTTP headers like `Authorization` are removed for security/privacy purposes.
## About the client libraries
For .NET developers building Windows apps and services that integrate with Visual Studio Team Services, client libraries are available for integrating with work item tracking, version control, build, and other services are now available. These packages replace the traditional TFS Client OM installer and make it easy to acquire and redistribute the libraries needed by your app or service.
See [.NET client libraries for Team Services documentation](https://www.visualstudio.com/docs/integrate/get-started/client-libraries/dotnet) for more getting started details.
### Other useful resources
* [Official NuGet packages](https://www.nuget.org/profiles/nugetvss)
* [.NET Client library intro](https://www.visualstudio.com/docs/integrate/get-started/client-libraries/dotnet)
* [WIQL reference](https://msdn.microsoft.com/en-us/library/bb130198(v=vs.90).aspx)
## Contribute
For developers that want to contribute, learn how to [contribute a sample](./contribute.md).

63
ServiceHooks/Utilities/Permissions/.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

245
ServiceHooks/Utilities/Permissions/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,245 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
[Xx]64/
[Xx]86/
[Bb]uild/
bld/
[Bb]in/
[Oo]bj/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Un-comment the next line if you do not want to checkin
# your web deploy settings because they may include unencrypted
# passwords
#*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Microsoft Azure ApplicationInsights config file
ApplicationInsights.config
# Windows Store app package directory
AppPackages/
BundleArtifacts/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# LightSwitch generated files
GeneratedArtifacts/
ModelManifest.xml
# Paket dependency manager
.paket/paket.exe
# FAKE - F# Make
.fake/

Просмотреть файл

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<system.serviceModel>
<extensions>
<!-- In this extension section we are introducing all known service bus extensions. User can remove the ones they don't need. -->
<behaviorExtensions>
<add name="connectionStatusBehavior" type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="serviceRegistrySettings" type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</behaviorExtensions>
<bindingElementExtensions>
<add name="netMessagingTransport" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="tcpRelayTransport" type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="httpRelayTransport" type="Microsoft.ServiceBus.Configuration.HttpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="httpsRelayTransport" type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="onewayRelayTransport" type="Microsoft.ServiceBus.Configuration.RelayedOnewayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingElementExtensions>
<bindingExtensions>
<add name="basicHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="webHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="ws2007HttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netTcpRelayBinding" type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netOnewayRelayBinding" type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netEventRelayBinding" type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
</system.serviceModel><appSettings>
<!-- Service Bus specific app setings for messaging connections -->
<add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://[your namespace].servicebus.windows.net;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=[your secret]" />
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.22.0.0" newVersion="2.22.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Просмотреть файл

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E449C3C1-8272-4781-A658-DDA4A3682A44}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.TeamServices.Samples.ServiceHooks</RootNamespace>
<AssemblyName>Microsoft.TeamServices.Samples.ServiceHooks</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject>Microsoft.TeamServices.Samples.ServiceHooks.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=2.22.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms, Version=2.22.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ServiceBus, Version=2.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\WindowsAzure.ServiceBus.2.5.1.0\lib\net40-full\Microsoft.ServiceBus.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.TeamFoundation.Client, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.TeamFoundationServer.ExtendedClient.14.102.0\lib\net45\Microsoft.TeamFoundation.Client.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.TeamFoundation.Common, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.VisualStudio.Services.Client.14.102.0\lib\net45\Microsoft.TeamFoundation.Common.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.TeamFoundation.Core.WebApi, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.TeamFoundationServer.Client.14.102.0\lib\net45\Microsoft.TeamFoundation.Core.WebApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Services.Client, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.VisualStudio.Services.InteractiveClient.14.102.0\lib\net45\Microsoft.VisualStudio.Services.Client.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Services.Common, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.VisualStudio.Services.Client.14.102.0\lib\net45\Microsoft.VisualStudio.Services.Common.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Services.WebApi, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.VisualStudio.Services.Client.14.102.0\lib\net45\Microsoft.VisualStudio.Services.WebApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration, Version=1.7.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.WindowsAzure.ConfigurationManager.1.7.0.0\lib\net35-full\Microsoft.WindowsAzure.Configuration.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\System.IdentityModel.Tokens.Jwt.4.0.0\lib\net45\System.IdentityModel.Tokens.Jwt.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="RestrictPermissionsToOneGroup.cs" />
<Compile Include="RestoreManagePermissionsToProjectAdminGroups.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Program.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="packages\Microsoft.TeamFoundationServer.ExtendedClient.14.102.0\build\Microsoft.TeamFoundationServer.ExtendedClient.targets" Condition="Exists('packages\Microsoft.TeamFoundationServer.ExtendedClient.14.102.0\build\Microsoft.TeamFoundationServer.ExtendedClient.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\Microsoft.TeamFoundationServer.ExtendedClient.14.102.0\build\Microsoft.TeamFoundationServer.ExtendedClient.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.TeamFoundationServer.ExtendedClient.14.102.0\build\Microsoft.TeamFoundationServer.ExtendedClient.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26223.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.TeamServices.Samples.ServiceHooks", "Microsoft.TeamServices.Samples.ServiceHooks.csproj", "{E449C3C1-8272-4781-A658-DDA4A3682A44}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E449C3C1-8272-4781-A658-DDA4A3682A44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E449C3C1-8272-4781-A658-DDA4A3682A44}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E449C3C1-8272-4781-A658-DDA4A3682A44}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E449C3C1-8272-4781-A658-DDA4A3682A44}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.TeamServices.Samples.ServiceHooks
{
public class Program
{
static void Main(string[] args)
{
string command = (args.Length > 0 ? args[0] : null);
if (command == null || args.Length < 2)
{
Console.WriteLine("Usage: Microsoft.TeamServices.Samples.ServiceHooks [command] [collection URL]");
}
else if (String.Equals(command, "restore", StringComparison.InvariantCultureIgnoreCase))
{
RestoreManagePermissionsToProjectAdminGroups r = new RestoreManagePermissionsToProjectAdminGroups();
r.Run(new Uri(args[1]));
}
else if(String.Equals(command, "restrict", StringComparison.InvariantCultureIgnoreCase))
{
RestrictPermissionsToOneGroup r = new RestrictPermissionsToOneGroup();
r.Run(new Uri(args[1]));
}
}
}
}

Просмотреть файл

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Microsoft.TeamServices.Samples.ServiceHooks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Visual Studio Team Services")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e449c3c1-8272-4781-a658-dda4a3682a44")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Core.WebApi;
using Microsoft.TeamFoundation.Framework.Common;
namespace Microsoft.TeamServices.Samples.ServiceHooks
{
public class RestoreManagePermissionsToProjectAdminGroups
{
private static readonly Guid ServiceHooksSecurityNamespaceId = new Guid("cb594ebe-87dd-4fc9-ac2c-6a10a4c92046");
public void Run(Uri collectionUri)
{
Console.WriteLine("Utility to restore Service Hooks manage permissions to the project administrator group");
Console.WriteLine("");
if (collectionUri != null)
{
TfsTeamProjectCollection connection = new TfsTeamProjectCollection(collectionUri);
// Get Core, security, and identity services
ISecurityService securityService = connection.GetService<ISecurityService>();
SecurityNamespace hooksSecurity = securityService.GetSecurityNamespace(ServiceHooksSecurityNamespaceId);
IIdentityManagementService2 identityService = connection.GetService<IIdentityManagementService2>();
ProjectHttpClient projectClient = connection.GetClient<ProjectHttpClient>();
IEnumerable<TeamProjectReference> projects = projectClient.GetProjects(stateFilter: Microsoft.TeamFoundation.Common.ProjectState.WellFormed).Result;
// Iterate over each project, check SH permissions, and grant if needed
foreach (var project in projects)
{
Console.WriteLine(String.Format("Project {0} ({1})", project.Name, project.Id));
var groups = identityService.ListApplicationGroups(project.Id.ToString(), ReadIdentityOptions.None, null, Microsoft.TeamFoundation.Framework.Common.IdentityPropertyScope.Both);
String adminGroupName = String.Format("vstfs:///Classification/TeamProject/{0}\\Project Administrators", project.Id);
try
{
TeamFoundationIdentity adminGroup = groups.First(g => String.Equals(g.UniqueName, adminGroupName, StringComparison.InvariantCultureIgnoreCase));
Console.WriteLine(" - Checking Project Administrators group permissions");
AccessControlEntry ace = new AccessControlEntry(adminGroup.Descriptor, 7, 0); // 7 = view, create, delete
String securityToken = "PublisherSecurity/" + project.Id;
bool hasPermission = hooksSecurity.HasPermission(securityToken, adminGroup.Descriptor, 7, false);
if (!hasPermission)
{
Console.WriteLine(" - Missing. Granting...");
hooksSecurity.SetAccessControlEntry(securityToken, ace, true);
// check permission again after granting
hasPermission = hooksSecurity.HasPermission(securityToken, adminGroup.Descriptor, 7, false);
if (hasPermission)
{
Console.WriteLine(" - Granted");
}
else
{
Console.WriteLine(" - Still does not have permission. Check to make sure it has not been explicitly denied.");
}
}
else
{
Console.WriteLine(" - Already has permission");
}
}
catch (Exception ex)
{
Console.WriteLine(String.Format("Admin group: Not found! ({0})", ex.Message));
}
Console.WriteLine("");
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Core.WebApi;
using Microsoft.TeamFoundation.Framework.Common;
namespace Microsoft.TeamServices.Samples.ServiceHooks
{
public class RestrictPermissionsToOneGroup
{
private static readonly Guid ServiceHooksSecurityNamespaceId = new Guid("cb594ebe-87dd-4fc9-ac2c-6a10a4c92046");
private static Int32 ManagePermissions = 7; // view, create, delete
private static Int32 ViewPermissions = 1; // view
private static readonly string SpecialGroupName = "Service Hooks Administrators"; // assumed to be a collection-level group containing people that will have management permissions for SH in each project
public void Run(Uri collectionUri)
{
Console.WriteLine("Utility to remove Service Hooks management permissions from the Project Administrators groups.");
Console.WriteLine("");
Console.WriteLine(" All projects in account/collection: " + collectionUri);
Console.WriteLine("");
Console.WriteLine("WARNING! This operation will remove the permissions.\n\n Are you sure you want to continue (Y/N)?");
int confirmChar = Console.In.Read();
if (confirmChar != 'y' || confirmChar != 'Y')
{
return;
}
if (collectionUri != null)
{
TfsTeamProjectCollection connection = new TfsTeamProjectCollection(collectionUri);
// Get Core, security, and identity services
ISecurityService securityService = connection.GetService<ISecurityService>();
SecurityNamespace hooksSecurity = securityService.GetSecurityNamespace(ServiceHooksSecurityNamespaceId);
IIdentityManagementService2 identityService = connection.GetService<IIdentityManagementService2>();
ProjectHttpClient projectClient = connection.GetClient<ProjectHttpClient>();
IEnumerable<TeamProjectReference> projects = projectClient.GetProjects(stateFilter: Microsoft.TeamFoundation.Common.ProjectState.WellFormed).Result;
// Iterate over each project, check SH permissions, and remove if the project administrators group has access
foreach (var project in projects)
{
// Remove manage permissions from the project's administrators group (but leave it "view" access)
Console.WriteLine(String.Format("Project {0} ({1})", project.Name, project.Id));
var groups = identityService.ListApplicationGroups(project.Id.ToString(), ReadIdentityOptions.None, null, Microsoft.TeamFoundation.Framework.Common.IdentityPropertyScope.Both);
String adminGroupName = String.Format("vstfs:///Classification/TeamProject/{0}\\Project Administrators", project.Id);
try
{
TeamFoundationIdentity adminGroup = groups.First(g => String.Equals(g.UniqueName, adminGroupName, StringComparison.InvariantCultureIgnoreCase));
Console.WriteLine(" - Checking Project Administrators group permissions");
String securityToken = "PublisherSecurity/" + project.Id;
bool hasPermission = hooksSecurity.HasPermission(securityToken, adminGroup.Descriptor, ManagePermissions, false);
// Project admin group has "manage" permissions for SH in the project
if (hasPermission)
{
// Remove manage permissions from the project's administrators group (but leave it "view" access)
Console.WriteLine(" - Has permissions. Removing...");
// Give the admin group only view permissions
hooksSecurity.SetPermissions(securityToken, adminGroup.Descriptor, ViewPermissions, 0, false);
// check permission again after granting
hasPermission = hooksSecurity.HasPermission(securityToken, adminGroup.Descriptor, ManagePermissions, false);
if (!hasPermission)
{
Console.WriteLine(" - Verified permissions correctly removed.");
}
else
{
Console.WriteLine(" - Project Administrators Group still has manage permissions.");
}
}
else
{
Console.WriteLine(" - Does not have permissions to manage service hook subscriptions.");
}
}
catch (Exception ex)
{
Console.WriteLine(String.Format("Admin group: Not found! ({0})", ex.Message));
}
Console.WriteLine("");
}
// Grant the group manage permissions across the entire collection
TeamFoundationIdentity specialGroup = identityService.ReadIdentity(IdentitySearchFactor.DisplayName, SpecialGroupName, MembershipQuery.None, ReadIdentityOptions.None);
if (specialGroup != null)
{
Console.WriteLine("Granting full manage permissions to: {0}", specialGroup.UniqueName);
String rootSecurityToken = "PublisherSecurity/";
hooksSecurity.SetPermissions(rootSecurityToken, specialGroup.Descriptor, ManagePermissions, 0, false);
}
else
{
Console.WriteLine("Could not find this group.");
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.2" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.2" targetFramework="net452" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="2.22.302111727" targetFramework="net452" />
<package id="Microsoft.TeamFoundationServer.Client" version="14.102.0" targetFramework="net452" />
<package id="Microsoft.TeamFoundationServer.ExtendedClient" version="14.102.0" targetFramework="net452" />
<package id="Microsoft.VisualStudio.Services.Client" version="14.102.0" targetFramework="net452" />
<package id="Microsoft.VisualStudio.Services.InteractiveClient" version="14.102.0" targetFramework="net452" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="1.7.0.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net452" />
<package id="System.IdentityModel.Tokens.Jwt" version="4.0.0" targetFramework="net452" />
<package id="WindowsAzure.ServiceBus" version="2.5.1.0" targetFramework="net452" />
</packages>