Exemple #1
0
        private static string FormatEmailBody(GraphInvitation data, RedemptionSettings redemption, InviteTemplate content)
        {
            var body = content.TemplateContent;

            body = body.Replace("{{InvitingOrgName}}", Settings.InvitingOrganization);
            body = body.Replace("{{InvitationLink}}", data.InviteRedeemUrl);
            body = body.Replace("{{OrgContactEmail}}", redemption.InviterResponseEmailAddr);
            return(body);
        }
Exemple #2
0
        private async Task <GraphInvitation> SendGraphInvitationAsync(GraphInvitation invitation, List <GroupObject> groups, string inviterResponseEmailAddr = null, InviteTemplate mailTemplate = null, string accessToken = null)
        {
            AdalResponse    serverResponse = null;
            GraphInvitation responseData   = new GraphInvitation();

            try
            {
                var inviteEndPoint = string.Format("{0}/{1}/invitations", Settings.GraphResource, Settings.GraphApiVersion);

                // Invite user. Your app needs to have User.ReadWrite.All or Directory.ReadWrite.All to invite
                serverResponse = AdalUtil.CallGraph(inviteEndPoint, invitation, false, null, _user, accessToken);
                responseData   = JsonConvert.DeserializeObject <GraphInvitation>(serverResponse.ResponseContent);
                if (responseData.id == null)
                {
                    responseData.ErrorInfo = string.Format("Error: Invite not sent - API error: {0}", serverResponse.Message);
                    return(responseData);
                }

                if (groups.Count > 0)
                {
                    var groupsAdded = AddUserToGroup(responseData.InvitedUser.Id, groups);
                    if (!groupsAdded.Success)
                    {
                        var resErrors = string.Join(", ", groupsAdded.Responses.Where(r => !r.Successful).Select(r => r.Message));
                        responseData.ErrorInfo += string.Format("\n\rOne or more groups failed while assigning to user \"{0}\" ({1})", responseData.InvitedUserEmailAddress, resErrors);
                    }
                }

                if (Settings.UseSMTP)
                {
                    mailTemplate = mailTemplate ?? Settings.CurrSiteConfig.InviteTemplateContent;

                    var emailSubject = mailTemplate.SubjectTemplate.Replace("{{InvitingOrgName}}", Settings.CurrSiteConfig.InvitingOrg);

                    string body = FormatEmailBody(responseData, inviterResponseEmailAddr, mailTemplate);
                    SendViaSMTP(emailSubject, body, invitation.InvitedUserEmailAddress);
                }


                var request = await GuestRequestRules.GetUserAsync(invitation.InvitedUserEmailAddress);

                request.InvitationResult = responseData;
                await GuestRequestRules.UpdateAsync(request);

                return(responseData);
            }
            catch (Exception ex)
            {
                var reason = (serverResponse == null ? "N/A" : serverResponse.ResponseContent);
                responseData.ErrorInfo = string.Format("Error: {0}<br>Server response: {1}", ex.Message, reason);
                return(responseData);
            }
        }
Exemple #3
0
        private static string FormatEmailBody(GraphInvitation invitation, string inviterResponseEmailAddr, InviteTemplate mailTemplate)
        {
            var body = mailTemplate.TemplateContent;

            body = body.Replace("{{InvitingOrgName}}", Settings.CurrSiteConfig.InvitingOrg);
            body = body.Replace("{{InvitationLink}}", invitation.InviteRedeemUrl);
            body = body.Replace("{{InvitationStatus}}", invitation.Status);
            if (invitation.InvitedUserMessageInfo != null)
            {
                body = body.Replace("{{CustomMessage}}", invitation.InvitedUserMessageInfo.CustomizedMessageBody);
            }
            body = body.Replace("{{OrgContactEmail}}", inviterResponseEmailAddr);
            return(body);
        }
