public static DBNote ToDBNote(this DTONote dto, DBUser user, bool encrypt = false) { // ServiceStack's .PopulateWith is for some reasons // ORDERS of magnitudes slower than manually copying // TODO evaluate PopulateWith performance / bottleneck // or other mappers like ValueInjecter var db = new DBNote (); db.Guid = dto.Guid; db.Title = dto.Title; db.Text = dto.Text; db.Tags = dto.Tags; // dates db.ChangeDate = dto.ChangeDate; db.MetadataChangeDate = dto.MetadataChangeDate; db.CreateDate = dto.CreateDate; db.OpenOnStartup = dto.OpenOnStartup; db.Pinned = dto.Pinned; db.Username = user.Username; return db; }
public static void AddDummyUserIfRequired(Funq.Container container) { // create a dummy user var fac = container.Resolve<IDbConnectionFactory> (); using (var db = fac.OpenDbConnection ()) { if (db.FirstOrDefault<DBUser> (u => u.Username == "dummy") == null) { var user = new DBUser (); user.Username = "******"; user.CreateCryptoFields ("foobar123"); user.FirstName = "John Dummy"; user.LastName = "Doe"; user.AdditionalData = "Dummy user that is created when in development mode"; user.IsActivated = true; user.IsVerified = true; user.Manifest.LastSyncRevision = 0; user.EmailAddress = "*****@*****.**"; db.Insert<DBUser> (user); // insert some sample notes var f = container.Resolve<IDbStorageFactory> (); var key = user.GetPlaintextMasterKey ("foobar123"); var r = new RequestingUser { Username = "******", EncryptionMasterKey = key.ToHexString () }; using (var storage = f.GetDbStorage (r)) { var sample_notes = new DiskStorage (); sample_notes.SetPath ("../../../sample_notes/"); sample_notes.CopyTo (storage); } } } }
public DbStorage(DBUser user) { this.db = DbConfig.GetConnection (); this.User = user; // start everything as a transaction trans = db.BeginTransaction (); }
public void CreateCryptoFieldsForNewUser() { var u = new DBUser (); u.Username = "******"; u.CreateCryptoFields ("foobar"); Assert.GreaterOrEqual (u.EncryptedMasterKey.Length, 32); Assert.That (u.EncryptedMasterKey.Length % 2 == 0); }
public void GetPlaintextMasterKeyReturns256Bit() { var u = new DBUser (); u.Username = "******"; var password = "******"; u.CreateCryptoFields (password); var master_key = u.GetPlaintextMasterKey (password); Assert.AreEqual(32, master_key.Length); }
public DbEncryptedStorage(IDbConnectionFactory factory, DBUser user, string encryption_master_key, bool use_history = true) : base(factory, user.Username, use_history) { this.User = user; if (encryption_master_key == null) throw new ArgumentNullException ("encryption_master_key"); encryptionMasterKey = encryption_master_key; }
public void GetPlaintextMasterKeyReturnsSameKeyForSamePassword() { var u = new DBUser (); u.Username = "******"; var password = "******"; u.CreateCryptoFields (password); var key1 = u.GetPlaintextMasterKey (password); var key2 = u.GetPlaintextMasterKey (password); Assert.AreEqual (key1, key2); Assert.AreEqual (key1.ToHexString (), key2.ToHexString ()); }
public DbEncryptedStorage(IDbConnectionFactory factory, DBUser user, string encryption_master_key, bool use_history = true) : base(factory, user.Username, user.Manifest, use_history) { this.User = user; if (encryption_master_key == null) { throw new ArgumentNullException("encryption_master_key"); } encryptionMasterKey = encryption_master_key; }
public DatabaseNoteRepository(IDbConnectionFactory factory, DbStorageFactory storageFactory, IUser user) : base(factory) { this.storage = storageFactory.GetDbStorage (user); engine = new Engine (storage); using (var db = connFactory.OpenDbConnection ()) { this.dbUser = db.Select<DBUser> (u => u.Username == user.Username)[0]; } if (dbUser.Manifest == null || string.IsNullOrEmpty (dbUser.Manifest.ServerId)) { // the user may not yet have synced dbUser.Manifest.ServerId = Guid.NewGuid ().ToString (); } }
public new void SetUp() { testServer = new RainyTestServer (); if (dbScenario == "postgres") { testServer.ScenarioPostgres (); } else if (dbScenario == "sqlite" || string.IsNullOrEmpty (dbScenario)) { testServer.ScenarioSqlite (); } testServer.Start (); this.connFactory = RainyTestServer.Container.Resolve<IDbConnectionFactory> (); using (var db = connFactory.OpenDbConnection ()) { testUser = db.First<DBUser> (u => u.Username == RainyTestServer.TEST_USER); } }
public void BasicEncryptAndDecrypt() { var u = new DBUser (); u.Username = "******"; var password = "******"; u.CreateCryptoFields (password); var test_string = "The quick brown fox jumps over the lazy dog."; var master_key = u.GetPlaintextMasterKey (password); byte[] encrypted_bytes = u.EncryptString (master_key, test_string); string decrypted_string = u.DecryptUnicodeString (master_key, encrypted_bytes); Assert.AreEqual (test_string, decrypted_string); }
public DbStorage(IDbConnectionFactory factory, string username, bool use_history = true) { if (factory == null) throw new ArgumentNullException ("factory"); this.connFactory = factory; using (var dbu = connFactory.OpenDbConnection ()) { this.User = dbu.Select<DBUser> (u => u.Username == username)[0]; } this.Manifest = this.User.Manifest; this.UseHistory = use_history; db = factory.OpenDbConnection (); // start everything as a transaction trans = db.BeginTransaction (); }
public void EncryptDecryptWithHexRepresentation() { var u = new DBUser (); u.Username = "******"; var password = "******"; u.CreateCryptoFields (password); var master_key = u.GetPlaintextMasterKey (password); var key = master_key.ToHexString (); var test_string = "The quick brown fox jumps over the lazy dog."; byte[] encrypted_bytes = u.EncryptString (master_key, test_string); string encrypted_string = encrypted_bytes.ToHexString (); string decrypted_string = u.DecryptUnicodeString (master_key, encrypted_string.ToByteArray ()); Assert.AreEqual (test_string, decrypted_string); }
public DbStorage(IDbConnectionFactory factory, string username, bool use_history = true) { if (factory == null) { throw new ArgumentNullException("factory"); } this.connFactory = factory; using (var dbu = connFactory.OpenDbConnection()) { this.User = dbu.Select <DBUser> (u => u.Username == username)[0]; } this.Manifest = this.User.Manifest; this.UseHistory = use_history; db = factory.OpenDbConnection(); // start everything as a transaction trans = db.BeginTransaction(); }
public void SaveAndReadUser() { var user = new DBUser(); using (var conn = dbFactory.OpenDbConnection()) { user.Username = "******"; user.Manifest.ServerId = Guid.NewGuid().ToString(); user.Manifest.LastSyncRevision = 123; user.Manifest.NoteRevisions.Add(Guid.NewGuid().ToString(), 666); conn.Save(user); } using (var conn = dbFactory.OpenDbConnection()) { var db_user = conn.First <DBUser> ("Username = {0}", "test"); Assert.AreEqual(user.Manifest.ServerId, db_user.Manifest.ServerId); Assert.AreEqual(user.Manifest.NoteRevisions.First(), db_user.Manifest.NoteRevisions.First()); Assert.AreEqual(user.Manifest.LastSyncRevision, db_user.Manifest.LastSyncRevision); } }
public void SetUp() { testUser = new DBUser () { Username = "******" }; // Start with empty tables in each test run using (var c = dbFactory.OpenDbConnection ()) { using (var t = c.BeginTransaction ()) { c.DropAndCreateTable <DBNote> (); c.DropAndCreateTable <DBUser> (); c.DropAndCreateTable <DBAccessToken> (); c.InsertParam<DBUser> (testUser); t.Commit (); } } using (var c = dbFactory.OpenDbConnection ()) { DBUser user = c.First<DBUser> (u => u.Username == "test"); Console.WriteLine (user.Username); } }
public void SetUp() { testUser = new DBUser() { Username = "******" }; // Start with empty tables in each test run using (var c = dbFactory.OpenDbConnection()) { using (var t = c.BeginTransaction()) { c.DropAndCreateTable <DBNote> (); c.DropAndCreateTable <DBUser> (); c.DropAndCreateTable <DBAccessToken> (); c.InsertParam <DBUser> (testUser); t.Commit(); } } using (var c = dbFactory.OpenDbConnection()) { DBUser user = c.First <DBUser> (u => u.Username == "test"); Console.WriteLine(user.Username); } }
public object Post(SignupUserRequest req) { req.AdditionalData = ""; req.Username = req.Username.ToLower (); // assert password is safe enough if (!req.Password.IsSafeAsPassword ()) throw new ValidationException () {ErrorMessage = "Password is unsafe"}; // assert username is not already taken using (var db = DbConfig.GetConnection ()) { var user = db.FirstOrDefault<DBUser> (u => u.Username == req.Username); if (user != null) throw new ConflictException () {ErrorMessage = "A user by that name already exists"}; } // assert email is not already registered using (var db = DbConfig.GetConnection ()) { var user = db.FirstOrDefault<DBUser> (u => u.EmailAddress == req.EmailAddress); if (user != null) throw new ConflictException () {ErrorMessage = "The emailaddress is already registered"}; } // assert all required fields are filled var db_user = new DBUser (); db_user.PopulateWith (req); db_user.IsActivated = false; db_user.IsVerified = false; db_user.VerifySecret = Guid.NewGuid ().ToString ().Replace("-", ""); // write user to db using (var db = DbConfig.GetConnection ()) { db.Insert<DBUser> (db_user); } return new HttpResult () { StatusCode = HttpStatusCode.OK }; }
private void WireupGenericTestClasses(Funq.Container container) { container.Register<IAuthenticator> (c => { var factory = c.Resolve<IDbConnectionFactory> (); var dbauth = new DbAuthenticator (factory); //var dbauth = new DbTestAuthenticator (); var test_user = new DBUser { Username = RainyTestServer.TEST_USER, IsActivated = true, IsVerified = true }; test_user.CreateCryptoFields (RainyTestServer.TEST_PASS); // insert a dummy testuser using (var db = factory.OpenDbConnection ()) { db.InsertParam<DBUser> (test_user); } return dbauth; }); container.Register<IAdminAuthenticator> (c => { var admin_auth = new DummyAdminAuthenticator (ADMIN_TEST_PASS); return (IAdminAuthenticator)admin_auth; }); container.Register<IDbStorageFactory> (c => { var conn_factory = c.Resolve<IDbConnectionFactory> (); IDbStorageFactory storage_factory; bool use_encryption = true; if (use_encryption) storage_factory = new DbEncryptedStorageFactory (conn_factory, use_history: true); else storage_factory = new DbStorageFactory (conn_factory, use_history: true); return (IDbStorageFactory) storage_factory; }); container.Register<IDataBackend> (c => { var conn_factory = c.Resolve<IDbConnectionFactory> (); var storage_factory = c.Resolve<IDbStorageFactory> (); var auth = c.Resolve<IAuthenticator> (); var handler = c.Resolve<OAuthHandler> (); return new DatabaseBackend (conn_factory, storage_factory, auth, handler); }); container.Register<OAuthHandler> (c => { var auth = c.Resolve<IAuthenticator> (); var factory = c.Resolve<IDbConnectionFactory> (); // ITokenRepository<AccessToken> access_tokens = new SimpleTokenRepository<AccessToken> (); // ITokenRepository<RequestToken> request_tokens = new SimpleTokenRepository<RequestToken> (); ITokenRepository<AccessToken> access_tokens = new DbAccessTokenRepository<AccessToken> (factory); ITokenRepository<RequestToken> request_tokens = new DbRequestTokenRepository<RequestToken> (factory); ITokenStore token_store = new RainyTokenStore (access_tokens, request_tokens); OAuthHandler handler = new OAuthHandler (auth, access_tokens, request_tokens, token_store); return handler; }); var connFactory = container.Resolve<IDbConnectionFactory> (); DatabaseBackend.CreateSchema (connFactory, true); // HACK so the user is inserted when a fixture SetUp is run container.Resolve<IAuthenticator> (); }
public virtual DbStorage GetDbStorage(IUser user) { var db_user = new DBUser () { Username = user.Username }; return new DbStorage (connFactory, db_user.Username, useHistory); }
public void PasswordHashHasCorrectLength() { var u = new DBUser (); u.Username = "******"; var password = "******"; u.CreateCryptoFields (password); Assert.AreEqual (64, u.PasswordHash.Length); }
public DatabaseNoteRepository(string username) { username = username; dbConnection = DbConfig.GetConnection (); storage = new DbStorage (username); engine = new Engine (storage); var db_user = dbConnection.Select <DBUser> ("Username = {0}", username); if (db_user.Count == 0) { dbUser = new DBUser () { Username = username }; } else dbUser = db_user[0]; if (dbUser.Manifest == null || string.IsNullOrEmpty (dbUser.Manifest.ServerId)) { // the user may not yet have synced dbUser.Manifest = new SyncManifest (); dbUser.Manifest.ServerId = Guid.NewGuid ().ToString (); } }
// TODO see if we can directly use DBUser // update existing user public object Put(UserRequest updated_user) { var user = new DBUser (); // TODO make explicit mapping user.PopulateWith (updated_user); using (var conn = DbConfig.GetConnection ()) { var stored_user = conn.FirstOrDefault<DBUser>("Username = {0}", user.Username); if (stored_user == null) { // user did not exist, can't update return new HttpResult { Status = 404, StatusDescription = "User " + user.Username + " was not found," + " and can't be updated. Try using HTTP POST to create a new user" }; } if (user.Password == "") { // password was not sent so use the old password // TODO hashing user.Password = stored_user.Password; } conn.Update<DBUser> (user, u => u.Username == user.Username); } Logger.DebugFormat ("updating user information for user {0}", user.Username); // do not return the password over the wire user.Password = ""; return new HttpResult (user) { StatusCode = System.Net.HttpStatusCode.OK, StatusDescription = "Successfully updated user " + user.Username }; }
public object Post(SignupUserRequest req) { if (!JsonConfig.Config.Global.AllowSignup) throw new Rainy.ErrorHandling.UnauthorizedException (); req.AdditionalData = ""; req.Username = req.Username.ToLower (); // assert password is safe enough //if (!req.Password.IsSafeAsPassword ()) // throw new ValidationException () {ErrorMessage = "Password is unsafe"}; // assert username is not already taken using (var db = connFactory.OpenDbConnection ()) { var user = db.FirstOrDefault<DBUser> (u => u.Username == req.Username); if (user != null) throw new ConflictException () {ErrorMessage = "A user by that name already exists"}; // assert email is not already registered user = db.FirstOrDefault<DBUser> (u => u.EmailAddress == req.EmailAddress); if (user != null) throw new ConflictException () {ErrorMessage = "The emailaddress is already registered"}; } // assert all required fields are filled var db_user = new DBUser (); db_user.PopulateWith (req); db_user.IsActivated = false; if (JsonConfig.Config.Global.RequireModeration == false) db_user.IsActivated = true; db_user.IsVerified = true; db_user.VerifySecret = Guid.NewGuid ().ToString ().Replace("-", ""); db_user.CreateCryptoFields (req.Password); db_user.Password = ""; // write user to db using (var db = connFactory.OpenDbConnection ()) { db.Insert<DBUser> (db_user); } return new HttpResult () { StatusCode = HttpStatusCode.OK }; }
/// <summary> /// POST /admin/user /// /// creates a new user. /// /// returns HTTP Response => /// 201 Created /// Location: http://localhost/admin/user/{Username} /// </summary> public object Post(UserRequest user) { var new_user = new DBUser (); // TODO explicit mapping new_user.PopulateWith (user); // TODO move into RequestFilter if (string.IsNullOrEmpty (user.Username)) throw new InvalidRequestDtoException { ErrorMessage = "Username was empty" }; if (string.IsNullOrEmpty (user.Password)) throw new InvalidRequestDtoException { ErrorMessage = "Password was empty" }; // TODO move into RequestFilter if (! (user.Username.IsOnlySafeChars () && user.Password.IsOnlySafeChars () && user.EmailAddress.Replace ("@", "").IsOnlySafeChars ())) { throw new ValidationException { ErrorMessage = "found unsafe/unallowed characters" }; } // TODO move into RequestFilter // lowercase the username new_user.Username = new_user.Username.ToLower (); // TODO move into API new_user.CreateCryptoFields (user.Password); using (var conn = connFactory.OpenDbConnection ()) { var existing_user = conn.FirstOrDefault<DBUser> ("Username = {0}", new_user.Username); if (existing_user != null) throw new ConflictException (){ErrorMessage = "A user by that name already exists"}; conn.Insert<DBUser> (new_user); } return new HttpResult (new_user) { StatusCode = HttpStatusCode.Created, StatusDescription = "Sucessfully created user " + new_user.Username, Headers = { { HttpHeaders.Location, base.Request.AbsoluteUri.CombineWith (new_user.Username) } } }; }
// This is the "Composition Root" in the IoC pattern that wires all // our objects/implementations up, based on a given configuration. // config sanity checks SHOULD NOT go here private static void ComposeObjectGraph(Funq.Container container) { var config = Config.Global; container.Register<SqliteConfig> (c => new SqliteConfig { File = Path.Combine (config.DataPath, "rainy.db") }); container.Register<PostgreConfig> (c => { dynamic txt_conf = config.Postgre; var psql_conf = new PostgreConfig (); if (!string.IsNullOrEmpty (txt_conf.Username)) psql_conf.Username = txt_conf.Username; if (!string.IsNullOrEmpty (txt_conf.Password)) psql_conf.Password = txt_conf.Password; if (!string.IsNullOrEmpty (txt_conf.Database)) psql_conf.Database = txt_conf.Database; if (!string.IsNullOrEmpty (txt_conf.Host)) psql_conf.Host = txt_conf.Host; if (txt_conf.Port > 0) psql_conf.Port = (uint) txt_conf.Port; return psql_conf; }); if (config.Backend == "xml") { // use username/password pairs from the config file container.Register<IAuthenticator> (c => { return new ConfigFileAuthenticator(config.User); }); // we store notes in XML files in the DataPath container.Register<IDataBackend> (c => { var auth = c.Resolve<IAuthenticator> (); var factory = c.Resolve<IDbConnectionFactory> (); var oauth_handler = c.Resolve<OAuthHandler> (); return new FileSystemBackend (config.DataPath, factory, auth, oauth_handler, false); }); } else { // database based backends switch ((string) config.Backend) { case "sqlite": container.Register<IDbConnectionFactory> (c => { var conf = container.Resolve<SqliteConfig> (); var connection_string = conf.ConnectionString; var factory = new OrmLiteConnectionFactory (connection_string, SqliteDialect.Provider); if (!File.Exists (conf.File)) { DatabaseBackend.CreateSchema (factory); } return (IDbConnectionFactory) factory; }); break; case "postgre": container.Register<IDbConnectionFactory> (c => { var connection_string = container.Resolve<PostgreConfig> ().ConnectionString; var factory = new OrmLiteConnectionFactory (connection_string, PostgreSqlDialect.Provider); DatabaseBackend.CreateSchema (factory); return factory; }); break; } container.Register<IAuthenticator> (c => { var factory = c.Resolve<IDbConnectionFactory> (); // var sfactory = new OrmLiteConnectionFactory (); var dbauth = new DbAuthenticator (factory); //var dbauth = new ConfigFileAuthenticator (Config.Global.Users); // we have to make sure users from the config file exist with the configured password // in the db // TODO delete old users? or restrict to webinterface? if (dbauth is ConfigFileAuthenticator) { foreach (dynamic user in Config.Global.Users) { string username = user.Username; string password = user.Password; using (var db = factory.OpenDbConnection ()) { var db_user = db.FirstOrDefault<DBUser> (u => u.Username == username); if (db_user != null) { var need_update = db_user.UpdatePassword (password); if (need_update) db.UpdateOnly (new DBUser { PasswordHash = db_user.PasswordHash }, u => new { u.PasswordHash }, (DBUser p) => p.Username == username); } else { // create the user in the db var new_user = new DBUser (); new_user.Username = username; new_user.CreateCryptoFields (password); new_user.UpdatePassword (password); db.Insert<DBUser> (new_user); } } } } return dbauth; }); // container.Register<IAdminAuthenticator> (c => { var auth = new ConfigFileAdminAuthenticator (); return auth; }); container.Register<OAuthHandler> (c => { var auth = c.Resolve<IAuthenticator> (); var factory = c.Resolve<IDbConnectionFactory> (); // ITokenRepository<AccessToken> access_tokens = new SimpleTokenRepository<AccessToken> (); // ITokenRepository<RequestToken> request_tokens = new SimpleTokenRepository<RequestToken> (); ITokenRepository<AccessToken> access_tokens = new DbAccessTokenRepository<AccessToken> (factory); ITokenRepository<RequestToken> request_tokens = new DbRequestTokenRepository<RequestToken> (factory); ITokenStore token_store = new RainyTokenStore (access_tokens, request_tokens); OAuthHandler handler = new OAuthHandler (auth, access_tokens, request_tokens, token_store); return handler; }); container.Register<DbStorageFactory> (c => { var conn_factory = c.Resolve<IDbConnectionFactory> (); bool use_encryption = (bool) Config.Global.UseNoteEncryption; var storage_factory = new DbStorageFactory (conn_factory, use_encryption, use_history: true); return storage_factory; }); container.Register<IDataBackend> (c => { var conn_factory = c.Resolve<IDbConnectionFactory> (); var storage_factory = c.Resolve<DbStorageFactory> (); var handler = c.Resolve<OAuthHandler> (); var auth = c.Resolve<IAuthenticator> (); return new DatabaseBackend (conn_factory, storage_factory, auth, handler); }); /* container.Register<OAuthHandler> (c => { var factory = c.Resolve<IDbConnectionFactory> (); var access_token_repo = new DbAccessTokenRepository<AccessToken> (factory); var request_token_repo = new SimpleTokenRepository<RequestToken> (); var auth = c.Resolve<IAuthenticator> (); var token_store = new Rainy.OAuth.SimpleStore.SimpleTokenStore (access_token_repo, request_token_repo); var handler = new OAuthHandler (auth, token_store); return handler; }); */ AddDummyUserIfRequired (container); } }
public void SaveAndReadUser() { var user = new DBUser (); using (var conn = dbFactory.OpenDbConnection ()) { user.Username = "******"; user.Manifest.ServerId = Guid.NewGuid ().ToString (); user.Manifest.LastSyncRevision = 123; user.Manifest.NoteRevisions.Add (Guid.NewGuid ().ToString (), 666); conn.Save (user); } using (var conn = dbFactory.OpenDbConnection ()) { var db_user = conn.First<DBUser> ("Username = {0}", "test"); Assert.AreEqual (user.Manifest.ServerId, db_user.Manifest.ServerId); Assert.AreEqual (user.Manifest.NoteRevisions.First (), db_user.Manifest.NoteRevisions.First ()); Assert.AreEqual (user.Manifest.LastSyncRevision, db_user.Manifest.LastSyncRevision); } }
public DatabaseNoteRepository(string username) { dbConnection = DbConfig.GetConnection (); dbUser = dbConnection.First<DBUser> (u => u.Username == username); storage = new DbStorage (dbUser); engine = new Engine (storage); if (dbUser.Manifest == null || string.IsNullOrEmpty (dbUser.Manifest.ServerId)) { // the user may not yet have synced dbUser.Manifest.ServerId = Guid.NewGuid ().ToString (); } }
public static void Decrypt(this DBNote note, DBUser user, string master_key) { var per_note_key = note.EncryptedKey.DecryptWithKey (master_key, user.MasterKeySalt); byte[] b_key = per_note_key.ToByteArray (); byte[] b_note_text = note.Text.ToByteArray (); note.Text = user.DecryptUnicodeString (b_key, b_note_text); }