Reset/Change a Password

Overview

Password management is a critical security function in the acre Access Control platform. This guide covers two distinct operations: resetting your own password (requires current password) and forcing a password change for another user (administrative action).

Key Concepts

Operation Method Who Can Do It Notification
Reset Password ResetPasswordAsync Current user only No email notification
Change Password ChangePasswordAsync Administrators Email sent to user with new password

Password Requirements

Requirement Description
Minimum Length Typically 8+ characters (configurable by instance)
Complexity May require uppercase, lowercase, numbers, special characters
History Cannot reuse recent passwords
Expiration May expire after configured period

Prerequisites

Before managing passwords, ensure you have:

  • ✅ Valid API authentication
  • ✅ Knowledge of current password (for reset)
  • ✅ Administrative permissions (for changing other users’ passwords)

C# Examples

Reset Your Own Password

Use this method when you know your current password and want to change it.

using Feenics.Keep.WebApi.Wrapper;
using Feenics.Keep.WebApi.Model;

// Reset the current user's password
// Requires: knowledge of old password
try
{
    await client.ResetPasswordAsync("CurrentPassword123!", "NewSecurePassword456!");
    Console.WriteLine("Password reset successfully");
}
catch (Exception ex)
{
    Console.WriteLine($"Password reset failed: {ex.Message}");
    // Common reasons: wrong current password, password doesn't meet complexity requirements
}

Change Another User’s Password (Administrative)

Use this method as an administrator to force a password change for any user. The user will receive an email notification with the new password.

// Get the target user by searching for their username
var users = await client.SearchAsync<UserInfo>(
    currentInstance,
    "{\"_t\":\"User\",\"Username\":\"john.smith@company.com\"}",
    0,
    1
);
var userInfo = users.FirstOrDefault();

if (userInfo != null)
{
    // Force password change (user will be notified via email)
    try
    {
        await client.ChangePasswordAsync(userInfo, "TemporaryPassword789!");
        Console.WriteLine($"Password changed for {userInfo.CommonName}");
        Console.WriteLine("User has been notified via email");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Failed to change password: {ex.Message}");
    }
}
else
{
    Console.WriteLine("User not found");
}
}

Get Current User Information

// Get information about the currently authenticated user
var currentUser = await client.GetCurrentUserAsync();

Console.WriteLine($"Current User: {currentUser.CommonName}");
Console.WriteLine($"Username: {currentUser.Username}");
Console.WriteLine($"Email: {currentUser.Email}");
Console.WriteLine($"Key: {currentUser.Key}");

Complete Password Management Utility

/// <summary>
/// Password management utility class
/// </summary>
public class PasswordManager
{
    private readonly Client _client;
    
    public PasswordManager(Client client)
    {
        _client = client;
    }
    
    /// <summary>
    /// Resets the current user's password
    /// </summary>
    public async Task<bool> ResetOwnPasswordAsync(string oldPassword, string newPassword)
    {
        try
        {
            // Validate password requirements before attempting
            if (!ValidatePassword(newPassword, out var error))
            {
                Console.WriteLine($"Password validation failed: {error}");
                return false;
            }
            
            await _client.ResetPasswordAsync(oldPassword, newPassword);
            Console.WriteLine("Password reset successfully");
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Password reset failed: {ex.Message}");
            return false;
        }
    }
    
    /// <summary>
    /// Forces a password change for another user (admin only)
    /// </summary>
    public async Task<bool> ForcePasswordChangeAsync(string username, string newPassword)
    {
        try
        {
            // Search for user by username
            var users = await _client.SearchAsync<UserInfo>(
                _currentInstance,
                $"{{\"_t\":\"User\",\"Username\":\"{username}\"}}",
                0,
                1
            );
            var user = users.FirstOrDefault();
            
            if (user == null)
            {
                Console.WriteLine($"User not found: {username}");
                return false;
            }
            
            await _client.ChangePasswordAsync(user, newPassword);
            Console.WriteLine($"Password changed for {user.CommonName}");
            Console.WriteLine($"Notification sent to: {user.Email}");
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to change password: {ex.Message}");
            return false;
        }
    }
    
