How to retrieve ZipCode from UserProfileManager in SharePoint 2010? - c#

I need to know how I can retrieve the ZipCode from Active Directory. Currently, I can get the User and Department but I can't retrieve ZipCode.
In the docs I can't see the ZipCode as a property:
This is my code in C#:
using(SPSite site = new SPSite("Server"))
{
site.AllowUnsafeUpdates = true;
SPServiceContext context = SPServiceContext.GetContext(site);
UserProfileManager upm = new UserProfileManager(context);
UserProfile profile = upm.GetUserProfile(GetNodeValue("xPath"));
String department = profile[PropertyConstants.Department].Value.ToString();
String position = profile[PropertyConstants.Title].Value.ToString();
String zipCode = profile[PropertyConstants.?????].Value.ToString();
}

You need to manually map this in the User Profile Service Application first.
Properties can be added in Central Administration -> Manage Service Application - > User profile service application -> Manage User Properties -> Add User Profile Property -> Choose the Zip Code Attribute.
Now you can run another sync, each user should have this property mapped. You can then access it like you are doing but with the string name you assigned :
String zipCode = profile["SPS-ZipCode"].Value.ToString();

Related

Insert permission for users inside sharedDrive

I want to add members inside specific shared drive (Team drive).
i have tried with inserting permission request as below:
var listPermisssion = new List<TeamDrivePermissionDetailsData>() { };
TeamDrivePermissionDetailsData permission = new TeamDrivePermissionDetailsData()
{
Role = role,
TeamDrivePermissionType ="member" ,
};
listPermisssion.Add(permission);
Permission tdrivePermission = new Permission();
tdrivePermission.EmailAddress = who;
tdrivePermission.TeamDrivePermissionDetails = listPermisssion;
var requestPermission = service.Permissions.Create(tdrivePermission, sharedDriveId);
requestPermission.Execute();
i got this error :
Error:'Google.Apis.Requests.RequestError
The permission role field is required. [400]
thnks for the help.
The method Permissions:create requires the specification of role and type as described in the documentation
member is not a valid option for type - it should be one of the following options:
user
group
domain
anyone
role expects one of the following options:
owner
organizer
fileOrganizer
writer
commenter
reader

Role-based Security Authorization in web froms using Identity 2.0