Exemple #4
0
        public static async Task <HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
        {
            log.Info("SendInvite http trigger started.");

            GraphInvitation result = null;

            try
            {
                // Deserialize request object to model
                var request = await req.RetrieveRequestObject <GuestRequest>().ConfigureAwait(false);

                // Check if user exists in Azure AD
                var user = await UserManager.GetUserByMailAddress(request.EmailAddress).ConfigureAwait(false);

                if (user != null)
                {
                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, "User already exists in directory."));
                }

                // Get group by account id
                var group = await GroupsManager.GetGroupByAccountIdAsync(request.AccountId).ConfigureAwait(false);

                // Check if the group is found
                if (group != null)
                {
                    // Send invitation to user
                    result = await InvitationManager
                             .SendInvitationAsync(request,
                                                  $"https://rubichill.sharepoint.com/sites/{request.AccountId}",
                                                  group.Id)
                             .ConfigureAwait(false);
                }
                else
                {
                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, "Azure AD group not found."));
                }

                return(req.CreateResponse(HttpStatusCode.Created, result));
            }
            catch (Exception e)
            {
                return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e));
            }
        }
        public static async Task <GraphInvitation> SendInvitationAsync(GuestRequest request, string groupUrl, string groupId)
        {
            var displayName = $"{request.FirstName} {request.LastName}";
            var memberType  = GraphMemberType.Guest;

            GraphResponse <GraphInvitation> response = null;
            // Setup invitation
            var inviteEndPoint = $"{Constants.ResourceUrl}/{Constants.GraphApiBetaVersion}/invitations";
            var invitation     = new GraphInvitation()
            {
                InvitedUserDisplayName  = displayName,
                InvitedUserEmailAddress = request.EmailAddress,
                InviteRedirectUrl       = groupUrl,
                SendInvitationMessage   = false,
                InvitedUserType         = memberType.ToString()
            };

            // Invite user via Graph API
            response = await Client.GetData <GraphInvitation>(HttpMethod.Post, inviteEndPoint, invitation)
                       .ConfigureAwait(false);

            if (!response.IsSuccessfull)
            {
                throw new Exception($"Error: invite not sent - API error: {response.Message}");
            }

            // Add user to group
            var groupAdded = await AddUserToGroupAsync(response.Data.InvitedUser.Id,
                                                       groupId).ConfigureAwait(false);

            if (!groupAdded)
            {
                throw new Exception($"Error: could not add user {response.Data.InvitedUserEmailAddress} to group {groupId}");
            }

            // Send email to user
            if (!await Mailer.SendInvitationEmailAsync(request.EmailAddress, response.Data.InviteRedeemUrl))
            {
                throw new Exception($"Error: invite not send to {request.EmailAddress}.");
            }

            return(response.Data);
        }
Exemple #6
0
        public static async Task <string> SendInvitation(GuestRequest request, string profileUrl, PreAuthDomain domainSettings = null)
        {
            var displayName = string.Format("{0} {1}", request.FirstName, request.LastName);

            var useCustomEmailTemplate = false;
            var redemptionSettings     = Settings.SiteRedemptionSettings;
            var memberType             = MemberType.Guest;

            //use domain custom setting if exists, else use global site config setting
            if (domainSettings != null)
            {
                redemptionSettings = domainSettings.DomainRedemptionSettings;
                //domainSettings.InviteTemplateContent;
                memberType = domainSettings.MemberType;

                if (!string.IsNullOrEmpty(domainSettings.InviteTemplateId))
                {
                    useCustomEmailTemplate = true;
                }
            }

            AdalResponse serverResponse = null;

            try
            {
                // Setup invitation
                var             inviteEndPoint = string.Format("{0}/{1}/invitations", Settings.GraphResource, Settings.GraphApiVersion);
                GraphInvitation invitation     = new GraphInvitation();
                invitation.InvitedUserDisplayName  = displayName;
                invitation.InvitedUserEmailAddress = request.EmailAddress;
                invitation.InviteRedirectUrl       = profileUrl;
                invitation.SendInvitationMessage   = (!Settings.UseSMTP);
                invitation.InvitedUserType         = memberType.ToString();

                if (useCustomEmailTemplate && invitation.SendInvitationMessage && domainSettings.InviteTemplateContent.TemplateContent != null)
                {
                    invitation.InvitedUserMessageInfo = new InvitedUserMessageInfo
                    {
                        CustomizedMessageBody = domainSettings.InviteTemplateContent.TemplateContent
                    };
                }

                // Invite user. Your app needs to have User.ReadWrite.All or Directory.ReadWrite.All to invite
                serverResponse = CallGraph(inviteEndPoint, invitation);
                var responseData = JsonConvert.DeserializeObject <GraphInvitation>(serverResponse.ResponseContent);
                if (responseData.id == null)
                {
                    return(string.Format("Error: Invite not sent - API error: {0}", serverResponse.Message));
                }

                if (domainSettings != null)
                {
                    if (domainSettings.Groups != null && domainSettings.Groups.Count > 0)
                    {
                        var groupsAdded = AddUserToGroup(responseData.InvitedUser.Id, domainSettings.Groups);
                        //todo: log or notify re the negative
                    }
                }

                if (Settings.UseSMTP)
                {
                    var emailSubject = Settings.InvitationEmailSubject.Replace("{{orgname}}", Settings.InvitingOrganization);

                    string body = FormatEmailBody(responseData, redemptionSettings, domainSettings.InviteTemplateContent);
                    SendViaSMTP(emailSubject, body, invitation.InvitedUserEmailAddress);
                }

                return(responseData.Status);
            }
            catch (Exception ex)
            {
                var reason = (serverResponse == null ? "N/A" : serverResponse.ResponseContent);

                return(string.Format("Error: {0}<br>Server response: {1}", ex.Message, reason));
            }
        }