    /// <summary>
    /// Generates a random secure password
    /// </summary>
    public static string GenerateSecurePassword(int length = 12)
    {
        const string uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        const string lowercase = "abcdefghijklmnopqrstuvwxyz";
        const string digits = "0123456789";
        const string special = "!@#$%^&*";
        
        var random = new Random();
        var password = new char[length];
        
        // Ensure at least one of each required type
        password[0] = uppercase[random.Next(uppercase.Length)];
        password[1] = lowercase[random.Next(lowercase.Length)];
        password[2] = digits[random.Next(digits.Length)];
        password[3] = special[random.Next(special.Length)];
        
        // Fill remaining with random characters
        var allChars = uppercase + lowercase + digits + special;
        for (int i = 4; i < length; i++)
        {
            password[i] = allChars[random.Next(allChars.Length)];
        }
        
        // Shuffle the password
        return new string(password.OrderBy(x => random.Next()).ToArray());
    }
    
    private bool ValidatePassword(string password, out string error)
    {
        error = string.Empty;
        
        if (password.Length < 8)
        {
            error = "Password must be at least 8 characters";
            return false;
        }
        
        if (!password.Any(char.IsUpper))
        {
            error = "Password must contain at least one uppercase letter";
            return false;
        }
        
        if (!password.Any(char.IsLower))
        {
            error = "Password must contain at least one lowercase letter";
            return false;
        }
        
        if (!password.Any(char.IsDigit))
        {
            error = "Password must contain at least one number";
            return false;
        }
        
        return true;
    }
}

// Usage
var passwordManager = new PasswordManager(client);

// Reset own password
await passwordManager.ResetOwnPasswordAsync("OldPass123!", "NewPass456!");

// Force change for another user
await passwordManager.ForcePasswordChangeAsync("jane.doe@company.com", "TempPass789!");

// Generate secure password
var securePassword = PasswordManager.GenerateSecurePassword(16);
Console.WriteLine($"Generated password: {securePassword}");

cURL Examples

Reset Your Own Password

ACCESS_TOKEN="your-access-token"

curl -X PUT \
  "https://api.us.acresecurity.cloud/api/currentuser/resetpassword" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "$type": "Feenics.Keep.WebApi.Model.ResetPasswordRequest, Feenics.Keep.WebApi.Model",
    "OldPassword": "CurrentPassword123!",
    "NewPassword": "NewSecurePassword456!"
  }'

Change Another User’s Password (Administrative)

INSTANCE_KEY="your-instance-key"
USER_KEY="target-user-key"
NEW_PASSWORD="TemporaryPassword789!"

curl -X POST \
  "https://api.us.acresecurity.cloud/api/f/${INSTANCE_KEY}/users/${USER_KEY}/password" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "\"${NEW_PASSWORD}\""

Get Current User Information

curl -X GET \
  "https://api.us.acresecurity.cloud/api/currentuser" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

Search for User by Username

INSTANCE_KEY="your-instance-key"
USERNAME="john.smith@company.com"

curl -X POST \
  "https://api.us.acresecurity.cloud/api/f/${INSTANCE_KEY}/search?page=0&pageSize=1" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{\"_t\":\"User\",\"Username\":\"${USERNAME}\"}"

Security Considerations

Consideration Recommendation
Audit Logging All password changes are logged for security audits
Email Notifications Force change sends email with new password
Session Invalidation Password change may invalidate active sessions
Rate Limiting Multiple failed attempts may trigger lockout
Temporary Passwords Require users to change temp passwords on first login

Best Practices

Practice Description
Use strong passwords Minimum 12 characters with mixed case, numbers, symbols
Don’t reuse passwords Each account should have a unique password
Communicate securely Don’t share passwords via insecure channels
Force temp password change Users should change admin-set passwords immediately
Log password changes Keep audit trail of who changed what when
Implement password policies Configure instance-level password requirements

Troubleshooting

Issue Possible Cause Solution
Reset fails Wrong current password Verify current password is correct
Complexity error Password too weak Add uppercase, numbers, special characters
User not found Wrong username or instance Verify user exists in current instance
Permission denied Insufficient privileges Admin role required for changing others’ passwords
Email not received Invalid email address Verify user’s email is configured correctly
Account locked Too many failed attempts Wait for lockout period or contact admin