Profile Images in TFS 2012 - tfs

Is there a way to change users profile images as an administrator. At our company we have a central repository of everyone's images that we want to use on TFS Web Portal for their profiles. I know everyone can do it individually but can it be done globally for everyone?

TL/DR
I've submitted a patch to the ALM Rangers Team Tools Quick Response Sample which provides profile image functionality to any TFS Administrator.
The Details
Official answer: no. Not in the current version of the platform, it is being considered for a future release.
Real answer, it can be done with api trickery. It is still unsupported though. I'm working on a command line tool that does just that. I can probably share it after the holidays. Should you need it earlier, open the webaccess dll's in reflector.net and you'll be able to find the code in question.
The profile image is basically an extended property of the identity object of the user.
The important lines are:
_identity.SetProperty("Microsoft.TeamFoundation.Identity.Image.Data", imageData); /* byte[] containing 90x90px png */
_identity.SetProperty("Microsoft.TeamFoundation.Identity.Image.Type", "image/png");
_identity.SetProperty("Microsoft.TeamFoundation.Identity.Image.Id", Guid.NewGuid().ToByteArray());
_identity.SetProperty("Microsoft.TeamFoundation.Identity.CandidateImage.Data", null);
_identity.SetProperty("Microsoft.TeamFoundation.Identity.CandidateImage.UploadDate", null);
UpdateIdentity();
Code to update identity:
private static void UpdateIdentity()
{
try
{
_service.UpdateExtendedProperties(_identity);
_service.RefreshIdentity(_identity.Descriptor);
}
catch (PropertyServiceException)
{
//swallow;
}
}
Code to retrieve the identity service and identity:
var server = TfsConfigurationServerFactory.GetConfigurationServer(new Uri("http://localhost:8080/tfs"));
server.ClientCredentials = new TfsClientCredentials();
server.ClientCredentials = new TfsClientCredentials(new WindowsCredential(new NetworkCredential(connectUser, password)));
server.Authenticate();
_service = server.GetService<IIdentityManagementService2>();
var identities = _service.ReadIdentities(IdentitySearchFactor.AccountName,
new[] {userToSetImageOn}, MembershipQuery.None, ReadIdentityOptions.None);

Related

Working with Entity framework with Sitefinity and Portal Connector and Dynamic CRM

