I have been breaking my head over this. Please take a look at this code. This code is in the customer controller.
[HttpPost]
[Themed]
public ActionResult Register(string email, string password, string confirmPassword, Gender gender, string givenName, string familyName, string insertion, DateTime birthDate) {
ViewData["PasswordLength"] = MinPasswordLength;
var shape = _orchardServices.New.Register();
//1. Initialize new content of customer contenttype
var customer = _orchardServices.ContentManager.New("Customer");
if (customer != null) {
//2. Define the parts that need to be filled
var userPart = customer.As<UserPart>();
var customerPart = customer.As<CustomerPart>();
//3. Let's validate first if the user can be created
if (userPart!=null) {
//shape.Customer = _orchardServices.ContentManager.UpdateEditor(customer, this);
if (!ModelState.IsValid)
{
_orchardServices.TransactionManager.Cancel();
return new ShapeResult(this, shape);
}
//4. Now validate the user credentials.
if (ValidateRegistration(email, password, confirmPassword)) {
//Now create the actual customer.
userPart.UserName = email;
userPart.Email = email;
userPart.NormalizedUserName = email.ToLowerInvariant();
userPart.Record.HashAlgorithm = "SHA1";
userPart.Record.RegistrationStatus = UserStatus.Approved;
userPart.Record.EmailStatus = UserStatus.Approved;
customerPart.CreatedAt = DateTime.UtcNow;
customerPart.LastLogonAt = DateTime.UtcNow;
_membershipService.SetPassword(userPart, password);
var user = customerPart.User;
_authenticationService.SignIn(user, false /* createPersistentCookie */);
return Redirect("~/");
}
}
}
When this code is run, I end up with two entries for UserPart in my database. One with a related CustomerPart and one not.
Related
I’m testing document signing via a Docusign template through the Docusign API. Once the document signing is complete, each recipient is supposed to receive a Document completed notification, with the link to view the document. But the Document completion Notification is not sent to each recipient as expected, when signing process is initiated using the DocuSign API. Please direct me to the help link on this.
I also, would like to know how to set up the certificate completion document to be sent to each recipient on completion of signing. Any help on above is appreciated.
Thanks
I am seeing you are setting clientUserId for all types of signers except Vendor roles. Now setting clientUserId for the signer tells DocuSign that you are implementing embedded signing in your app. As its an embedded signing, so by Default and Design, DocuSign does not send any types of email notification to the embedded signer. To make DocuSign send the completion email with Certification of Completion, you need to modify Signing Settings in your DocuSign Account. In your DS Account, Go To Admin -> Select Signing Settings from the Left Hand Side Navigation under SIGNING AND SENDING section. Then, scroll to the bottom on Signing Settings page to Envelope Delivery section as shown in below screenshot, select Send Completion emails to embedded signers and also select Attach Certificate of completion to envelope. This should resolve your issue.
Please find below the code for creating and sending envelope and initiating signing for the Agent and Purchaser roles.
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult Create(CreateContractViewModel viewModel)
{
if (!ModelState.IsValid)
return Json(new { success = false, errors=ModelStateExtensions.GetErrors(ViewData.ModelState.Values) }, JsonRequestBehavior.AllowGet);
try
{
#region "Validation"
if (viewModel.Purchasers == null) //only allow max. of 2 purchasers at this point in time.
return Json(new { success = false, errors = "Minimum of one Purchaser is required." },
JsonRequestBehavior.AllowGet);
if (viewModel.Purchasers.Count > 2) //only allow max. of 2 purchasers at this point in time.
return Json(new { success = false, errors = "Number of Purchasers allowed exceed." },
JsonRequestBehavior.AllowGet);
#endregion
// Get template based on drop down selection.
var envTemplate = Templates.Get(viewModel.SelectTemplateId);
// Assign all parties. eg. recipients, signers, and CCs
var docusignRecipients = envTemplate.Recipients;
var signers = docusignRecipients.Signers;
var carbonCopies = docusignRecipients.CarbonCopies;
var templateRolesList = new List<TemplateRole>();
if (viewModel.Purchasers.Count == 1) //remove Purchaser 2 if there's only 1 Purchaser needed.
{
var remove = signers.SingleOrDefault(x => x.RoleName.Equals(RoleNames.Purchaser_2));
if (remove != null)
signers.Remove(remove);
}
// Minimum of 1 Purchaser must exist.
var purchaser1 = viewModel.Purchasers[0];
var purchaser2 = viewModel.Purchasers.Count > 1
? viewModel.Purchasers[1]
: new Purchaser();
#region "Setup Template Roles"
// Recipients
var envelopeRecipients = new Recipients
{
RecipientCount = docusignRecipients.RecipientCount,
Signers = new List<Signer>(),
CarbonCopies = new List<CarbonCopy>()
};
// Signers
TemplateRoles.Signers.AddRoles(viewModel, signers, purchaser1, purchaser2, envelopeRecipients,
docusignRecipients);
// Carbon Copies
TemplateRoles.CarbonCopies.AddRoles(carbonCopies, envelopeRecipients, docusignRecipients);
#endregion
#region "Prepare & Create Envelope"
// Server template
var serverTemplates = new List<ServerTemplate>
{
new ServerTemplate
{
Sequence = "1",
TemplateId = viewModel.SelectTemplateId
}
};
// Server inline template
var serverInlineTemplates = new List<InlineTemplate>
{
new InlineTemplate
{
Sequence = "2",
Recipients = envelopeRecipients
}
};
// refactor this part to a new method.
var documentFactory = new DocumentFactory(viewModel.SelectTemplateId, _documentService);
var type = viewModel.OptionalInserts.GetType();
var optionalInserts = type.GetProperties();
var templateList = new List<CompositeTemplate>();
foreach (var insert in optionalInserts)
{
var value = insert.GetValue(viewModel.OptionalInserts);
var isChecked = (bool)value;
if (!isChecked) continue;
var template = documentFactory.GetTemplate(insert.Name);
var compositeTemplate = template.Compose();
templateList.Add(compositeTemplate);
}
// Prepare composite template, combining the Server and Inline templates
var compositeTemplates = new List<CompositeTemplate>
{
new CompositeTemplate
{
ServerTemplates = serverTemplates,
InlineTemplates = serverInlineTemplates
}
};
templateList.ForEach(t => compositeTemplates.Add(t));
// Create Envelope Definition
var envDef = Envelopes.CreateEnvDef(envTemplate, compositeTemplates);
// Create Envelope
var envSummary = Envelopes.CreateEnvelope(envDef);
#endregion
#region "Generate View Url"
// Generate recipient Url - Agent as 1st recipient by default
var agent = envelopeRecipients.Signers.SingleOrDefault(x => x.RoleName.Equals(RoleNames.Agent));
if (agent == null)
return
Json(
new
{
success = false,
errors = "No Agent role has been found.",
JsonRequestBehavior.AllowGet
});
var returnUrl = Url.Action("Sign", "Contract",
new { envelopeId = envSummary.EnvelopeId, routingOrder = agent.RoutingOrder, selectedTemplateId = viewModel.SelectTemplateId });//modified on 15-6-2017
// Get View Options.
var viewOptions = DocuSign.Recipients.ViewRequest(returnUrl, agent.ClientUserId, agent.Name, agent.Email);
// Create Recipient View
var view = Envelopes.CreateRecipientView(envSummary.EnvelopeId, viewOptions);
#endregion
return Json(new { success = true, returnUrl = view.Url, JsonRequestBehavior.AllowGet });
}
catch (Exception e)
{
return Json(new
{
success = false,
errors = e.Message,
JsonRequestBehavior.AllowGet
});
}
}
public ActionResult Sign(CreateContractViewModel viewModel)
//public ActionResult Sign() //previous code
{
var paramEvent = Request.QueryString["event"];
var paramEnvId = Request.QueryString["envelopeId"];
var paramRoutingOrder = Request.QueryString["routingOrder"];
var selectedTemplateId = Request.QueryString["selectedTemplateId"];
var contractIdQueryString = Request.QueryString["contractId"];
// Validation
if (string.IsNullOrEmpty(paramEvent) || string.IsNullOrEmpty(paramEnvId) ||
string.IsNullOrEmpty(paramRoutingOrder) || (paramEvent != SigningStatus.Signing_Complete))
return View("Error");
// Get next Signer
var recipients = Envelopes.ListRecipients(paramEnvId);
var signers = recipients.Signers;
///////addded on 25/5/2017 to check docusign value extraction
//var cfe = Envelopes.ListRecipientsWithTags(paramEnvId);
//Envelopes.ListCustomFields(paramEnvId);
//List<TextCustomField> tcfList = cfe.TextCustomFields;
//foreach (var tcf in tcfList)
//{
// string dfd = tcf.FieldId;
// string ddfdfd = tcf.Name;
// string sdf = tcf.Value;
// //string str = cfe.TextCustomFields[0].FieldId;
//}
//EnvelopesApi envelopesApi = new EnvelopesApi();
//CustomFieldsEnvelope cfe = envelopesApi.ListCustomFields(accountId, _templateId2);
//TemplateCustomFields cfUpdate = new TemplateCustomFields();
//cfUpdate.TextCustomFields = new System.Collections.Generic.List<TextCustomField>();
//TextCustomField tcf = new TextCustomField();
//tcf.FieldId = cfe.TextCustomFields[0].FieldId;
// Get template based on drop down selection.
//var envTemplate = Templates.Get(viewModel.SelectTemplateId);
//// Assign all parties. eg. recipients, signers, and CCs
//var docusignRecipients = envTemplate.Recipients;
//var signers1 = docusignRecipients.Signers;
int ContractId = 0;
if (contractIdQueryString != null && contractIdQueryString !="")
{
ContractId = int.Parse(contractIdQueryString.Trim());
}
ContractId= GetTabs(signers, selectedTemplateId, paramRoutingOrder, ContractId);
/////
//note:ClientUserId is made null only for the Vendor role in TemplateRoles.Signers.AddRoles method, so that
//signing continues for the Agent and Purchaser roles only
var nextSigner = (from s in signers
where
!string.IsNullOrEmpty(s.ClientUserId) &&
(Convert.ToInt32(s.RoutingOrder) > Convert.ToInt32(paramRoutingOrder))
orderby s.RoutingOrder
select s).FirstOrDefault();
//added following on 06/06/2018 to prevent workflow from proceeding to the next signers. But this will prevent capturing signed dates by signers
//if( paramEvent == "signing_complete" && paramRoutingOrder == "1")
// {
// return View("Completed");
// }
// return View("Completed");
//
#region Code that proceeds workflow to the next signer. Need to have an option to allow agent to go for following approach which allows purchaser to sign via the application or, another option that allows purchaser to receive an email notification for completing signing as done in above commented code
// No next Signer redirect to Completed page.
if (nextSigner == null) return View("Completed");
//var returnUrl = Url.Action("Sign", "Contract",
// new
// {
// envelopeId = paramEnvId,
// routingOrder = nextSigner.RoutingOrder,
// recipientId = nextSigner.RecipientId
// });//original code
var returnUrl = Url.Action("Sign", "Contract",
new
{
envelopeId = paramEnvId,
routingOrder = nextSigner.RoutingOrder,
recipientId = nextSigner.RecipientId,
selectedTemplateId = selectedTemplateId,
contractId = ContractId
});//modified on 19-6-2017
// Get View Options.
var viewOptions = DocuSign.Recipients.ViewRequest(returnUrl, nextSigner.ClientUserId, nextSigner.Name,
nextSigner.Email);
// Create Recipient View
var view = Envelopes.CreateRecipientView(paramEnvId, viewOptions);
return Redirect(view.Url);
#endregion
}
public static class TemplateRoles
{
public static class Signers
{
public static void AddRoles(CreateContractViewModel viewModel, List<Signer> signers, Purchaser purchaser1, Purchaser purchaser2,
global::DocuSign.eSign.Model.Recipients r, global::DocuSign.eSign.Model.Recipients recipients)
{
try
{
foreach (var signer in signers)
{
switch (signer.RoleName)
{
default:
throw new Exception("Unknown Signer role was found on the template.");
region "Role: Agent"
case RoleNames.Agent:
// Fill all Sign tabs for Agent role, which includes Purchaser fields.
// Agent role is the first point of the draft, therefore all the fields need to be prefilled.
var signerTabs = signer.Tabs;
if (signerTabs != null)
{
if (signerTabs.TextTabs != null)
{
var signerTextTabs = signerTabs.TextTabs;
DocuSign.Tabs.Sign(viewModel, signerTextTabs, purchaser1, purchaser2);
}
if (signerTabs.CheckboxTabs != null)
{
var signerCheckboxTabs = signerTabs.CheckboxTabs;
DocuSign.Tabs.SignCheckBoxes(viewModel, signerCheckboxTabs, purchaser1, purchaser2);//Assigning check box values
}
}
var agentSigner = recipients.Signers.Find(x => x.RoleName == "Agent");
if (agentSigner != null)
{
var s = new Signer();
s = agentSigner;
s.RoleName = signer.RoleName;
s.Name = signer.Name;
s.Email = signer.Email;
s.RoutingOrder = signer.RoutingOrder;
s.ClientUserId = Guid.NewGuid().ToString();
s.Tabs = signerTabs;
r.Signers.Add(s);
}
break;
#endregion
#region "Role: Purchaser 1"
case RoleNames.Purchaser_1:
var purchaserSigner = recipients.Signers.Find(x => x.RoleName == "Purchaser 1");
if (purchaserSigner != null)
{
var p1 = new Signer();
p1 = purchaserSigner;
p1.RoleName = RoleNames.Purchaser_1;
p1.Name =
(!string.IsNullOrEmpty(purchaser1.CompanyName)
? purchaser1.CompanyName
: $"{purchaser1.FirstName} {purchaser1.Surname}");
p1.Email = (!string.IsNullOrEmpty(purchaser1.Email) ? purchaser1.Email : null);
p1.RoutingOrder = signer.RoutingOrder;
p1.ClientUserId = Guid.NewGuid().ToString();
p1.Tabs = signer.Tabs;
r.Signers.Add(p1);
}
break;
#endregion
#region "Role: Purchaser 2"
case RoleNames.Purchaser_2:
var purchaser2Signer = recipients.Signers.Find(x => x.RoleName == "Purchaser 2");
if (purchaser2Signer != null)
{
var p2 = new Signer();
p2 = purchaser2Signer;
p2.RoleName = RoleNames.Purchaser_2;
p2.Name =
(!string.IsNullOrEmpty(purchaser2.CompanyName)
? purchaser2.CompanyName
: $"{purchaser2.FirstName} {purchaser2.Surname}");
p2.Email = (!string.IsNullOrEmpty(purchaser2.Email) ? purchaser2.Email : null);
p2.RoutingOrder = signer.RoutingOrder;
p2.ClientUserId = Guid.NewGuid().ToString();
p2.Tabs = signer.Tabs;
r.Signers.Add(p2);
}
break;
#endregion
#region "Role: Vendor"
case RoleNames.Vendor: // No embedded signing.
var vendorSigner = recipients.Signers.Find(x => x.RoleName == "Vendor");
if (vendorSigner != null)
{
var v = new Signer();
v = vendorSigner;
v.RoleName = signer.RoleName;
v.Name = signer.Name;
v.Email = signer.Email;
v.RoutingOrder = signer.RoutingOrder;
v.ClientUserId = null;
r.Signers.Add(v);
}
break;
#endregion
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
As it says in the title I have already assigned claims to the registered user, I am now trying to retrieve the claim value when the user logs into the application within the UserClaims table in sql server which I find a bit difficult to do as this is my first time using claims.
Looking for directions on our to achieve this, thank you in advance.
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email, UserRoleId = model.RoleId };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created a new account with password.");
await addUserClaims(model.CusomterId, model.UserName);
return RedirectToLocal(returnUrl);
}
AddErrors(result);
}
List<UserRole> roles = _userRoleRepo.GetAll();
model.CreateRoleList(roles);
List<Customer> customers = await _customerRepository.GetAll();
model.SetupCustomerOptionList(customers);
// If we got this far, something failed, redisplay form
return View(model);
}
private async Task addUserClaims(string CustomerID ,string username)
{
// Customer customer = _customerRepository.GetById(customerid);
List<Customer> customers = await _customerRepository.GetAll();
Customer customer = _customerRepository.GetById(CustomerID);
var user = await _userManager.FindByNameAsync(username);
;
await _userManager.AddClaimAsync(user, new Claim(ClaimTypes.Name, CustomerID));
}
Set
var claims = new List<Claim>
{
new Claim("Currency", "PKR")
};
Get
#User.Claims.FirstOrDefault(c => c.Type == "Currency").Value
Very easy
public static class IdentityExtension
{
public static string GetId(this IIdentity identity)
{
ClaimsIdentity claimsIdentity = identity as ClaimsIdentity;
Claim claim = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier);
return claim.Value;
}
}
Example
User.Identity.GetId();
We are trying to use the O365 Unified API to send emails from our line-of-business apps. I use the following code to send the email. This throws a DataServiceQueryException exception "Unauthorized".
public async Task SendEmailAsUserAsync(EmailMessage message)
{
try
{
var graphClient = await _authenticationHelper.GetGraphClientAsync();
Message m = InitializeMessage(message);
await graphClient.Me.SendMailAsync(m, true);
}
catch (DataServiceQueryException dsqe)
{
_logger.Error("Could not get files: " + dsqe.InnerException.Message, dsqe);
throw;
}
}
private static Message InitializeMessage(EmailMessage message)
{
ItemBody body = new ItemBody {Content = message.Body, ContentType = BodyType.HTML};
Message m = new Message
{
Body = body,
Subject = message.Subject,
Importance = Importance.Normal,
};
//Add all the to email ids
if (message.ToRecipients != null)
foreach (Models.Messaging.EmailAddress emailAddress in message.ToRecipients)
{
m.ToRecipients.Add(new Recipient { EmailAddress = new Microsoft.Graph.EmailAddress { Address = emailAddress.Address, Name = emailAddress.Name } });
}
return m;
}
The code for _authenticationHelper.GetGraphClientAsync() is
public async Task<GraphService> GetGraphClientAsync()
{
Uri serviceRoot = new Uri(appConfig.GraphResourceUriBeta + appConfig.Tenant);
_graphClient = new GraphService(serviceRoot,
async () => await AcquireTokenAsyncForUser(appConfig.GraphResourceUri, appConfig.Tenant));
return _graphClient;
}
private async Task<string> AcquireTokenAsyncForUser(string resource, string tenantId)
{
AuthenticationResult authenticationResult = await GetAccessToken(resource, tenantId);
_accessCode = authenticationResult.AccessToken;
return _accessCode;
}
private async Task<AuthenticationResult> GetAccessToken(string resource, string tenantId)
{
string authority = appConfig.Authority;
AuthenticationContext authenticationContext = new AuthenticationContext(authority);
ClientCredential credential = new ClientCredential(appConfig.ClientId, appConfig.ClientSecret);
string authHeader = HttpContext.Current.Request.Headers["Authorization"];
string userAccessToken = authHeader.Substring(authHeader.LastIndexOf(' ')).Trim();
UserAssertion userAssertion = new UserAssertion(userAccessToken);
var authenticationResult = await authenticationContext.AcquireTokenAsync(resource, credential, userAssertion);
return authenticationResult;
}
However if I change the SendEmailAsUserAsync method as shown below, the email is sent but an InvalidOperationException is thrown with message "The complex type 'System.Object' has no settable properties."
public async Task SendEmailAsUserAsync(EmailMessage message)
{
try
{
var graphClient = await _authenticationHelper.GetGraphClientAsync();
Message m = InitializeMessage(message);
//await graphClient.Me.SendMailAsync(m, true); //This did not work
var user = await graphClient.Me.ExecuteAsync();
await user.SendMailAsync(m, true);
}
catch (DataServiceQueryException dsqe)
{
_logger.Error("Could not get files: " + dsqe.InnerException.Message, dsqe);
throw;
}
}
Can any one point out if there is something wrong here.
Check the example project below, this has a working example (after you fill in the ClientID etc. in app.config).
Office 365 API demo applications
For sending email it uses the function below, which works if you set it up correctly. It also has a number of functions for Authenticating using Authorization Code Grant Flow.
public async Task SendMail(string to, string subject, string body)
{
var client = await this.AuthenticationHelper
.EnsureOutlookServicesClientCreatedAsync(
Office365Capabilities.Mail.ToString());
Message mail = new Message();
mail.ToRecipients.Add(new Recipient()
{
EmailAddress = new EmailAddress
{
Address = to,
}
});
mail.Subject = subject;
mail.Body = new ItemBody() { Content = body, ContentType = BodyType.HTML };
await client.Me.SendMailAsync(mail, true);
}
Actually, there is no assembly wrapper for the graph API.
Microsoft.Graph.dll is deprecrated.
So, you should to :
Deal with the REST requests : See here : http://graph.microsoft.io/docs/api-reference/v1.0/api/message_send
Generate a wrapper with Microsoft.Vipr project : see here : https://github.com/microsoft/vipr
For the authentication, ADAL works fine :)
I'm trying to create a new user using the CoSign SPML WS.
The code I'm using (C#.NET) is below. Can someone please let me know if the PSOIdentifierType.ID is correct (i.e. "The ID of the User") and what should the Target ID be, I think it should be blank as the user does not exist yet.
private const readonly string addTargetDB = "CoSignDB";
public void CreateBasicUser(string userName, string userLoginName, string userPassword, string userCN, string userEmail)
{
SPMLSoapClient client = new SPMLSoapClient();
AddRequestType request = new AddRequestType();
PSOIdentifierType psoCreationType = new PSOIdentifierType();
psoCreationType.ID = userName;
psoCreationType.targetID = ""; //The parameter that was returned in the ListTargets operation
UserRecord newUserRecord = new UserRecord();
newUserRecord.UserLoginName = userLoginName;
newUserRecord.Password = userPassword;
newUserRecord.UserCN = userCN;
newUserRecord.EmailAddress = userEmail;
newUserRecord.RightsMask = (uint)1; // 1 - User
newUserRecord.UserKind = UserKindEnum.User;
request.returnData = ReturnDataType.everything;
request.targetID = addTargetDB;
request.psoID = psoCreationType;
request.UserRecord = newUserRecord;
AddResponseType clientAddResponse = client.add(request);
if(clientAddResponse.status == StatusCodeType.success)
{
// OK
}
else if(clientAddResponse.status == StatusCodeType.failure)
{
// Fail
}
}
The id of the user is correct (it should be the username) and the TargetID should be "CoSignDB"
I like to calculate the passowrd expiration date for the user in active directory
I am able to get the MaxPWdAge and LastPwdSet attributes.
But the problem is whenever i am changing the password of one of a user for testing purposes, lastPwdSet is not updating and it is still showing the old date?
Can anybody tell me why is this happen ?
public bool CheckPassWordExpiryDate(string LdapPath, string Username, string Password)
{
DomainConfiguration domainConfig = new DomainConfiguration();
// Configuration(web.config) changes
DirectoryEntry de = new DirectoryEntry("LDAP://" + LdapPath, domainConfig.UserName, domainConfig.Password);
DirectoryEntry entry = new DirectoryEntry();
entry.Username = Username;
entry.Password = Password;
//Function to get maximum password age from the active directory
int maxPwdAge = GetMaxPasswordAge();
// Function to get last password set date for the use.
DateTime pwdLastSet = GetPwdLastSet("pwdLastSet", Username);
//Add maximum password age days to Last password set days , if it is less than today's date means that password has been expired else it is not expired
if (pwdLastSet.AddDays(maxPwdAge) < DateTime.Now)
{
return true;
}
else
{
return false;
}
}
public static int GetMaxPasswordAge()
{
DomainConfiguration domainConfig = new DomainConfiguration();
using (new SPMonitoredScope("AD Properties"))
{
using (DirectoryEntry domain = new DirectoryEntry("LDAP://" + domainConfig.DomainName, domainConfig.UserName, domainConfig.Password))
{
DirectorySearcher ds = new DirectorySearcher(
domain,
"(objectClass=*)",
null,
SearchScope.Base
);
SearchResult sr = ds.FindOne();
TimeSpan maxPwdAge = TimeSpan.MinValue;
if (sr.Properties.Contains("maxPwdAge"))
maxPwdAge = TimeSpan.FromTicks((long)sr.Properties["maxPwdAge"][0]);
return maxPwdAge.Duration().Days;
}
}
}
public DateTime GetPwdLastSet(string attr, string UserName)
{
DomainConfiguration domainConfig = new DomainConfiguration();
using (new SPMonitoredScope("AD Properties"))
{
using (DirectoryEntry domain = new DirectoryEntry("LDAP://" + domainConfig.DomainName, domainConfig.UserName, domainConfig.Password))
{
//DirectorySearcher searcher = new DirectorySearcher(domain, "(|(objectClass=organizationalUnit)(objectClass=container)(objectClass=builtinDomain)(objectClass=domainDNS))");
DirectorySearcher searcher = new DirectorySearcher(domain);
searcher.PageSize = 1000;
searcher.Filter = "(SAMAccountName='" + UserName + "')";
searcher.Filter = "(|(objectCategory=group)(objectCategory=person))";
var user = searcher.FindOne();
DateTime pwdLastSet = DateTime.FromFileTime((Int64)user.Properties["PwdLastSet"][0]);
return pwdLastSet;
}
}
}
} }