Exemple #7
0
        public async Task <BulkInviteResults> ProcessBulkInvitations(BulkInviteSubmission submission)
        {
            var res = new BulkInviteResults(submission.Id);

            try
            {
                var batch          = new GraphBatch();
                int counter        = 0;
                var inviteEndPoint = string.Format("/{0}/invitations", Settings.GraphApiVersion);
                var headerColl     = new Dictionary <string, string>
                {
                    { "Content-Type", "application/json" }
                };

                var items = await BulkInviteSubmission.GetGuestRequestsPending(submission.Id);

                foreach (var item in items)
                {
                    counter++;
                    // Setup invitation
                    GraphInvitation invitation = new GraphInvitation()
                    {
                        InvitedUserDisplayName  = item.EmailAddress,
                        InvitedUserEmailAddress = item.EmailAddress,
                        InviteRedirectUrl       = _profileUrl,
                        SendInvitationMessage   = (!Settings.UseSMTP),
                        InvitedUserType         = submission.MemberType.ToString()
                    };

                    if (submission.InvitationMessage.Length > 0)
                    {
                        invitation.InvitedUserMessageInfo = new InvitedUserMessageInfo
                        {
                            CustomizedMessageBody = submission.InvitationMessage
                        };
                    }

                    batch.Requests.Add(new BulkInviteRequest
                    {
                        Id             = counter.ToString(),
                        GuestRequestId = item.Id,
                        Request        = item,
                        Method         = "POST",
                        Headers        = headerColl,
                        Url            = inviteEndPoint,
                        Body           = invitation
                    });
                }

                /* NOTE:
                 * This process is designed to leverage the Microsoft Graph batch processor:
                 *     https://developer.microsoft.com/en-us/graph/docs/concepts/json_batching
                 * However, the batch processor is currently (2018) in preview and limited to 20 submissions per request
                 * For the time being, we'll loop the collection and make individual synchronous calls
                 */
                //res = SubmitToGraphBatch(batch, submission, userId);

                res = await SubmitLocally(batch, submission);


                return(res);
            }
            catch (Exception ex)
            {
                var msg = "Error processing bulk invitation";
                res.ErrorMessage = Logging.WriteToAppLog(msg, System.Diagnostics.EventLogEntryType.Error, ex);
                await BulkInviteResults.AddItem(res);

                return(res);
            }
        }
Exemple #8
0
        public async Task <GraphInvitation> ProcessInvitationAsync(GuestRequest request, PreAuthDomain domainSettings = null)
        {
            var displayName = string.Format("{0} {1}", request.FirstName, request.LastName);

            var useCustomEmailTemplate = false;
            var redemptionSettings     = Settings.CurrSiteConfig.SiteRedemptionSettings;
            var inviteTemplate         = Settings.CurrSiteConfig.InviteTemplateContent;

            var memberType = MemberType.Guest;

            //use domain custom setting if exists, else use global site config setting
            if (domainSettings != null)
            {
                redemptionSettings = domainSettings.DomainRedemptionSettings;
                inviteTemplate     = domainSettings.InviteTemplateContent;
                memberType         = domainSettings.MemberType;

                if (!string.IsNullOrEmpty(domainSettings.InviteTemplateId))
                {
                    useCustomEmailTemplate = true;
                }
            }

            try
            {
                // Setup invitation
                GraphInvitation invitation = new GraphInvitation()
                {
                    InvitedUserDisplayName  = displayName,
                    InvitedUserEmailAddress = request.EmailAddress,
                    InviteRedirectUrl       = _profileUrl,
                    SendInvitationMessage   = (!Settings.UseSMTP),
                    InvitedUserType         = memberType.ToString()
                };
                if (useCustomEmailTemplate && invitation.SendInvitationMessage && domainSettings.InviteTemplateContent.TemplateContent != null)
                {
                    invitation.InvitedUserMessageInfo = new InvitedUserMessageInfo
                    {
                        CustomizedMessageBody = domainSettings.InviteTemplateContent.TemplateContent
                    };
                }
                var groups = new List <GroupObject>();

                if (domainSettings != null)
                {
                    if (domainSettings.Groups != null && domainSettings.Groups.Count > 0)
                    {
                        groups = domainSettings.Groups;
                    }
                }

                return(await SendGraphInvitationAsync(invitation, groups, redemptionSettings.InviterResponseEmailAddr, inviteTemplate));
            }
            catch (Exception ex)
            {
                return(new GraphInvitation
                {
                    ErrorInfo = string.Format("Error: {0}", ex.Message)
                });
            }
        }
