Beispiel #1
0
        public void Handle(ReceiveSamlAuthnResponseCommand command)
        {
            if (command == null)
            {
                throw new ArgumentNullException("command");
            }
            if (command.SamlResponse == null)
            {
                throw new InvalidOperationException("The SAML Response cannot be null.");
            }
            var samlResponse = command.SamlResponse;

            // get the trusted establishment for this saml 2 response
            var establishment = GetTrustedIssuingEstablishment(samlResponse);

            // verify the response's signature
            VerifySignature(samlResponse);

            // first try to find user by SAML person targeted id
            var user = GetUserByEduPersonTargetedId(samlResponse);

            // when saml user does not exist, search for person
            if (user == null)
            {
                var person = GetPerson(samlResponse);
                user = person.User ?? new User {
                    Person = person
                };
            }

            // delete local account if it exists
            if (!string.IsNullOrWhiteSpace(user.Name) && _passwords.Exists(user.Name))
            {
                _passwords.Destroy(user.Name);
            }

            // enforce invariants on user
            user.Name = samlResponse.EduPersonPrincipalName;
            user.EduPersonTargetedId = samlResponse.EduPersonTargetedId;
            user.IsRegistered        = true;

            // remove previous scoped affiliations and add new ones
            var oldScopedAffiliations = user.EduPersonScopedAffiliations.ToArray();
            var newScopedAffiliations = samlResponse.EduPersonScopedAffiliations ?? new string[] {};

            newScopedAffiliations = newScopedAffiliations.Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
            foreach (var oldScopedAffiliation in oldScopedAffiliations)
            {
                if (!newScopedAffiliations.Contains(oldScopedAffiliation.Value))
                {
                    user.EduPersonScopedAffiliations.Remove(oldScopedAffiliation);
                }
            }
            foreach (var newScopedAffiliation in newScopedAffiliations)
            {
                if (oldScopedAffiliations.ByValue(newScopedAffiliation) == null)
                {
                    user.EduPersonScopedAffiliations.Add(
                        new EduPersonScopedAffiliation
                    {
                        Value  = newScopedAffiliation,
                        Number = user.EduPersonScopedAffiliations.NextNumber(),
                    });
                }
            }

            // log the subject name id
            var subjectNameId = samlResponse.SubjectNameIdentifier;

            if (!string.IsNullOrWhiteSpace(subjectNameId))
            {
                var subjectNameIdentifier = user.SubjectNameIdentifiers.ByValue(subjectNameId);
                if (subjectNameIdentifier == null)
                {
                    user.SubjectNameIdentifiers.Add(
                        new SubjectNameIdentifier
                    {
                        Value  = subjectNameId,
                        Number = user.SubjectNameIdentifiers.NextNumber(),
                    });
                }
                else
                {
                    subjectNameIdentifier.UpdatedOnUtc = DateTime.UtcNow;
                }
            }


            // enforce invariants on person
            if (!user.Person.IsAffiliatedWith(establishment))
            {
                user.Person.AffiliateWith(establishment);
            }

            // remove previous saml mails, add new ones, and update existing ones
            var oldSamlMails = user.Person.Emails.FromSaml().ToArray();
            var newSamlMails = samlResponse.Mails ?? new string[] {};

            newSamlMails = newSamlMails.Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
            foreach (var oldSamlMail in oldSamlMails)
            {
                if (!newSamlMails.Contains(oldSamlMail.Value))
                {
                    user.Person.Emails.Remove(oldSamlMail);
                }
            }
            foreach (var newSamlMail in newSamlMails)
            {
                if (user.Person.GetEmail(newSamlMail) == null)
                {
                    user.Person.AddEmail(newSamlMail);
                }
            }
            foreach (var emailAddress in user.Person.Emails)
            {
                if (newSamlMails.Contains(emailAddress.Value))
                {
                    emailAddress.IsFromSaml  = true;
                    emailAddress.IsConfirmed = true;
                }
            }

            // make sure person has at least 1 confirmed email address
            var defaultEmail = user.Person.DefaultEmail;

            if (defaultEmail == null || !defaultEmail.IsConfirmed)
            {
                if (defaultEmail != null)
                {
                    defaultEmail.IsDefault = false;
                }
                defaultEmail             = user.Person.AddEmail(samlResponse.EduPersonPrincipalName);
                defaultEmail.IsDefault   = true;
                defaultEmail.IsConfirmed = true;
            }

            // update db
            if (user.RevisionId == 0)
            {
                _entities.Create(user);
            }
            else
            {
                _entities.Update(user);
            }
            _unitOfWork.SaveChanges();

            // sign on user
            _userSigner.SignOn(user.Name);
        }