详细剖析TFS 2010中工作区的改进细节(组图)

开发 后端
我们利用全新的安全服务来做出这些变更,并且给一个工作区的用户设定了四种权限。这些权限分别是:Read, Use, CheckIn, 和Administer Use权限包括改变工作区的状态(它的定义,本地版本,冲突,或挂起的变更)的相关操作。

在TFS(Team Foundation Server) 2005和TFS(Team Foundation Server) 2008中,版本控制的工作区有如下限制。

1、工作区的所有者设置的创建时间不能被改变(具有恒定不变性)
2、一个工作区只能被它的所有者使用

当我们提到“使用”一个工作区的时候,可能意味着如下操作中的任何一个:

取消搁置到工作区中的搁置集
在一个工作区中做一次“获取”
在一个工作区中挂起变更或取消挂起变更
从一个工作区签入或搁置
在一个工作区中消除冲突
......

在TFS(Team Foundation Server)2010中,我们取消了这些限制。添加改变工作区的所有者的功能并不是很困难,但是,让工作区可以被所有者以外的人使用则需要我们把工作区变成完全安全的对象。我们利用全新的安全服务来做出这些变更,并且给一个工作区的用户设定了四种权限。这些权限分别是:Read, Use, CheckIn, 和Administer Use权限包括改变工作区的状态(它的定义,本地版本,冲突,或挂起的变更)的相关操作。你平时使用的大多数的操作都包括在Use权限里。你可以看看本文上面列出的那张关于“使用”的列表

我们把签入的权限单独分离出来了,那就是CheckIn权限。原因是在一些共享工作区的场景下,只有某个用户(比如:所有者)可以进行签入操作。一个用户需要Administer权限才能改变映射,名字,所有者,描述,或一个工作区所在的计算机。用户需要这个权限才能从这个系统中删除工作区,或变更这个工作区的访问控制列表。

Read权限也是一种权限,但是并不会发挥什么作用。从理论上来说,它包括查看一个现有的工作区的状态,例如:查看一个工作区的映射,查看一个工作区挂起的变更等。在TFS(Team Foundation Server)和TFS(Team Foundation Server) 2008中,任何一个合法的用户都可以查看任意一个工作区中的这些属性,TFS(Team Foundation Server) 2010并没有对这个行为做出变更。

使用Edit Workspace对话框改变工作区的权限

TFS(Team Foundation Server) 2010并没有为操作工作区的权限提供一个完整的UI。用户可以在三个“权限配置”中进行选择;一个“权限配置”实际上是一个工作区访问控制列表的模板。默认的“权限配置”是“Private workspace”。一个私有的工作区和TFS(Team Foundation Server) 2005和TFS(Team Foundation Server) 2008中的工作区据有相同的行为:这个工作区只可以被它的所有者使用。私有工作区的访问控制列表只有一个条目,那就是给所有者授予所有的权限——例如,John Smith:
YOURDOMAIN\johnsmith: Read, Use, CheckIn, Administer
 

我们提供的其他两个“权限配置”是:“Public-limited”和 “Public”。这两个“权限配置”也给所有者授予了所有权限。此外,它们还给任何一个合法的用户授予了附加的权限。对于“public-limited”权限配置来说,其他的用户被授予了在工作区上Read 和 Use的权限。对于一个完全公有的工作区来说,团队项目集合中的每一个合法用户都和所有者具有同样的权限:Read, Use, CheckIn, Administer。
 

在Visual Studio中使用一个公有的工作区

我们需要登录那个公有的工作区所在的机器。启动Visual Studio 2010,连接到公有的工作区所在的服务器以后,你可以在Source Control Explorer和Pending Changes工具窗口中的下拉组合框中看到这个工作区。
 

Visual Studio 2008或更早期的版本的用户不能看到属于其他用户的公有的工作区。他们只能看到他们自己的工作区
 

在这个例子中,我把共享的工作区设置成“Public-limited”的。你可以看到,因为我在这个工作区上缺乏Administer权限,所以我只能查看这个工作区的映射,所有者,描述和权限配置。一些控制都是只读的。
 

通过命令行(tf.exe)使用一个公有的工作区

还是一样,你需要登录那个公有的工作区所在的机器。如果你已经启动了Visual Studio 2010命令提示符,你可以cd到这个工作区的映射路径。在我的例子中,这个路径是D:\Proj。你可以看到我在下面试图运行一个命令,但是无法找到这个工作区。这是因为本地的工作区缓存文件是针对每个用户的,而这个用户从来没有意识到这个工作区存在问题。有两种方法可以解决这个问题:

1、马上启动Visual Studio,然后连接到团队项目集合,这会填充这个本地的工作区缓存。
2、运行“tf workspaces”来手动填充这个缓存文件,通过命令来实现。

我选择运行“tf workspaces”。我们可以看到属于其他用户的这个工作区被显示出来了,这说明我已经可以访问这个公有的工作区了。现在我的“tf get”命令成功了。
 