Exemple #9
0
        /// <summary>
        /// GraphInvitation is a model from https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/resources/invitation
        /// Do not alter
        /// </summary>
        /// <param name="invitation">The GraphInvitation object transmitted to the B2B Guest API</param>
        /// <param name="groups">Azure AD groups to assign the guest user to</param>
        /// <param name="inviterResponseEmailAddr"></param>
        /// <param name="mailTemplate"></param>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        private async Task <GuestRequest> SendGraphInvitationAsync(GraphInvitation invitation, List <GroupObject> groups, GuestRequest request, string inviterResponseEmailAddr = null, InviteTemplate mailTemplate = null, string accessToken = null)
        {
            AdalResponse    serverResponse = null;
            GraphInvitation responseData   = new GraphInvitation();

            try
            {
                var inviteEndPoint = string.Format("{0}/{1}/invitations", Settings.GraphResource, Settings.GraphApiVersion);

                // Invite user. Your app needs to have User.ReadWrite.All or Directory.ReadWrite.All to invite
                serverResponse = AdalUtil.CallGraph(inviteEndPoint, invitation, false, null, _user, accessToken);

                responseData             = JsonConvert.DeserializeObject <GraphInvitation>(serverResponse.ResponseContent);
                request.InvitationResult = responseData;
                request.Status           = responseData.Status;

                if (responseData.id == null)
                {
                    //API call failed - put the request back in the queue
                    responseData.ErrorInfo   = string.Format("Error: Invite not sent - API error: {0}", serverResponse.Message);
                    request.InvitationResult = responseData;
                    request.Disposition      = Disposition.Pending;
                }
                else
                {
                    //invitation API call successful
                    if (responseData.Status.Substring(0, 5) == "Error")
                    {
                        //API call was successful but something failed while trying to process the request - put the request back in the queue
                        request.Disposition = Disposition.Pending;
                    }
                    else
                    {
                        //check to see if groups should be assigned
                        if (groups.Count > 0)
                        {
                            try
                            {
                                var groupsAdded = AddUserToGroup(responseData.InvitedUser.Id, groups);
                                if (!groupsAdded.Success)
                                {
                                    //group assignment failed
                                    var resErrors = string.Join(", ", groupsAdded.Responses.Where(r => !r.Successful).Select(r => r.Message));
                                    var msg       = string.Format("\n\rOne or more groups failed while assigning to user \"{0}\" ({1})", responseData.InvitedUserEmailAddress, resErrors);
                                    request.PostProcessingStatus += msg;
                                }
                            }
                            catch (Exception groupEx)
                            {
                                //group assignment errored
                                var msg = string.Format("\n\rAn error occured while assigning a group to user \"{0}\" ({1})", responseData.InvitedUserEmailAddress, groupEx.Message);
                                Logging.WriteToAppLog(msg, EventLogEntryType.Warning, groupEx);
                                request.PostProcessingStatus += msg;
                            }
                        }

                        //check to see if custom mail should be sent
                        if (Settings.UseSMTP)
                        {
                            try
                            {
                                mailTemplate = mailTemplate ?? Settings.CurrSiteConfig.InviteTemplateContent;

                                var emailSubject = mailTemplate.SubjectTemplate.Replace("{{InvitingOrgName}}", Settings.CurrSiteConfig.InvitingOrg);

                                string body = FormatEmailBody(responseData, inviterResponseEmailAddr, mailTemplate);
                                SendViaSMTP(emailSubject, body, invitation.InvitedUserEmailAddress);
                                request.MailSent = true;
                            }
                            catch (Exception mailEx)
                            {
                                var msg = string.Format("\n\rSending invitation failed for user \"{0}\" ({1})", responseData.InvitedUserEmailAddress, mailEx.Message);
                                Logging.WriteToAppLog(msg, EventLogEntryType.Warning, mailEx);
                                request.PostProcessingStatus += msg;
                            }
                        }
                    }
                }

                //all attempts complete, UPDATE GuestRequest
                await GuestRequestRules.UpdateAsync(request);

                return(request);
            }
            catch (Exception ex)
            {
                var reason = (serverResponse == null ? "N/A" : serverResponse.ResponseContent);
                responseData.ErrorInfo   = string.Format("Error: {0}<br>Server response: {1}", ex.Message, reason);
                request.InvitationResult = responseData;

                //UPDATE GuestRequest
                await GuestRequestRules.UpdateAsync(request);

                return(request);
            }
        }