public override AuthenticationResponse VerifyPassword(AuthenticationRequest request)
        {
            // User needs to be authenticated in the scope of a project (tenant).
            // Since a tenant with the same name is generated for each user in keystone, we
            // use the username as project name.
            var project = new Keystone.Project()
            {
                Domain = new Keystone.Domain()
                {
                    Name = settings.Domain.ToLowerInvariant()
                },
                Name = request.Username.ToLowerInvariant()
            };

            // Verify user password in Keystone, we don't use
            // Graywulf password in this case
            var token = KeystoneClient.Authenticate(settings.Domain.ToLowerInvariant(), request.Username.ToLowerInvariant(), request.Password, project);

            // Find user details in keystone
            token.User = GetKeystoneUser(request.Username);

            // Create a response, this sets necessary response headers
            var response = new AuthenticationResponse(request);
            settings.UpdateAuthenticationResponse(response, token, true);

            // Load user from the graywulf registry. This call will create the user
            // if necessary because authority is set to master
            LoadOrCreateUser(response.Principal.Identity);

            return response;
        }
        protected override void OnCreateUser(User user)
        {
            // Create user in keystone
            var keystoneUser = KeystoneClient.Create(ConvertUser(user));

            // Create and associated project (tenant)
            var keystoneProject = new Keystone.Project
            {
                Name = user.Name.ToLowerInvariant(),
                DomainID = settings.Domain.ToLowerInvariant(),
            };
            keystoneProject = KeystoneClient.Create(keystoneProject);

            // Create user locally
            base.OnCreateUser(user);

            // Grant user roles on the project just created. This is necessary to
            // gain access to services like swift.
            // Project has no equivalent in graywulf (because users are not associated
            // with federations but only with domains). Hence, project name is simply
            // taken from the username.
            foreach (var userRole in user.UserRoleMemberships.Values.Where(r => r.UserRole.Default))
            {
                var roles = KeystoneClient.FindRoles(settings.Domain, userRole.Name, true, false);
                if (roles == null || roles.Length == 0)
                {
                    throw new Exception("No matching role found");      // TODO: ***
                }
                var role = roles[0];
                KeystoneClient.GrantRole(keystoneProject, keystoneUser, role);
            }

            // Add identity to local principal
            var principal = settings.CreateAuthenticatedPrincipal(keystoneUser, true);
            AddUserIdentity(user, principal.Identity);
        }
        public KeystoneClient CreateClient()
        {
            var ksclient = new KeystoneClient(AuthorityUri);

            // If using password authentication, make sure we have a valid admin token
            // Leave e 30 second margin to perform all keystone-related operations with an
            // already existing token
            if (!String.IsNullOrWhiteSpace(adminPassword) && (DateTime.Now - adminTokenExpiresAt).TotalSeconds > -30)
            {
                lock (this)
                {
                    var project = new Keystone.Project()
                    {
                        Domain = new Keystone.Domain()
                        {
                            Name = domain
                        },
                        Name = adminProject
                    };

                    var token = ksclient.Authenticate(domain, adminUserName, adminPassword, project);

                    adminToken = token.ID;
                    adminTokenExpiresAt = token.ExpiresAt;
                }
            }

            // Set the valid admin token
            ksclient.AdminAuthToken = adminToken;

            return ksclient;
        }