神奇的所有权

如果用户B搁置了用户A的工作区中的变更,那么用户B,是这个刚刚创建的搁置集的所有者。同样地,如果用户B签入了用户A的工作区中的变更,那么用户B会被标记为提交这些变更的用户。

挂起的特定变更并没有所有者——只有工作区才有所有者,如果用户A签出了用户B的工作区中的file.txt文件来编辑,那么,虽然用户A是挂起这个变更的人,但是一些UI组件还是会说明“file.txt”文件被用户B打开了,正在编辑。它还会更精确地说明在工作区X中被打开编辑的“file.txt ”文件是属于用户B的。

权限检查失败

TFS(Team Foundation Server) 2005/2008中的错误信息“TF14091:你不能在工作区{0}上执行这个操作,因为你不是这个工作区的所有者。”在TFS(Team Foundation Server)2010中已经不复存在了。取而代之,你会收到下面这条消息,它会指出这个操作需要哪个工作区的权限:

TF204017:这个操作不能被完成,因为用户({0}) 没有操作工作区{2}所必需的一个或多个权限。

在下面这个例子中,只是在这个命令被执行以前,把这个工作区切换成“Private”的了。
 

AdminWorkspaces全局性授权

从2005到2010,所有版本的(Team Foundation Server)都有一个全局性的授权,称为“Administer Workspaces”或简称为“AdminWorkspaces”。默认情况下,这个授权会被授予给团队项目集合的管理员们。即使他们原来没有Administer权限,拥有AdminWorkspaces授权的用户也可以自动地在这个系统的所有工作区上获得Administer权限。这个授权可以让管理员们清除系统中过时的工作区,并且可以在假期中收回属于员工的工作区所有权,或者收回不再属于这个团队的合同工的所有权。拥有AdminWorkspaces授权的用户可以代表其他用户创建工作区。
 

让我们回到前面那个例子上,在那个例子中,我的Edit Workspace对话框中有一些选项是锁定的,因为这个工作区是“Public-limited”,如果我拥有AdminWorkspaces授权,我们可以看到我现在可以完全访问这个对话框。我的有效权限是“Read, Use, Administer”。如果我想拥有“CheckIn”,我可以通过把这个工作区的权限配置变成“Public”来给自己授予这个权限。
 

自定义权限

虽然UI只提供了三个现成的权限模板,但是这个服务器支持在工作区上自定义访问控制列表。你可以使用安全服务和版本控制服务来查询完整的访问控制列表。工作区的security命名空间的GUID(Globally Unique Identifier:全局统一标识符)是一个众所周知的常数,并且,对于任意给定的工作区来说,在这个命名空间中,版本控制客户端对象模型会有一个标记,可以通过Workspace.SecurityToken属性来访问这个标记。下面的代码样例展示了如何提取和显示通过当前目录推断出的工作区的访问控制列表。

(这个代码样例需要引用MS.TeamFoundation.Common程序集,MS.TeamFoundation.Client程序集,MS.TeamFoundation.VersionControl.Common,程序集和MS.TeamFoundation.VersionControl.Client程序集。)

using Microsoft.TeamFoundation;

using Microsoft.TeamFoundation.Common;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.VersionControl.Common;
using Microsoft.TeamFoundation.VersionControl.Client;

// Use the current directory to infer the workspace and TFS team project collection.
WorkspaceInfo wi = Workstation.Current.GetLocalWorkspaceInfo(Environment.CurrentDirectory);
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(wi.ServerUri);
VersionControlServer vcs = tpc.GetService<VersionControlServer>();
Workspace workspace = vcs.GetWorkspace(wi);

// Get the identity service for the TPC.
IIdentityManagementService ims = tpc.GetService<IIdentityManagementService>();

// Get the security service for the TPC and use it to get the workspace security namespace.
ISecurityService security = tpc.GetService<ISecurityService>();
SecurityNamespace workspaceSecurityNamespace =
                       security.GetSecurityNamespace(SecurityConstants.WorkspaceSecurityNamespaceGuid);

// Get the access control list for the workspace, using the workspace's security token in the namespace.
AccessControlList acl = workspaceSecurityNamespace.QueryAccessControlList(workspace.SecurityToken,
                        null, false);

// Get the full TeamFoundationIdentity objects for the IdentityDescriptor of each access control entry.
List<IdentityDescriptor> descriptors = new List<IdentityDescriptor>();

foreach (AccessControlEntry ace in acl.AccessControlEntries)
    descriptors.Add(ace.Descriptor);

TeamFoundationIdentity[] identities = ims.ReadIdentities(descriptors.ToArray(), MembershipQuery.None,
                          ReadIdentityOptions.None);

// Display the access control list to the user.
Console.WriteLine("Access control list for " + workspace.DisplayName + Environment.NewLine);

int i = 0;

