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 }