I'm working on a project that contains Dynamics CRM and Portal Connector which built upon Sitefinity.
There is a way to retrieve data inside Portal Connector from Dynamic CRM called Saved Query and this way generate a URL for you to retrieve data by HTTP request in front-end but I don't want to access it by the front end I want to access the Dynamics CRM by Backened, specifically by Entity framework, is it possible to connect to Dynamic CRM by Entity framework and retrieve the data by C# then send it to View?
My apologies for not coming across your post sooner.
A better way is to use the CRM connection provided by the Portal Connector. It essentially wraps the CRM SDK so calls you want make to the SDK can be made here and it uses the CRM connection configured in the site.
https://www.crmportalconnector.com/developer-network/documentation/developing-for-tpc/Dynamics-CRM-Connection-API
// Required usings
using System;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using pavliks.PortalConnector.Crm.Connection;
// The Code
// Create an instance of the connection manager
CrmConnectionManager manager = new CrmConnectionManager();
// Use the Connection property of the manager to access the
// configured CRM connection and create a new account
Guid newId = manager.Connection.Create(new Entity("account")
{
Attributes = new AttributeCollection()
{
{"name", "My Account Name"}
}
});
// Create Query Expression
QueryExpression query = new QueryExpression("account")
{
ColumnSet = new ColumnSet(true),
};
// Use manager to query CRM
EntityCollection entities = manager.Connection.RetrieveMultiple(query);
All the required assemblies are already in the Sitefinity site bin folder as they come with the Portal Connector assemblies and are copied to that location with the Portal Connector during installation. If your code is in another project, either reference the assemblies in the Sitefinity project or add them from the Portal Connector deploy package to your project.
I know it's a bit late but I hope it helps you in your next portal project.
let me answer my question, in case anyone wants to do a similar thing in the future :
1- first thing connect to Dynamic CRM is not related to Portal Connector, so the area that you should search in is Dynamic CRM.
2- To connect to Dynamic CRM you should follow the below steps :
2.1- install this package "Microsoft.CrmSdk.XrmTooling.CoreAssembly"
2.2- find what is your connection string.
2.3 use below code
var service=new CrmServiceClient("AuthType=Office365;Url=https://ititisdf.crm4.dynamics.com;Password=1234" )/*put your connection string instead*/
3- Some example of you could create or retrieved data
service.Create(new Entity("account"){["name]="Test connection"}); // add record
// retrive data
//1- query expression
//var query= new QueryExpression().Criteria. <===== from here you can add filteration ... and so on
//2- fetch xml expression
//var query=new FetchExpression(#"fetch xml value"); // you need to use XrmToolBox to generate your fetchXml
//3- var query=new QueryByAttribute("account");
// query.AddAttributeValue("name","Test1");
var entities=service.RetrieveMultiple(query).Entities;
foreach(var entity in entities)
{
entity["name"];
}
var organization=new OrganizationServiceContext(service);
// below code is under a concept called late-bound
var result=(from account in organization.CreateQuery("account")
join contact in organization.CreateQuery("contact")
on account["primarcontactid"] equals contact["contactid"]
where account["gendercode"] == "test" AND account["industrycode"]=1
select new {
Name=account["name"],
ContactName=contact["fullname"]
}).ToList();
// to implement Early bound
1- go to XrmToolBox ==> About ==> Plugin Store ==> Early Bound Generator==>Early Bound Generator Page will opened choose Entity to skip and choose which entity to want to include and which want to exclude
===> choose the path of generated .cs class that will represent you Entity in your project ===> press on Create Entities ===> now copy the generated file .
Now you have something like Entity framework :
Just use Entity name as a normal class :
var account = new Account{Name="Ahmed"};
and instead of this :
organization.CreateQuery("account")
use
organization.CreateQuery<yourEntityName>()
Actually, I got all of this information from youtube serious related to Dynamic, and here is the link
note: this serious in the Arabic language for this reason I summarised the steps in this answer to make it helpful for all.

Set and retrieve the Team Administrator in Team Foundation Server or VSTS

TFS 2012 and later as well as VSTS have a concept of a Team Administrator. I've looked all over the API for a simple way to set and retrieve the value through code to make it easier to provision these settings, but could not find it.
Reflectoring through the Server Object Model for the web UI gives hints for how to do it, but it relies on a number of private methods to get this done. Especially the part that calculates the Security Scope Token is hidden magic.
It took quite a bit of digging to find this old blogpost from 2013 which details how to do this, and I don't seem to be the only person who got stumped by the private methods. In the end they also ended up using Reflection to call the private method to retrieve the token:
This functionality is now available through the TFS Team Tools:
TFS Team Tools
Retrieve
Find the security group matching the team, use it to calculate the team's token, get the people who are part of that special security namespace:
public List<string> ListTeamAdministrators(string team, out string message)
{
// Retrieve the default team.
TeamFoundationTeam t = this.teamService.ReadTeam(this.projectInfo.Uri, team, null);
List<string> lst = null;
message = "";
if (t == null)
{
message = "Team [" + team + "] not found";
}
else
{
// Get security namespace for the project collection.
ISecurityService securityService = this.teamProjectCollection.GetService<ISecurityService>();
SecurityNamespace securityNamespace =
securityService.GetSecurityNamespace(FrameworkSecurity.IdentitiesNamespaceId);
// Use reflection to retrieve a security token for the team.
var token = GetTeamAdminstratorsToken(t);
// Retrieve an ACL object for all the team members.
var allMembers = t.GetMembers(this.teamProjectCollection, MembershipQuery.Expanded)
.ToArray();
AccessControlList acl =
securityNamespace.QueryAccessControlList(token, allMembers.Select(m => m.Descriptor), true);
// Retrieve the team administrator SIDs by querying the ACL entries.
var entries = acl.AccessControlEntries;
var admins = entries.Where(e => (e.Allow & 15) == 15).Select(e => e.Descriptor.Identifier);
// Finally, retrieve the actual TeamFoundationIdentity objects from the SIDs.
var adminIdentities = allMembers.Where(m => admins.Contains(m.Descriptor.Identifier));
lst = adminIdentities.Select(i => i.DisplayName).ToList();
}
return lst;
}
private static string GetTeamAdminstratorsToken(TeamFoundationTeam team)
{
return IdentityHelper.CreateSecurityToken(team.Identity);
}
Set
Setting works in a similar fashion. Grab the token and then add the users unique identifier to the Access Control List:
IdentityDescriptor descriptor = GetMemberDescriptor(memberId);
securityNamespace.SetPermissions(token, descriptor, 15, 0, false);
Remove
And removing a person from the list is then, of course, easy to guess;
IdentityDescriptor descriptor = GetMemberDescriptor(memberId);
securityNamespace.RemovePermissions(token, descriptor, 15);

Obtaining Information About Web Style Builds via the API

We are moving to the web style builds on TFS 2015 (Update 4).
I've always been able to retrieve information about builds using the code below, but that is not retrieving our new builds created via the web interface.
Is there a reasonable way to modify my code to bring in both legacy builds and the new style builds?
If not, I assume it is time for me to figure out how to use the REST API. Any tips for an equivalent query would be appreciated.
TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(new Uri("http://SERVERINFO"));
IBuildServer buildServer = (IBuildServer) tfs.GetService(typeof (IBuildServer));
var buildDetail = buildServer.CreateBuildDetailSpec("*");
buildDetail.MinFinishTime = DateTime.Now.Date.AddDays(-1);
buildDetail.InformationTypes = null;
buildDetail.QueryDeletedOption = QueryDeletedOption.IncludeDeleted;
buildDetail.MaxBuildsPerDefinition = 1; //Only return the most recent of each build type...or comment out to return all builds with this definition
var builds = buildServer.QueryBuilds(buildDetail).Builds.Select(....
The old XAML build system uses a SOAP API.The task-based new vNet build system does not have a SOAP API. It's using REST API. I'm afraid you could not just modify the code to get new builds. They do not support Build vNext as they were written before their time.
Besides the SOAP API is slowly being replaced with a REST API, especially in some new features.Since you are moving to vNext build on TFS2015 update4. Highly recommend you stat to use Rest API.
You can access it from C# code either by querying the REST API directly or by using the Team Foundation Server Client NuGet package. A Sample:
using System;
using System.Collections.Generic;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Build.WebApi;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Uri tfsurl = new Uri("http://xxxx:8080/tfs/CollectionName");
TfsTeamProjectCollection ttpc = new TfsTeamProjectCollection(tfsurl);
BuildHttpClient bhc = ttpc.GetClient<BuildHttpClient>();
List<Build> builds = bhc.GetBuildsAsync("ProjectName").Result;
foreach (Build bu in builds)
{
Console.WriteLine(bu.BuildNumber);
}
Console.ReadLine();
}
}
}
By using the Rest API in the libraries as above, you could be able to get both XAML and vNext builds.

How to remove the custom checkin policy while uninstalling?

I have a custom checkin policy written in c# and I used VSIX project with custom action enabled on install. Installation is working great. If I have the custom checkin policy applied to the team project in TFS 2010 and I uninstalled my policy from the same installer, it is cleaning up the registry and the files, but the source control still have the policy enabled and throws an error Error loading the policy. I want my installer to remove the policy from the source control while uninstalling the policy. How can I achieve this?
I tried to write the following code in OnAfterUninstall event, but it is not doing what I need:
protected override void OnAfterUninstall(IDictionary savedState)
{
base.OnAfterUninstall(savedState);
RemovePolicy();
}
private void RemovePolicy()
{
try
{
TfsTeamProjectCollection projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(projectCollectionUri, new UICredentialsProvider());
projectCollection.EnsureAuthenticated();
VersionControlServer vcs = projectCollection.GetService<VersionControlServer>();
List<TeamProject> lstTeamProject = vcs.GetAllTeamProjects(true).ToList<TeamProject>();
foreach (TeamProject tp in lstTeamProject)
{
List<PolicyEnvelope> tc = tp.GetCheckinPolicies().ToList<PolicyEnvelope>();
var myPolicy = new MyCustomCheckinPolicy();
TeamProject teamProject = vcs.GetTeamProject(tp.Name);
foreach (PolicyType policyType in Workstation.Current.InstalledPolicyTypes)
{
if (policyType.Name == myPolicy.Type)
{
tc.Remove(new PolicyEnvelope(myPolicy, policyType));
teamProject.SetCheckinPolicies(tc.ToArray());
break;
}
}
}
}
catch (Exception ex)
{
throw new InstallException("My Error Message");
}
}
Because a custom checkin policy needs to be installed on all developer workstations that access the TFS Project, having it deregister itself from the TFS Project upon uninstall will actually remove the policy whenever any of these developers uninstalls it. Which isn't what you want I suspect.
There are ways to ensure the policy is distributed to all team members through the Team Foundation Power Tools, that way, should you need to ship an upgrade or a different policy, you'll be sure all members have it. Only do the deregistration manually through the UI.

Sharepoint-Active Directory Profiles

I have written the following code to edit the User Profiles for MOSS 2007. User Profiles are being populated through the Active directory.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPSite sc = new SPSite("http://xxxxx:81");
ServerContext context = ServerContext.GetContext(sc);
HttpContext currentContext = HttpContext.Current;
HttpContext.Current = null;
UserProfileManager profileManager = new UserProfileManager(context);
foreach (UserProfile profile in profileManager)
{
if (profile[PropertyConstants.PreferredName].ToString().Contains("Domain\\"))
{
profile[PropertyConstants.PreferredName].ToString().Replace("Domain\\", "").ToString();
profile.Commit();
NoOfUser++;
}
}
The Details are being updated properly.
My question is Which site do I need to use, to update the details.
For Example I have SSP service WebApplication, Central Administration Web Application and Other Web Applications.
Which Site I need to use to update the profiles, So that the profile name gets updated in all the Sites.
Could Anybody point me in the right direction.
Thank You.
Hari Gillala
NHS Direct.
With sharepoint 2007, SPSite's belong to SPWebApplications, which are associated with an SSP, which store the user profile properties.
SPSite sc = new SPSite("http://xxxxx:81");
ServerContext context = ServerContext.GetContext(sc);
Those lines effectivity lookup the SSP associated with the SPSite url you pass in.
It looks like you only have one SSP, so any SPSite url you use in the constructor will give you a reference to the correct SSP.
Once the information is stored in the SSP database, a timer job copies the info from the SSP store to the individual SPSite databases, into a hidden list "User Information List"s.
This link explains it for 2010, let me see if i can find it for 2007:
http://www.harbar.net/articles/sp2010ups.aspx
EDIT
I found the 2007 explanation link for you:
http://blah.winsmarts.com/2007-7-MOSS_User_Profile_Info_-_How_the_information_flows.aspx

Resources