예제 #1
0
        /// <summary>
        /// Creates or Finds a Person and UserLogin record, and returns the userLogin.UserName
        /// </summary>
        /// <param name="auth0UserInfo">The auth0 user information.</param>
        /// <returns></returns>
        public static string GetAuth0UserName(Auth0UserInfo auth0UserInfo)
        {
            string username = string.Empty;

            string    userName = "******" + auth0UserInfo.sub;
            UserLogin user     = null;

            using (var rockContext = new RockContext())
            {
                // Query for an existing user
                var userLoginService = new UserLoginService(rockContext);
                user = userLoginService.GetByUserName(userName);

                // If no user was found, see if we can find a match in the person table
                if (user == null)
                {
                    // Get name/email from auth0 userinfo
                    string lastName  = auth0UserInfo.family_name?.Trim()?.FixCase();
                    string firstName = auth0UserInfo.given_name?.Trim()?.FixCase();
                    string nickName  = auth0UserInfo.nickname?.Trim()?.FixCase();
                    string email     = auth0UserInfo.email;

                    Person person = null;

                    // If person had an email, get the first person with the same name and email address.
                    if (!string.IsNullOrWhiteSpace(email))
                    {
                        var personService = new PersonService(rockContext);
                        var people        = personService.GetByMatch(firstName, lastName, email);
                        if (people.Count() == 1)
                        {
                            person = people.First();
                        }
                    }

                    var personRecordTypeId  = DefinedValueCache.Read(SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id;
                    var personStatusPending = DefinedValueCache.Read(SystemGuid.DefinedValue.PERSON_RECORD_STATUS_PENDING.AsGuid()).Id;

                    rockContext.WrapTransaction(() =>
                    {
                        if (person == null)
                        {
                            person                     = new Person();
                            person.IsSystem            = false;
                            person.RecordTypeValueId   = personRecordTypeId;
                            person.RecordStatusValueId = personStatusPending;
                            person.FirstName           = firstName;
                            person.LastName            = lastName;
                            person.Email               = email;
                            person.IsEmailActive       = true;
                            person.EmailPreference     = EmailPreference.EmailAllowed;

                            if (auth0UserInfo.gender == "male")
                            {
                                person.Gender = Gender.Male;
                            }
                            else if (auth0UserInfo.gender == "female")
                            {
                                person.Gender = Gender.Female;
                            }
                            else
                            {
                                person.Gender = Gender.Unknown;
                            }

                            if (person != null)
                            {
                                PersonService.SaveNewPerson(person, rockContext, null, false);
                            }
                        }

                        if (person != null)
                        {
                            int typeId      = EntityTypeCache.Read(typeof(Auth0Authentication)).Id;
                            user            = UserLoginService.Create(rockContext, person, AuthenticationServiceType.External, typeId, userName, "auth0", true);
                            user.ForeignKey = auth0UserInfo.sub;
                        }
                    });
                }

                if (user != null)
                {
                    username = user.UserName;

                    if (user.PersonId.HasValue)
                    {
                        var personService = new PersonService(rockContext);
                        var person        = personService.Get(user.PersonId.Value);
                        if (person != null)
                        {
                            // If person does not have a photo, try to get the photo return with auth0
                            if (!person.PhotoId.HasValue && !string.IsNullOrWhiteSpace(auth0UserInfo.picture))
                            {
                                // Download the photo from the url provided
                                var restClient   = new RestClient(auth0UserInfo.picture);
                                var restRequest  = new RestRequest(Method.GET);
                                var restResponse = restClient.Execute(restRequest);
                                if (restResponse.StatusCode == HttpStatusCode.OK)
                                {
                                    var bytes = restResponse.RawBytes;

                                    // Create and save the image
                                    BinaryFileType fileType = new BinaryFileTypeService(rockContext).Get(Rock.SystemGuid.BinaryFiletype.PERSON_IMAGE.AsGuid());
                                    if (fileType != null)
                                    {
                                        var binaryFileService = new BinaryFileService(rockContext);
                                        var binaryFile        = new BinaryFile();
                                        binaryFileService.Add(binaryFile);
                                        binaryFile.IsTemporary    = false;
                                        binaryFile.BinaryFileType = fileType;
                                        binaryFile.MimeType       = restResponse.ContentType;
                                        binaryFile.FileName       = user.Person.NickName + user.Person.LastName + ".jpg";
                                        binaryFile.FileSize       = bytes.Length;
                                        binaryFile.ContentStream  = new System.IO.MemoryStream(bytes);

                                        rockContext.SaveChanges();

                                        person.PhotoId = binaryFile.Id;
                                        rockContext.SaveChanges();
                                    }
                                }
                            }
                        }
                    }
                }

                return(username);
            }
        }
예제 #2
0
        /// <summary>
        /// Authenticates the user based on a request from a third-party provider.  Will set the username and returnUrl values.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="userName">Name of the user.</param>
        /// <param name="returnUrl">The return URL.</param>
        /// <returns></returns>
        public override bool Authenticate(System.Web.HttpRequest request, out string userName, out string returnUrl)
        {
            string authDomain   = this.GetAttributeValue("ClientDomain");
            string clientId     = this.GetAttributeValue("ClientID");
            string clientSecret = this.GetAttributeValue("ClientSecret");

            userName  = string.Empty;
            returnUrl = request.QueryString["state"];
            string code        = request.QueryString["code"];
            string redirectUri = GetRedirectUrl(request);

            // see: https://auth0.com/docs/api/authentication#support
            var restClient           = new RestClient($"https://{authDomain}");
            var authTokenRequest     = new RestRequest("oauth/token", Method.POST);
            var authTokenRequestBody = new
            {
                grant_type    = "authorization_code",
                client_id     = clientId,
                client_secret = clientSecret,
                code,
                redirect_uri = redirectUri
            };

            authTokenRequest.AddJsonBody(authTokenRequestBody);

            var authTokenRestResponse = restClient.Execute(authTokenRequest);

            if (authTokenRestResponse.StatusCode == HttpStatusCode.OK)
            {
                Auth0TokenResponse authTokenResponse = authTokenRestResponse.Content.FromJsonOrNull <Auth0TokenResponse>();
                if (authTokenResponse != null)
                {
                    var userInfoRequest      = new RestRequest($"userinfo?access_token={authTokenResponse.access_token}", Method.GET);
                    var userInfoRestResponse = restClient.Execute(userInfoRequest);
                    if (userInfoRestResponse.StatusCode == HttpStatusCode.OK)
                    {
                        Auth0UserInfo auth0UserInfo = userInfoRestResponse.Content.FromJsonOrNull <Auth0UserInfo>();

                        var managementTokenRequest     = new RestRequest("oauth/token", Method.POST);
                        var managementTokenRequestBody = new
                        {
                            grant_type    = "client_credentials",
                            client_id     = clientId,
                            client_secret = clientSecret,
                            audience      = $"https://{authDomain}/api/v2/"
                        };

                        managementTokenRequest.AddJsonBody(managementTokenRequestBody);

                        var managementTokenRestResponse = restClient.Execute(managementTokenRequest);
                        if (managementTokenRestResponse.StatusCode == HttpStatusCode.OK)
                        {
                            Auth0TokenResponse managementTokenResponse = managementTokenRestResponse.Content.FromJsonOrNull <Auth0TokenResponse>();
                            var managementUserLookupRequest            = new RestRequest($"api/v2/users/{auth0UserInfo.sub}", Method.GET);
                            managementUserLookupRequest.AddHeader("authorization", $"Bearer {managementTokenResponse?.access_token}");
                            var managementUserLookupResponse = restClient.Execute(managementUserLookupRequest);

                            if (managementUserLookupResponse.StatusCode == HttpStatusCode.OK)
                            {
                                // if we were able to look up the user using the management api, fill in null given_name from user_metadata or app_metadata;
                                var managementUserInfo = managementUserLookupResponse.Content.FromJsonOrNull <Auth0ManagementUserInfo>();

                                if (managementUserInfo != null)
                                {
                                    if (auth0UserInfo.given_name == null)
                                    {
                                        auth0UserInfo.given_name = managementUserInfo.user_metadata?.given_name ?? managementUserInfo.app_metadata?.given_name;

                                        // if we had to get given_name from user_metadata/app_metadata, then the nickname that we got back might not be correct, so just have it be given_name
                                        auth0UserInfo.nickname = auth0UserInfo.given_name;
                                    }

                                    if (auth0UserInfo.family_name == null)
                                    {
                                        auth0UserInfo.family_name = managementUserInfo.user_metadata?.family_name ?? managementUserInfo.app_metadata?.family_name;
                                    }
                                }
                            }
                        }


                        userName = GetAuth0UserName(auth0UserInfo);

                        return(true);
                    }
                }
            }

            return(false);
        }