I've seen not hundred but THOUSANDS of example where from scratch to complete examples with MVC identity 2.0 are done but not a single one with bloody web forms and the one which are present are not even worth while just very basic.
I'm working on an application where I've three roles, user,admin,superUser and all these are in AspNetRoles table because I'm using identity 2.0. now when I create a user I also assign that user one of these roles too.
before this role and stuff I've worked on customize roles system as we use to do on desktop applications.
so here I tried all the links and articles written on CodeProject about form authentication and all that what we can do in web.config but nothing was helpful
Please take a look at this screen shot http://prntscr.com/6ca09i you might get a little idea what I mean by that.
My C# code on register is
protected void btnSubmit_Click(object sender, EventArgs e)
{
//owin entity
var userStore = new UserStore<IdentityUser>();
userStore.Context.Database.Connection.ConnectionString =
System.Configuration.ConfigurationManager
.ConnectionStrings["GCR"].ConnectionString;
var manager = new UserManager<IdentityUser>(userStore);
//string userInfor;// = new UserInformation();
// check if the url contains an id perameter
if (!String.IsNullOrWhiteSpace(Request.QueryString["id"]))
{
var id = Convert.ToInt32(Request.QueryString["id"]);
var userInfo = new UserInformation
{
Email = txtEmail.Text,
FirstName = txtFirstName.Text,
LastName = txtLastName.Text,
AddressLine1 = txtAddressLine1.Text,
AddressLine2 = txtAddressLine2.Text,
City = txtCity.Text,
State = ddlState.SelectedValue,
ZipCode = Convert.ToInt32(txtZip.Text),
PhoneNumber = txtPhone.Text,
RoleId = Convert.ToInt32(ddlRole.SelectedValue)
and here is my registration page where I am assigning the roles which are not actually getting assigned http://prntscr.com/6ca1xi
Now please tell me how can I create role based app where in a single folder we have different files which User with different role can get access
Please I'd already wasted my two days on Identity I have no wich to waste more time on it
This is how you are going to properly deal with this
var userInfo = new UserInformation
{
Email = txtEmail.Text,
FirstName = txtFirstName.Text,
LastName = txtLastName.Text,
AddressLine1 = txtAddressLine1.Text,
AddressLine2 = txtAddressLine2.Text,
City = txtCity.Text,
State = ddlState.SelectedValue,
ZipCode = Convert.ToInt32(txtZip.Text),
PhoneNumber = txtPhone.Text,
RoleId = ddlRole.SelectedValue
Fist your role should be some text value because it does not take role as id
after saving this object or model above `db.saveChanges();
you in the end are going to add this role to aspnetroles table and how you are going to do that is very simple just a single line
// add role to the user which is created right now
manager.AddToRole(userInfo.GUID, ddlRole.Text.Trim());
The first argument is the id of the user and the second one is the dropdown in which you are selecting the user roles and you can also do that role exist stuff in it. now how you are going to check this one page load is very simple
and its just like this
#region page load
if (!IsPostBack)
{
if (User.IsInRole("admin") || User.IsInRole("superuser"))
{
}
else
{
string unAuthorizedRedirect = WebConfigurationManager.AppSettings["UnAuthorizedRedirect"];
Response.Redirect("~/" + unAuthorizedRedirect);
}
}
#endregion
I hope this helps you completely
I got the roles from aspnetroles table and this is how I got those
var context = new ApplicationDbContext();
var roleStore = new RoleStore<IdentityRole>(context);
var roleMgr = new RoleManager<IdentityRole>(roleStore);
if (User.IsInRole("admin"))
{
//come here
}

outlook contact can't get SMTP address, No MAPI properties on "exchange" contact list

is it a bug in outlook?
i've created a local Contact list card, and i gave him in the address field an exchange user address. (double click on that address, see that its exchange).
when i try to get the address using MAPI - i can't, the problem is this, when i check the AddressEntry object, i get the following:
Type = "EX"
Address = "/o=.../ou=Exchange..."/cn=Recipients/cn=Name
Class = olAddressEntry
AddressEntryUserType = olOutlookContactAddressEntry
when i checked in OutlookSpy - no MAPI properties, so i can't get PR_SMTP_ADDRESS nor PR_EMS_AB_PROXY_ADDRESSES, also, this is not SMTP so i have no valid address.
i checked other users and those are the properties (which it works):
Real exchange user recipient, same email address as the exchange one, but it was created without autocorrect to the exchange user, so it stays smtp:
Type = "SMTP"
Address = "Email#email.com"
Class = olAddressEntry
AddressEntryUserType = olExchangeUserAddressEntry
Regular address entry
Type = "EX"
Address = "/o=.../ou=Exchange..."/cn=Recipients/cn=Name
Class = olAddressEntry
AddressEntryUserType = olOutlookContactAddressEntry
if i double click on the "exchange" local contact, it opens exchange window of its properties, if i open the "regular one i created manually", it opens the "SMTP" address window.
any workaround i can do?
thanks.
It didn't work in way "Dmitry Streblechenko" suggested because for some reason
ContactItem.Email1EntryId, ContactItem.Email2EntryId and ContactItem.Email3EntryId contains not id but some wrong random data (even some html tags) - office 2016.
But it finally worked with following code
using (var pa = new InteropWrapper<Outlook.PropertyAccessor>(contact.innerObject.PropertyAccessor))
{
String EMAIL1_ENTRYID = "http://schemas.microsoft.com/mapi/id/{00062004-0000-0000-C000-000000000046}/80850102";
string emailEntryID = pa.innerObject.BinaryToString(pa.innerObject.GetProperty(EMAIL1_ENTRYID));
using (var rs = new InteropWrapper<Outlook.NameSpace>(Globals.ThisAddIn.Application.Session))
{
rs.innerObject.Logon();
using (var addressEntry = new InteropWrapper<Outlook.AddressEntry>(rs.innerObject.GetAddressEntryFromID(emailEntryID)))
using (var exchangeUser = new InteropWrapper<Outlook.ExchangeUser>(addressEntry.innerObject.GetExchangeUser()))
{
return exchangeUser.innerObject.PrimarySmtpAddress;
}
}
}
where InteropWrapper<T> just IDisposable wrapper around com object - it does Marshal.ReleaseComObject(innerObject) on dispose. So you can do everything without it by using Marshal.ReleaseComObject() directly.
just in case if someone need email 2 and email 3 including them here
String EMAIL2_ENTRYID = "http://schemas.microsoft.com/mapi/id/{00062004-0000-0000-C000-000000000046}/80950102";
String EMAIL3_ENTRYID = "http://schemas.microsoft.com/mapi/id/{00062004-0000-0000-C000-000000000046}/80A50102";
Hope it will save someones time! I've spent like a day on it.
If you have an EX type contact, use the value of the ContactItem.Email1EntryId property to call Namespace,GetAddressEntryFromId, then read the AddressEntry.GetExchangeUser.PrimarySmtpAddress property.

Getting a Random User using UserProfileManager

I'm trying to create a "Who is" web part for a SharePoint 2010 project i'm working on.
This web part is supposed to select a random user from SharePoint profiles and display his/her name, department and phone.
The problem is that i couldn't find a way to get a random user directly from the User Profiles, which is what i'd like to do.
I found a way to do it:
SPServiceContext myContext = SPServiceContext.GetContext(mySite);
SPWeb myWeb = SPContext.Current.Web;
UserProfileManager profileManager = new UserProfileManager(myContext);
bool boolOut;
SPPrincipalInfo[] userInfos = SPUtility.GetPrincipalsInGroup(myWeb, "AllUsers", profileManager.Count, out boolOut);
Random random = new Random();
int randomUser = random.Next(0, userInfos.Length);
SPPrincipalInfo user = userInfos[randomUser];
bool userFound = false;
while(!userFound)
{
if (profileManager.UserExists(user.LoginName))
{
UserProfile userProfile = profileManager.GetUserProfile(user.LoginName);
userDepartment = Convert.ToString(userProfile[PropertyConstants.Department].Value);
userPicture = Convert.ToString(UserProfile[PropertyConstants.PictureUrl].Value);
userFound = true;
}
}
This way i did it could be a problem because the site would have 2k+ users, that's why i'd like to know if it's possible to do this directly from the User Profiles.
I'm new to SharePoint and it still a little confusing to me.
Thanks for your help.
I'm curious why the need for it to be a "random" user. I would suggest using the OOB functionality around suggested colleagues, and your web part could expose this information instead.

I have a SID of a user account, and I want the SIDs of the groups it belongs to

This has to be obtained from a remote machine. The following query works not for SIDs, but for group and account names.
"SELECT GroupComponent FROM Win32_GroupUser WHERE PartComponent = \"Win32_UserAccount.Domain='" + accountDomain + "',Name='" + accountName + "'\""
The Win32_Group objects it returns come in the forms of strings, and they only have domain and name (even though Win32_Group has a SID property).
I have this sinking feeling I'll have to:
Turn the SID into an account name by querying Win32_SID;
Perform the query above;
Turn each of the resulting group names into SIDs by querying Win32_Group.
Can you use the System.DirectoryServices.AccountManagement namespace classes?
using (var context = new PrincipalContext( ContextType.Domain ))
{
using (var user = UserPrincipal.FindByIdentity( context, accountName ))
{
var groups = user.GetAuthorizationGroups();
...iterate through groups and find SIDs for each one
}
}
It should work with ContextType.Machine, though you'd need to specify the machine name and have appropriate privileges.
using (var context = new PrincipalContext( ContextType.Machine,
"MyComputer",
userid,
password ))
{
...
}
There's a nice MSDN article (longish, though) on using the new .NET 3.5 account management namespace.
Yes there is but some methods depend on having a domain.
See this page for how to convert a SID
to a user id using P/Invoke and the Windows API, or with .NET 2.0+ and no P/Invoke.
using System.Security.Principal;
// convert the user sid to a domain\name
string account = new SecurityIdentifier(stringSid).Translate(typeof(NTAccount)).ToString();
If you have AD and
the user id in there then use the DirectorySearcher
method or Account Management APIs to find the groups.
Otherwise use the method outlined in
this article to get local
groups.
Now use the API suggested by #tvanfosson to iterate the groups and get the SIDs. Or follow the info below.
In an ASP.NET application it is possible to use code like this to access group info provided a user is authenticated by Windows and not Forms authentication. In this example I've left an interesting note about exceptions that are thrown in that environment but it may apply to other users:
public List<string> GetGroupsFromLogonUserIdentity()
{
List<string> groups = new List<string>();
HttpRequest request = HttpContext.Current.Request;
if (request.LogonUserIdentity.Groups != null)
{
foreach (IdentityReference group in request.LogonUserIdentity.Groups)
{
try
{
groups.Add(group.Translate(typeof(NTAccount)).ToString());
}
catch (IdentityNotMappedException)
{
// Swallow these exceptions without throwing an error. They are
// the result of dead objects in AD which are associated with
// user accounts. In this application users may have a group
// name associated with their AD profile which cannot be
// resolved in the Active Directory.
}
}
}
return groups;
}
LogonUserIdentity is based on the WindowsIdentity class. You could modify my code sample to use WindowsIdentity and function in a non-Web application. Once you iterate over a group you should be able to do something like this to get the SecurityIdentifier:
SecurityIdentifier secid = group as SecurityIdentifier;

Categories