public async Task <IActionResult> ViewShift(ShiftViewModel viewModel) { Location location = await this.GetLocation(viewModel.LocationName); IEnumerable <Shift> shifts = await this.shiftRepository.Get( "SELECT * FROM c WHERE c.LocationId = @locationId AND c.StartDateTime = @start AND c.EndDateTime = @end AND c.WorkType = @workType", new Dictionary <string, object> { { "@locationId", location.id }, { "@start", viewModel.Start }, { "@end", viewModel.End }, { "@workType", viewModel.WorkType } }, location.id); IEnumerable <Shift> bookedShifts = shifts.Where(x => x.EmployeeId != null); if (bookedShifts.Count() == 0) { this.logger.LogInformation("Trying to view shift when there are no employees"); ViewData["NoEmployees"] = this.stringLocalizer["NoEmployees"]; } List <string> employees = new List <string>(); foreach (var shift in bookedShifts) { Microsoft.Graph.User user = await graphServiceClient.Users[shift.EmployeeId].Request().GetAsync(); employees.Add($"{user.GivenName} {user.Surname}"); } ViewData["Employees"] = employees; return(View(viewModel)); }
public async Task Should_return_user_names_starting_with_text() { var text = "test'user"; var filter = $"startswith(userPrincipalName,'{text.Replace("'", "''")}')"; _queryUrl += $"?$filter={filter}"; var user = new Microsoft.Graph.User() { UserPrincipalName = "TestUser" }; var azureAdGraphQueryResponse = new AzureAdGraphQueryResponse <Microsoft.Graph.User>() { Value = new List <Microsoft.Graph.User> { user } }; _secureHttpRequest.Setup(x => x.GetAsync(It.IsAny <string>(), It.IsAny <string>())) .ReturnsAsync(ApiRequestHelper.CreateHttpResponseMessage(azureAdGraphQueryResponse, HttpStatusCode.OK)); var response = await _client.GetUsernamesStartingWithAsync(text); response.Should().NotBeNull(); var users = response.ToList(); users.Count.Should().Be(1); users.First().Should().Be("TestUser"); _secureHttpRequest.Verify(x => x.GetAsync(_graphApiSettings.Object.AccessToken, _queryUrl), Times.Once); }
internal OrganizationUser(Microsoft.Graph.User u, string orgIdExtension, string orgRoleExtension, string tenantIssuerName) { this.Id = u.Id; this.DisplayName = u.DisplayName; this.GivenName = u.GivenName; this.Surname = u.Surname; this.UserPrincipalName = u.UserPrincipalName; if (u.AdditionalData == null || !u.AdditionalData.Any()) { return; } if (u.AdditionalData.ContainsKey(orgIdExtension)) { this.OrgId = u.AdditionalData[orgIdExtension].ToString(); } if (u.AdditionalData.ContainsKey(orgRoleExtension)) { this.OrgRole = u.AdditionalData[orgRoleExtension].ToString(); } if (u.Identities == null || !u.Identities.Any()) { return; } SignInNames = u.Identities.Where(x => x.Issuer == tenantIssuerName && x.SignInType != "userPrincipalName").Select(x => x.IssuerAssignedId); Identities = u.Identities; }
public async Task <Microsoft.Graph.User> Me() { Microsoft.Graph.GraphServiceClient client = await graphTokenService.GetClientForUser(new string[] { "profile" }); Microsoft.Graph.User me = await client.Me.Request().GetAsync(); return(me); }
public static object ToJson(this Microsoft.Graph.User user) { return(new { id = user.Id, name = user.DisplayName, mail = user.Mail }); }
//private void Button_Click(object sender, RoutedEventArgs e) //{ // login.ClientId = "935c61af-136a-4671-b4f6-cabf7964bfb4"; // //System.Diagnostics.Debug.WriteLine(WebAuthenticationBroker.GetCurrentApplicationCallbackUri().Host.ToUpper()); // login.SignInAsync(); //} private async void login_SignInCompleted(object sender, GraphLogin.SignInEventArgs e) { var graphClient = e.GraphClient; Microsoft.Graph.User loggedInUser = await graphClient.Me.Request().GetAsync(); System.Diagnostics.Debug.WriteLine(loggedInUser.DisplayName); debugOutput.Text = "User logged in:" + loggedInUser?.DisplayName + "\r\n"; debugOutput.Text += "User logged in:" + loggedInUser?.JobTitle + "\r\n"; }
public static UserVm ToViewModel(Microsoft.Graph.User user) { var userVm = new UserVm(); userVm.DisplayName = user.DisplayName; userVm.Email = user.Mail; userVm.JobTitle = user.JobTitle; return(userVm); }
public static User UserProperty(Microsoft.Graph.User graphUser) { User user = new User(); user.id = graphUser.Id; user.givenName = graphUser.GivenName; user.surname = graphUser.Surname; user.userPrincipalName = graphUser.UserPrincipalName; user.email = graphUser.Mail; return(user); }
/// <summary> /// Handles non-message activities /// </summary> /// <param name="context"></param> /// <param name="activity"></param> /// <returns></returns> private async Task HandleSubmitAction(IDialogContext context, Activity activity) { JObject parameters = activity.Value as JObject; if (parameters != null) { var command = parameters["command"]; // Handle login completion event. if (activity.IsTeamsVerificationInvoke()) { string code = parameters["state"].ToString(); var oauthClient = activity.GetOAuthClient(); var token = await oauthClient.OAuthApi.GetUserTokenAsync(activity.From.Id, ConnectionName, magicCode : code).ConfigureAwait(false); if (token != null) { Microsoft.Graph.User current = await new GraphUtil(token.Token).GetMe(); await context.PostAsync($"Success! You are now signed in as {current.DisplayName} with {current.Mail}"); } } // Confirmation of job posting message. else if (command != null && command.ToString() == "createPosting") { OpenPosition pos = new OpenPositionsDataController().CreatePosition(parameters["jobTitle"].ToString(), int.Parse(parameters["jobLevel"].ToString()), Constants.Locations[int.Parse(parameters["jobLocation"].ToString())], activity.From.Name); await SendNewPostingConfirmationMessage(context, pos); } } else if (activity.Attachments.Any()) { // Handle file upload scenario. if (activity.Attachments[0].ContentType == "application/vnd.microsoft.teams.file.download.info") { string fileName = activity.Attachments[0].Name; string fileType = (activity.Attachments[0].Content as JObject)["fileType"].ToString().ToLower(); if (fileType.Contains("docx")) { await context.PostAsync($"Job posting successfully uploaded: {fileName}"); } else { await context.PostAsync("Invalid file type received. Please upload a PDF or Word document"); } } } }
private static void extendedTest(IDocumentProvider msGraph, Microsoft.Graph.User serviceUser) { var documents = msGraph.GetDocuments(serviceUser.Id); //var folders = msGraph.GetFolders(); /*var htmlLargeInputBytes = File.ReadAllBytes("..\\..\\resources\\source\\large-file.pptx"); * byte[] pdfHTMLLargeDocBytes = msGraph.ConvertDocumentToPDF(htmlLargeInputBytes, $"Temp/{Guid.NewGuid()}.pptx", serviceUser.Id); * File.WriteAllBytes($"..\\..\\resources\\target\\large-file-pptx.pdf", pdfHTMLLargeDocBytes);*/ var htmlSimpleInputBytes = File.ReadAllBytes("..\\..\\resources\\source\\simple-html.html"); byte[] pdfHTMLSimpleDocBytes = msGraph.ConvertDocumentToPDF(htmlSimpleInputBytes, $"Temp/{Guid.NewGuid()}.html", serviceUser.Id); File.WriteAllBytes($"..\\..\\resources\\target\\simple-html.pdf", pdfHTMLSimpleDocBytes); /*var csvSimpleInputBytes = File.ReadAllBytes("..\\..\\resources\\source\\simple.csv"); * byte[] pdfCSVSimpleDocBytes = msGraph.ConvertDocumentToPDF(csvSimpleInputBytes, $"Temp/{Guid.NewGuid()}.csv", serviceUser.Id); * File.WriteAllBytes($"..\\..\\resources\\target\\csv-simple.pdf", pdfCSVSimpleDocBytes);*/ var inputBytes = File.ReadAllBytes("..\\..\\resources\\source\\doc.docx"); byte[] pdfDocBytes = msGraph.ConvertDocumentToPDF(inputBytes, $"Temp/{Guid.NewGuid()}.docx", serviceUser.Id); File.WriteAllBytes($"..\\..\\resources\\target\\doc.pdf", pdfDocBytes); var invoiceInputBytes = File.ReadAllBytes("..\\..\\resources\\source\\invoice.xlsx"); byte[] pdfInvoiceDocBytes = msGraph.ConvertDocumentToPDF(invoiceInputBytes, $"Temp/{Guid.NewGuid()}.xlsx", serviceUser.Id); File.WriteAllBytes($"..\\..\\resources\\target\\invoice.pdf", pdfInvoiceDocBytes); /*var csvInvoiceInputBytes = File.ReadAllBytes("..\\..\\resources\\source\\invoice.csv"); * byte[] pdfCSVInvoiceDocBytes = msGraph.ConvertDocumentToPDF(csvInvoiceInputBytes, $"Temp/{Guid.NewGuid()}.csv", serviceUser.Id); * File.WriteAllBytes($"..\\..\\resources\\target\\csv-invoice.pdf", pdfCSVInvoiceDocBytes);*/ var rootDocs = msGraph.GetRootDocuments(serviceUser.Id); var doc1 = msGraph.GetDocumentByPath(serviceUser.Id, "dummy.txt"); //var doc2 = msGraph.GetDocumentById(serviceUser.Id, "01IKWSDM5REL3VRV2EFNHZ6DCBXVN46JCV"); // 01IKWSDMZZH4XLSPOKLNA33GWZD6XF7MC5 //var doc3 = msGraph.GetDocumentByPath(serviceUser.Id, "7Digital"); //var childDocuments = msGraph.GetChildDocumentsById(serviceUser.Id, "01IKWSDM5REL3VRV2EFNHZ6DCBXVN46JCV"); var smallBuffer = System.Text.Encoding.UTF8.GetBytes("Empty"); var smallDocName = Guid.NewGuid().ToString(); var smallDoc = msGraph.UploadSmallDocument(smallBuffer, $"Temp/{smallDocName}.txt", serviceUser.Id); msGraph.DeleteDocumentById(serviceUser.Id, smallDoc.id); var largeBuffer = System.IO.File.ReadAllBytes("..\\..\\resources\\source\\doc.docx"); var largeDocName = Guid.NewGuid().ToString(); var largeDoc = msGraph.UploadLargeDocument(largeBuffer, $"Temp/{largeDocName}.txt", serviceUser.Id); msGraph.DeleteDocumentById(serviceUser.Id, largeDoc.id); }
public static UserDto UserProperty(Microsoft.Graph.User graphUser) { UserDto user = new UserDto { UserId = graphUser.Id, GivenName = graphUser.GivenName, Surname = graphUser.Surname, UserPrincipalName = graphUser.UserPrincipalName, Email = graphUser.Mail, DisplayName = graphUser.DisplayName }; return(user); }
/// <summary> /// Signs in the current user. /// </summary> /// <returns></returns> public async Task <bool> SignInCurrentUserAsync() { graphClient = AuthenticationHelper.GetAuthenticatedClient(); if (graphClient != null) { Microsoft.Graph.User user = await graphClient.Me.Request().GetAsync(); if (user != null) { string userId = user.Id; UserInfo.Text = "Name:" + user.DisplayName + " and address: " + user.UserPrincipalName; return(true); } } return(false); }
public void TestIntialize() { user = new Microsoft.Graph.User() { Id = "1" }; group = new Microsoft.Graph.Group() { Id = "2" }; customDirectoryObject = new CustomDirectoryObject { ObjectDataId = $"{GraphApiSettings.GraphApiBaseUri}v1.0/{GraphApiSettings.TenantId}/directoryObjects/{user.Id}" }; groupAccessUri = $"{GraphApiSettings.GraphApiBaseUri}v1.0/{GraphApiSettings.TenantId}/groups/{group.Id}/members/$ref"; }
public UserModel(Microsoft.Graph.User user) { var accec = SetAccessLevel(user.JobTitle); var name = user.DisplayName.Split(' '); GUID = user.Id; Login = user.Mail; LastName = name.ElementAtOrDefault(0); FirstName = name.ElementAtOrDefault(1); FatherName = name.ElementAtOrDefault(2); Phone = user.MobilePhone; Address = user.StreetAddress; Birthday = user.Birthday.Value.DateTime; AccessLevel = accec; Department = accec == AccessLevel.Teacher ? string.Concat(user.Department, $", {user.JobTitle}") : user.Department; }
private async Task HandleLoginVerification(Activity invoke) { string connectionName = ConfigurationManager.AppSettings["ConnectionName"]; JObject ctx = invoke.Value as JObject; if (ctx != null) { string code = ctx["code"].ToString(); var oauthClient = invoke.GetOAuthClient(); var token = await oauthClient.OAuthApi.GetUserTokenAsync(invoke.From.Id, connectionName, magicCode : invoke.Text).ConfigureAwait(false); if (token != null) { Microsoft.Graph.User current = await new GraphUtil(token.Token).GetMe(); await context.PostAsync($"Success! You are now signed in as {current.DisplayName} with {current.Mail}"); } } }
public static DirectoryUser MapToDirectoryUser(this Microsoft.Graph.User graphUser) { DirectoryUser user = new DirectoryUser { UserId = graphUser.Id, EmailAddress = graphUser.Mail, FirstName = graphUser.GivenName, LastName = graphUser.Surname, PreferredLanguage = graphUser.PreferredLanguage, Location = graphUser.OfficeLocation, PhoneNumber = graphUser.MobilePhone, DisplayName = graphUser.DisplayName, UserPrincipalName = graphUser.UserPrincipalName, SamAccountName = graphUser.OnPremisesSamAccountName, CompanyRole = graphUser.JobTitle }; return(user); }
public ActiveDirectoryServiceTests() { _mockRemoteGraphService = new Mock <IRemoteGraphService>(); _mockLogger = new Mock <ILogger <ActiveDirectoryService> >(); var configuration = new MapperConfiguration(cfg => cfg.AddProfile(new MappingProfiles())); var mapper = new Mapper(configuration); //var cache = new NoCacheService(); _mockCache = new Mock <ICacheService>(); _activeDirectoryService = new ActiveDirectoryService(_mockRemoteGraphService.Object, mapper, _mockCache.Object, _mockLogger.Object); // Init testdata var inMemoryGraphService = new InMemoryGraphService(); var userId = Guid.NewGuid().ToString(); var groupId = Guid.NewGuid().ToString(); _user = inMemoryGraphService.GetUserAsync(userId).Result; _group = inMemoryGraphService.GetGroupAsync(groupId).Result; _managerId = Guid.NewGuid().ToString(); var users = inMemoryGraphService.FindActiveUserAsync(string.Empty).Result; var groups = inMemoryGraphService.FindGroupAsync(string.Empty).Result; // Init mock behaviour _mockRemoteGraphService.Setup(x => x.GetUserAsync(It.IsAny <string>())) .Returns(Task.FromResult(_user)); _mockRemoteGraphService.Setup(x => x.FindActiveUserAsync(It.IsAny <string>())) .Returns(Task.FromResult(users)); _mockRemoteGraphService.Setup(x => x.GetManagerIdOfUserAsync(It.IsAny <string>())) .Returns(Task.FromResult(_managerId)); _mockRemoteGraphService.Setup(x => x.GetGroupAsync(It.IsAny <string>())) .Returns(Task.FromResult(_group)); _mockRemoteGraphService.Setup(x => x.FindGroupAsync(It.IsAny <string>())) .Returns(Task.FromResult(groups)); }
public async Task <User> UpdateUserAccount(string userId, string firstName, string lastName, string newUsername) { var updatedUser = new User { Id = userId, GivenName = firstName, Surname = lastName, DisplayName = $"{firstName} {lastName}", UserPrincipalName = newUsername }; var json = JsonConvert.SerializeObject(updatedUser); var stringContent = new StringContent(json); var accessUri = $"{_baseUrl}/users/{userId}"; var response = await _secureHttpRequest.PatchAsync(_graphApiSettings.AccessToken, stringContent, accessUri); await AssertResponseIsSuccessful(response); return(updatedUser); }
internal OrganizationUser(Microsoft.Graph.User u, string orgIdExtension, string orgRoleExtension) { this.Id = u.Id; this.DisplayName = u.DisplayName; this.GivenName = u.GivenName; this.Surname = u.Surname; this.UserPrincipalName = u.UserPrincipalName; if (!u.AdditionalData.Any()) { return; } if (u.AdditionalData.ContainsKey(orgIdExtension)) { this.OrgId = u.AdditionalData[orgIdExtension].ToString(); } if (u.AdditionalData.ContainsKey(orgRoleExtension)) { this.OrgRole = u.AdditionalData[orgRoleExtension].ToString(); } }
private async Task StartConversation(IDialogContext context, IAwaitable <GetTokenResponse> tokenResponse) { var tokenResponseData = await tokenResponse; var userName = string.Empty; if (null != tokenResponseData && !string.IsNullOrEmpty(tokenResponseData.Token)) { /********ConversationStarter*********/ await context.PostAsync($"SignIn- Token! {tokenResponseData.Token}"); /***********************************/ context.ConversationData.TryGetValue <string>("UserName", out userName); if (string.IsNullOrEmpty(userName)) { var client = new Services.GraphClient(tokenResponseData.Token); Microsoft.Graph.User user = await client.GetMe(); userName = user.DisplayName; context.ConversationData.SetValue <string>("UserName", userName); } await context.PostAsync($"*Hey {userName}, You are already here. How may I help you with your query.*"); //await context.PostAsync($"*you are logged in successfully*"); } else { //await context.PostAsync($"*something went wrong, please try again"); await context.Forward(new SignInDialog(), Callback, context.Activity.AsMessageActivity(), CancellationToken.None); } context.Done(true); }
public async Task <IActionResult> GetUserProfile() { Microsoft.Graph.User user = await _graphApiService.GetUserProfileAsync(); return(Ok(user)); }
/// <summary> /// Get emails from raw user input /// </summary> /// <param name="emailInput">Email user input</param> /// <param name="accessToken">Microsoft Graph access token</param> /// <returns></returns> public async Task <List <string> > GetEmails(string emailInput, string accessToken) { try { var emailList = new List <string>(); //This is because in Skype for business, " "(space) is automatically converted to " ", which is blocking to get emails var emailInputImproved = emailInput.Replace(" ", "").Replace(" :^", ""); //This is removing hyper-link which Skype for business automatically adds var emails = System.Text.RegularExpressions.Regex.Replace(emailInputImproved, "\\(.+?\\)", ""); var emailArray = emails.Split(','); foreach (var email in emailArray) { // We have name if (!email.Contains("@")) { var trimmed = email.Trim(); var valueArray = trimmed.Split(new[] { " " }, StringSplitOptions.None); var user = new User(); // TBD : We assume that first the given name is provided and then the surname with ' ' in between if (valueArray.Length > 1) { user.GivenName = valueArray[0]; user.Surname = valueArray[1]; } // TBD : Refactoring needed. For now we assume if there is one name it is the surname due to Japanese else { // TBD : Abstract that via configuration or branch logic in order to keep it generic user.Surname = valueArray[0].Replace("さん", string.Empty).Replace("ー", string.Empty).Replace("-", string.Empty) .Replace(" ", string.Empty); } var persons = await _peopleService.GetPeolpe(new List <User> { user }, accessToken); if (persons == null || persons.Count <= 0) { continue; } var emailAddress = persons.FirstOrDefault()?.Mail; emailList.Add(emailAddress); } else { var improvedEmail = email.Replace(" ", "").Replace(" ", ""); if (improvedEmail.ToLower().Trim().StartsWith("dl-")) { var groupId = await _groupService.GetGroupId(improvedEmail.Replace("dl-", string.Empty), accessToken); if (string.IsNullOrEmpty(groupId)) { throw new ApplicationException("Can't get group id."); } var members = await _groupService.GetMembers(groupId, accessToken); emailList.AddRange(members.Select(x => x.Mail)); } else { emailList.Add(improvedEmail); } } } return(emailList); } catch (Exception e) { _loggingService.Error(e, "Error in EmailService.GetEmails"); throw; } }
private static void simpleTest(IDocumentProvider msGraph, Microsoft.Graph.User serviceUser) { var documents = msGraph.GetDocuments(serviceUser.Id); }
internal OrganizationUser(Microsoft.Graph.User u, OrganizationOptions config) : this(u, config.OrgIdExtensionName, config.OrgRoleExtensionName, config.TenantIssuerName) { }
/// <summary> /// This is where you can process the incoming user message and decide what to do. /// </summary> /// <param name="context"></param> /// <param name="result"></param> /// <returns></returns> private async Task MessageReceivedAsync(IDialogContext context, IAwaitable <object> result) { var activity = await result as Activity; // Strip out all mentions. As all channel messages to a bot must @mention the bot itself, you must strip out the bot name at minimum. // This uses the extension SDK function GetTextWithoutMentions() to strip out ALL mentions var text = activity.GetTextWithoutMentions(); if (text == null) { await HandleSubmitAction(context, activity); } else { // Supports 5 commands: Help, Welcome (sent from HandleSystemMessage when bot is added), top candidates, schedule interview, and open positions. // This simple text parsing assumes the command is the first two tokens, and an optional parameter is the second. var split = text.Split(' '); // The user is asking for onen of the supported commands. if (split.Length >= 2) { var cmd = split[0].ToLower(); var keywords = split.Skip(2).ToArray(); // Parse the command and go do the right thing if (cmd.Contains("top") && keywords.Length > 0) { await SendTopCandidatesMessage(context, keywords[0]); } else if (cmd.Contains("schedule")) { // Supports either structured query or via user input. JObject ctx = activity.Value as JObject; // Check if this is a button press or a text command. if (ctx != null) { Candidate c = ctx.ToObject <Candidate>(); await SendScheduleInterviewMessage(context, c, c.ReqId); } else if (keywords.Length == 3) { string name = string.Join(" ", keywords.Take(2).ToArray()); string reqId = keywords[2]; // Takes 3 parameters: first name, last name, and then req ID await SendScheduleInterviewMessage(context, name, reqId); } else { await SendHelpMessage(context, "I'm sorry, I did not understand you :("); } } else if (cmd.Contains("open")) { await SendOpenPositionsMessage(context); } else if (cmd.Contains("resume")) { // Return "resume file" for the given candidate name. if (keywords.Length > 0) { string name = string.Join(" ", keywords).ToLower(); IMessageActivity reply = context.MakeMessage(); reply.Attachments = new List <Attachment>(); JObject card = new JObject(); card["description"] = $"Here is the resume for {name}"; card["sizeInBytes"] = 1500; Attachment attachment = new Attachment() { ContentType = "application/vnd.microsoft.teams.card.file.consent", Name = $"{name} resume.pdf", Content = card }; reply.Attachments.Add(attachment); await context.PostAsync(reply); } } else if (cmd.Contains("candidate")) { // Supports either structured query or via user input. JObject ctx = activity.Value as JObject; Candidate c = null; if (ctx != null) { c = ctx.ToObject <Candidate>(); await SendCandidateDetailsMessage(context, c); } else if (keywords.Length > 0) { string name = string.Join(" ", keywords); c = new CandidatesDataController().GetCandidateByName(name); await SendCandidateDetailsMessage(context, c); } } else if (cmd.Contains("new")) { await SendCreateNewJobPostingMessage(context); } else if (cmd.Contains("assign")) { string guid = split[1]; await UpdateMessage(context, guid); } else { await SendHelpMessage(context, "I'm sorry, I did not understand you :("); } } else { int magicCode; if (int.TryParse(text, out magicCode)) { // If the user is pasting a magic number, check if that's to get an auth token. // TODO: This shouldn't be necessary once we make some small fixes to the bot auth service. var oauthClient = activity.GetOAuthClient(); var token = await oauthClient.OAuthApi.GetUserTokenAsync(activity.From.Id, ConnectionName, magicCode : activity.Text).ConfigureAwait(false); if (token != null) { Microsoft.Graph.User current = await new GraphUtil(token.Token).GetMe(); await context.PostAsync($"Success! You are now signed in as {current.DisplayName} with {current.Mail}"); } } else if (text.Contains("help")) { // Respond with standard help message. await SendHelpMessage(context, "Sure, I can provide help info about me."); } else if (text.Contains("login")) { await SendOAuthCardAsync(context, activity); } else if (text.Contains("welcome") || text.Contains("hello") || text.Contains("hi")) { await SendHelpMessage(context, "## Welcome to the Contoso Talent Management app"); } else // Don't know what to say so this is the generic handling here. { await SendHelpMessage(context, "I'm sorry, I did not understand you :("); } } } context.Wait(MessageReceivedAsync); }
public static User ToUser(this Microsoft.Graph.User user) { return(new User { Id = user.Id, DisplayName = user.DisplayName, Email = user.Mail }); }