1 module vibelog.user;
2 
3 import vibe.data.bson;
4 import vibe.textfilter.markdown;
5 import vibe.textfilter.html;
6 
7 import std.array;
8 import std.base64;
9 import std.conv;
10 import std.exception;
11 import std.md5;
12 import std.random;
13 public import std.datetime;
14 
15 
16 class User {
17 	BsonObjectID _id;
18 	string username;
19 	string name;
20 	string email;
21 	string password;
22 	string[] groups;
23 	string[] allowedCategories;
24 
25 	this()
26 	{
27 		_id = BsonObjectID.generate();
28 	}
29 
30 	bool inGroup(string group) const {
31 		foreach( g; groups )
32 			if( g == group )
33 				return true;
34 		return false;
35 	}
36 
37 	bool isConfigAdmin() const { return inGroup("admin"); }
38 	bool isUserAdmin() const { return inGroup("admin"); }
39 	bool isPostAdmin() const { return inGroup("admin"); }
40 	bool mayPostInCategory(string category){
41 		if( isPostAdmin() ) return true;
42 		foreach( c; allowedCategories )
43 			if( c == category )
44 				return true;
45 		return false;
46 	}
47 
48 	static User fromBson(Bson bson)
49 	{
50 		auto ret = new User;
51 		ret._id = cast(BsonObjectID)bson["_id"];
52 		ret.username = cast(string)bson["username"];
53 		ret.name = cast(string)bson["name"];
54 		ret.email = cast(string)bson["email"];
55 		ret.password = cast(string)bson["password"];
56 		foreach( grp; cast(Bson[])bson["groups"] )
57 			ret.groups ~= cast(string)grp;
58 		foreach( cat; cast(Bson[])bson["allowedCategories"] )
59 			ret.allowedCategories ~= cast(string)cat;
60 		return ret;
61 	}
62 	
63 	Bson toBson()
64 	const {
65 		Bson[] bgroups;
66 		foreach( grp; groups )
67 			bgroups ~= Bson(grp);
68 
69 		Bson[] bcats;
70 		foreach( cat; allowedCategories )
71 			bcats ~= Bson(cat);
72 
73 		Bson[string] ret;
74 		ret["_id"] = Bson(_id);
75 		ret["username"] = Bson(username);
76 		ret["name"] = Bson(name);
77 		ret["email"] = Bson(email);
78 		ret["password"] = Bson(password);
79 		ret["groups"] = Bson(bgroups);
80 		ret["allowedCategories"] = Bson(bcats);
81 
82 		return Bson(ret);
83 	}
84 }
85 
86 bool testPassword(string password, string hashstring)
87 {
88 	ubyte[] upass = Base64.decode(hashstring);
89 	enforce(upass.length == 20);
90 	auto salt = upass[0 .. 4];
91 	auto hashcmp = upass[4 .. 20];
92 	ubyte[16] hash;
93 	sum(hash, salt, password);
94 	return hash == hashcmp;
95 }
96 
97 string generatePasswordHash(string password)
98 {
99 	ubyte[4] salt;
100 	foreach( i; 0 .. 4 ) salt[i] = cast(ubyte)uniform(0, 256);
101 	ubyte[16] hash;
102 	sum(hash, salt ~ cast(ubyte[])password);
103 	return Base64.encode(salt ~ hash).idup;
104 }