foreach (AccessControlEntry ace in acl.AccessControlEntries)
{
    if (null == identities[i])
        Console.WriteLine("  " + ace.Descriptor.Identifier + ":");
    else
        Console.WriteLine("  " + IdentityHelper.GetDomainUserName(identities[i]) + ":");

    if (0 != ace.Allow)
        Console.WriteLine("     Allow: " + ((WorkspacePermissions)ace.Allow).ToString());

    if (0 != ace.Deny)
        Console.WriteLine("     Deny: " + ((WorkspacePermissions)ace.Deny).ToString());

    i++;
}

回到我们的“public-limited”的工作区的例子,我们现在可以使用这些代码来观察这个工作区的完整访问控制列表了。
 

修改访问控制列表

我们可以对上面的代码做进一步的修改,来操作访问控制列表。让我们移除针对[Collection0]\Project Collection Valid Users的访问控制条目,然后使用只给REDMOND\vseqa1授予所有权限的条目来替换它。在这个工作区上执行这个操作需要Administer权限,当然,拥有AdminWorkspaces全局性授权的用户也可以做到。

// Use the current directory to infer the workspace and TFS team project collection.
WorkspaceInfo wi = Workstation.Current.GetLocalWorkspaceInfo(Environment.CurrentDirectory);
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(wi.ServerUri);
VersionControlServer vcs = tpc.GetService<VersionControlServer>();
Workspace workspace = vcs.GetWorkspace(wi);

// Get the security service for the TPC and use it to get the workspace security namespace.
ISecurityService security = tpc.GetService<ISecurityService>();
SecurityNamespace workspaceSecurityNamespace =
        security.GetSecurityNamespace(SecurityConstants.WorkspaceSecurityNamespaceGuid);

// Get the access control list for the workspace, using the workspace's security token in the namespace.
AccessControlList acl = workspaceSecurityNamespace.QueryAccessControlList(workspace.SecurityToken,
                           null, false);

WorkspacePermissions allWorkspacePermissions = WorkspacePermissions.Read | WorkspacePermissions.Use |
                                          WorkspacePermissions.CheckIn | WorkspacePermissions.Administer;

acl.RemoveAccessControlEntry(new IdentityDescriptor(IdentityConstants.TeamFoundationType,
                      GroupWellKnownSidConstants.EveryoneGroupSid));
acl.SetAccessControlEntry(new AccessControlEntry(tpc.AuthorizedIdentity.Descriptor,
                                 (int)allWorkspacePermissions, 0), false);

workspaceSecurityNamespace.SetAccessControlList(acl);

运行这些代码以后,我可以看到这个工作区的访问控制列表只有两个条目——一个是针对这个工作区的所有者的,另外一个是针对我的(REDMOND\vseqa1)。
 

因为这个工作区的访问控制列表不再和预定义的“权限配置”(模板)匹配了,所以在Edit Workspace对话框中,这个“权限配置”显示成了“Custom permissions”。
 

如果你把这个工作区的permissions组合框设置成了“Custom permissions”,那么你无需重写这个自定义的访问控制列表,就可以改变这个工作区的任何一个属性了。但是如果你以后想切换回预定义的“权限配置”,只要在这个组合框中选择相应的“权限配置”,然后点击“OK”就可以了。你的自定义访问控制列表将会被消除和替换。如果我(所有者)不小心删除了自己的ACE,会发生什么呢?

即使在安全服务的访问控制列表中不存在所有者的ACE,版本控制权限检查也会成功的。版本控制服务知道你是这个工作区的所有者,并且,也知道你拥有全部的权限。在所有者的ACE恢复以前,你无法通过安全服务更改访问控制列表。要恢复所有者的ACE,你可以打开Edit Workspace对话框,然后随便做一些改变(例如:改变描述)。当你点击OK的时候,在服务器上,这个工作区会被更新,所有者的ACE将会被恢复。
 

责任编辑:马沛 来源: 51CTO.com
相关推荐

2010-11-02 13:45:52

TFS2010VS2010微软

2009-12-03 15:35:26

2009-03-09 09:12:32

路由交换机交换能力

2010-02-24 15:04:54

Visual Stud

2009-04-07 08:55:08

Firefox火狐浏览器

2010-05-06 17:56:15

Visual Stud

2010-05-14 10:13:46

Office Mobi

2010-03-01 09:16:22

Visual Stud

2010-03-11 16:29:28

Visual Stud

2010-06-01 13:32:15

Visual Stud

2012-06-21 09:34:18

Windows Pho

2010-11-11 08:37:48

TFS2010

2018-08-09 15:45:39

AndroidGoogle 移动系统

2009-09-18 09:14:49

SharePoint细

2009-11-24 09:00:02

Visual Stud

2010-10-08 14:48:32

TFSVisual Stud

2010-05-25 09:48:37

Office2010微软

2009-11-03 09:21:26

Visual Stud

2011-06-10 09:10:50

2021-05-31 06:21:03

PythonPython 3.3编程语言
点赞
收藏

51CTO技术栈公众号