📄 usersstorageprovider.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using ScrewTurn.Wiki.PluginFramework;
namespace ScrewTurn.Wiki {
/// <summary>
/// Implements a Users Storage Provider.
/// </summary>
[Serializable]
public class UsersStorageProvider : IUsersStorageProvider {
/// <summary>
/// Used as lock object for multithreaded operations.
/// </summary>
private object locker = new object();
private ComponentInformation info = new ComponentInformation("Local Users Provider", "ScrewTurn Software", "http://www.screwturn.eu");
private IHost host;
/// <summary>
/// Initializes the Provider.
/// </summary>
/// <param name="host">The Host of the Provider.</param>
/// <param name="config">The Configuration data, if any.</param>
public void Init(IHost host, string config) {
this.host = host;
}
/// <summary>
/// Method invoked on shutdown.
/// </summary>
/// <remarks>This method might not be invoked in some cases.</remarks>
public void Shutdown() { }
/// <summary>
/// Gets the Information about the Provider.
/// </summary>
public ComponentInformation Information {
get { return info; }
}
/// <summary>
/// Gets a value specifying whether the provider is read-only, i.e. it can only provide data and not store it.
/// </summary>
public bool ReadOnly {
get { return false; }
}
/// <summary>
/// Tests a Password for a User account.
/// </summary>
/// <param name="user">The User account.</param>
/// <param name="password">The Password to test.</param>
/// <returns>True if the Password is correct.</returns>
public bool TestAccount(UserInfo user, string password) {
return Hash.Compute(password).Equals(((LocalUserInfo)user).PasswordHash);
}
/// <summary>
/// Gets all the Users.
/// </summary>
/// <remarks>The array is unsorted.</remarks>
public UserInfo[] AllUsers {
get {
string tmp;
lock(locker) {
tmp = Tools.LoadFile(Settings.UsersFile).Replace("\r", "");
}
string[] lines = tmp.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
UserInfo[] result = new UserInfo[lines.Length];
string[] fields;
for(int i = 0; i < lines.Length; i++) {
fields = lines[i].Split('|');
// Structure:
// Username|PasswordHash|Email|Active-Inactive|DateTime|Admin-User
result[i] = new LocalUserInfo(fields[0], fields[2], fields[3].ToLower().Equals("active"),
DateTime.Parse(fields[4]), fields[5].ToLower().Equals("admin"), this, fields[1]);
}
return result;
}
}
/// <summary>
/// Searches for a User.
/// </summary>
/// <param name="user">The User to search for.</param>
/// <returns>True if the User already exists.</returns>
private bool Exists(UserInfo user) {
UserInfo[] users = AllUsers;
UsernameComparer comp = new UsernameComparer();
for(int i = 0; i < users.Length; i++) {
if(comp.Compare(users[i], user) == 0) return true;
}
return false;
}
/// <summary>
/// Adds a new User.
/// </summary>
/// <param name="username">The Username.</param>
/// <param name="password">The Password.</param>
/// <param name="email">The Email address.</param>
/// <param name="active">A value specifying whether or not the account is active.</param>
/// <param name="dateTime">The Account creation Date/Time.</param>
/// <param name="admin">A value specifying whether or not the User is an Administrator.</param>
/// <returns>The correct UserInfo object or null.</returns>
public UserInfo AddUser(string username, string password, string email, bool active, DateTime dateTime, bool admin) {
if(Exists(new UserInfo(username, "", true, DateTime.Now, false, this))) return null;
lock(locker) {
StringBuilder sb = new StringBuilder();
sb.Append("\r\n"); // Important
sb.Append(username);
sb.Append("|");
sb.Append(Hash.Compute(password));
sb.Append("|");
sb.Append(email);
sb.Append("|");
sb.Append(active ? "ACTIVE" : "INACTIVE");
sb.Append("|");
sb.Append(dateTime.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss"));
sb.Append("|");
sb.Append(admin ? "ADMIN" : "USER");
Tools.AppendFile(Settings.UsersFile, sb.ToString());
}
return new LocalUserInfo(username, email, active, dateTime, admin, this, Hash.Compute(password));
}
/// <summary>
/// Sets the Active/Inactive status of a User.
/// </summary>
/// <param name="user">The User.</param>
/// <param name="active">The status.</param>
/// <returns>The correct UserInfo object.</returns>
public UserInfo SetUserActivationStatus(UserInfo user, bool active) {
lock(locker) {
UserInfo[] users = AllUsers;
UsernameComparer comp = new UsernameComparer();
for(int i = 0; i < users.Length; i++) {
if(comp.Compare(users[i], user) == 0) {
LocalUserInfo tmp = new LocalUserInfo(user.Username, user.Email, active, user.DateTime, user.Admin, this, ((LocalUserInfo)user).PasswordHash);
users[i] = tmp;
DumpUsers(users);
return tmp;
}
}
}
return null;
}
/// <summary>
/// Sets the User/Administrator status of a User.
/// </summary>
/// <param name="user">The User.</param>
/// <param name="active">The status.</param>
/// <returns>True if the User's status has been changed successfully.</returns>
public UserInfo SetUserAdministrationStatus(UserInfo user, bool admin) {
lock(locker) {
UserInfo[] users = AllUsers;
UsernameComparer comp = new UsernameComparer();
for(int i = 0; i < users.Length; i++) {
if(comp.Compare(users[i], user) == 0) {
LocalUserInfo tmp = new LocalUserInfo(user.Username, user.Email, user.Active, user.DateTime, admin, this, ((LocalUserInfo)user).PasswordHash);
users[i] = tmp;
DumpUsers(users);
return tmp;
}
}
}
return null;
}
/// <summary>
/// Removes a User.
/// </summary>
/// <param name="user">The User to remove.</param>
/// <returns>True if the User has been removed successfully.</returns>
public bool RemoveUser(UserInfo user) {
lock(locker) {
UserInfo[] users = AllUsers;
UsernameComparer comp = new UsernameComparer();
int idx = -1;
for(int i = 0; i < users.Length; i++) {
if(comp.Compare(users[i], user) == 0) {
idx = i;
break;
}
}
List<UserInfo> tmp = new List<UserInfo>(users);
tmp.Remove(tmp[idx]);
DumpUsers(tmp.ToArray());
}
return true;
}
/// <summary>
/// Changes the Email address of a User.
/// </summary>
/// <param name="user">The User to change the Email address to.</param>
/// <param name="newEmail">The new Email address.</param>
/// <returns>The correct UserInfo object.</returns>
public UserInfo ChangeEmail(UserInfo user, string newEmail) {
lock(locker) {
UserInfo[] users = AllUsers;
UsernameComparer comp = new UsernameComparer();
for(int i = 0; i < users.Length; i++) {
if(comp.Compare(users[i], user) == 0) {
users[i].Email = newEmail;
DumpUsers(users);
return users[i];
}
}
}
return null;
}
/// <summary>
/// Changes the Password of a User.
/// </summary>
/// <param name="user">The User to change the Password to.</param>
/// <param name="newPassword">The new Password (plain text).</param>
/// <returns>The correct UserInfo object.</returns>
public UserInfo ChangePassword(UserInfo user, string newPassword) {
lock(locker) {
UserInfo[] users = AllUsers;
UsernameComparer comp = new UsernameComparer();
for(int i = 0; i < users.Length; i++) {
if(comp.Compare(users[i], user) == 0) {
((LocalUserInfo)users[i]).PasswordHash = Hash.Compute(newPassword);
DumpUsers(users);
return users[i];
}
}
}
return null;
}
/// <summary>
/// Writes on disk all the Users.
/// </summary>
/// <param name="users">The User list.</param>
/// <remarks>This method does not lock resources, therefore a lock is need in the caller.</remarks>
private void DumpUsers(UserInfo[] users) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < users.Length; i++) {
LocalUserInfo u = (LocalUserInfo)users[i];
sb.Append(u.Username);
sb.Append("|");
sb.Append(u.PasswordHash);
sb.Append("|");
sb.Append(u.Email);
sb.Append("|");
sb.Append(u.Active ? "ACTIVE" : "INACTIVE");
sb.Append("|");
sb.Append(u.DateTime.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss"));
sb.Append("|");
sb.Append(u.Admin ? "ADMIN" : "USER");
if(i != users.Length - 1) sb.Append("\r\n");
}
Tools.WriteFile(Settings.UsersFile, sb.ToString());
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -