故事时间到了!我们的一位比较不满的员工决定在他最后一天的前一天升级可视化svn并修改我们的网络界面。我们设置了旧的身份验证,一切都很好。在我们遵循的大计划中,给出这个特定的应用程序足迹:“如果它没有损坏,就不要修复它”。
它没坏,他修好了.
所以我们到了。我找到了关于与Visual与C#进行接口的这个问题,看起来他只是逐字复制和粘贴代码。
我们拥有的界面非常简单。有一个输入框,用户输入的名称为那里所需的回购。下面是一个文本区域,他/她可以在其中添加用户以访问回购。用户查找是基于电子邮件地址完成的,它会访问我们的活动目录。最终的结果是,我有我需要创建的repo的名称,以及我需要给予读/写访问权限的人的用户/SID。
通过测试他粘贴的代码,存储库似乎正在被创建得很好(当我以管理员身份登录到服务器时,它们就会显示出来)。以下是回购创建代码:
static public bool CreateRepository(repository r)
{
ManagementClass repoClass = new ManagementClass("root\\VisualSVN", "VisualSVN_Repository", null);
// Obtain in-parameters for the method
ManagementBaseObject inParams = repoClass.GetMethodParameters("Create");
// Add the input parameters.
inParams["Name"] = r.name;
// Execute the method and obtain the return values.
ManagementBaseObject outParams =
repoClass.InvokeMethod("Create", inParams, null);
return true;
}方法参数中的“存储库r”是一个具有以下属性的类:
private int _id;
private string _name;
private System.Nullable<System.DateTime> _deleteAfter;
private EntitySet<UserRepositoryRight> _UserRepositoryRights;对于所有的公共getter和setter,您都期望从linq到sql生成的文件。UserRepositoryRight是一个表,它保存对许多(用户)关系的一个(回购)关系。
就像我说的,我认为这段代码很好,因为我看到了正在创建的存储库。
下一个copypasta代码是UpdatePermissions方法
static public void UpdatePermissions(string sid, string repository, AccessLevel level, bool isAdmin = false)
{
//Update SVN
ManagementClass userClass = new ManagementClass("root\\VisualSVN", "VisualSVN_WindowsAccount", null);
ManagementClass permClass = new ManagementClass("root\\VisualSVN", "VisualSVN_PermissionEntry", null);
ManagementClass repoClass = new ManagementClass("root\\VisualSVN", "VisualSVN_Repository", null);
ManagementObject userObject = userClass.CreateInstance();
userObject.SetPropertyValue("SID", sid);
ManagementObject permObject = permClass.CreateInstance();
permObject.SetPropertyValue("Account", userObject);
permObject.SetPropertyValue("AccessLevel", level);
ManagementObject repoObject = repoClass.CreateInstance();
repoObject.SetPropertyValue("Name", repository);
ManagementBaseObject inParams =
repoClass.GetMethodParameters("SetSecurity");
inParams["Path"] = "/trunk";
inParams["Permissions"] = new object[] { permObject };
ManagementBaseObject outParams =
repoObject.InvokeMethod("SetSecurity", inParams, null);
//Update in DB
var db = new DataMapSVNServiceDataContext();
if (level == AccessLevel.NoAccess) //If we are removing the user
{
var output = (db.repositories.Single(r => r.name == repository)).UserRepositoryRights.Single(u => u.User.Sid == sid);
if (output.isAdmin != null && !((bool)output.isAdmin)) //making sure DB owner isn't ever removed
db.UserRepositoryRights.DeleteOnSubmit(output);
}
if (level == AccessLevel.ReadWrite) //if we are adding the user
{
var add = new UserRepositoryRight
{
isAdmin = isAdmin,
User = db.Users.Single(u => u.Sid == sid),
repository = db.repositories.Single(r => r.name == repository)
};
db.UserRepositoryRights.InsertOnSubmit(add);
}
db.SubmitChanges();
}在这里,一切看起来都很好,但似乎并没有转移到回购和添加用户拥有ReadWrite (键值为2)对创建的回购权限。该方法的尾部只需将数据保存到我们的网站数据库中,就可以与其进行接口。
所以,根本的问题是,如果我在这里通过网络界面创建一个回购,在尝试访问它时,我会得到一个403个禁止的错误,但是在创建和删除它时没有错误。有人能指出我的正确方向吗?
发布于 2013-11-29 11:28:39
您应该使用 VisualSVN服务器PowerShell cmdlet,而不是使用服务器的WMI提供程序。VisualSVN服务器的WMI可以看作是一个内部API。它没有文档化,也不打算用于构建自定义应用程序。
旧答案
如果在运行代码时没有任何错误,我猜访问规则设置在path <repo>/trunk上,这在最年轻的版本中根本不存在。您可以在某个新的测试存储库上尝试脚本,该库在根中包含"/trunk“。否则,只需将代码字符串inParams["Path"] = "/trunk";更改为inParams["Path"] = "/";即可。
VisualSVN服务器允许您在最年轻版本中不存在的项(文件和文件夹)上设置基于路径的授权规则,因为这些项可以存在于较早版本和更新版本中。
https://stackoverflow.com/questions/20049722
复制相似问题