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 <DbStorageFactory> (); var key = user.GetPlaintextMasterKey("foobar123"); var r = new RequestingUser { Username = "******", EncryptionMasterKey = key.ToHexString() }; // populate with note test cases taken from Tomdroid // these notes will fail Tomboy... using (var storage = f.GetDbStorage(r)) { var sample_notes = new DiskStorage("../../../sample_notes/"); sample_notes.GetNotes().Values.ToList().ForEach(n => storage.SaveNote(n)); } } } }
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); }); RegisterStorageFactory(container, false); container.Register <IDataBackend> (c => { var conn_factory = c.Resolve <IDbConnectionFactory> (); var storage_factory = c.Resolve <DbStorageFactory> (); 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 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 PasswordHashHasCorrectLength() { var u = new DBUser(); u.Username = "******"; var password = "******"; u.CreateCryptoFields(password); Assert.AreEqual(64, u.PasswordHash.Length); }
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 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 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 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); }
/// <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" } } ; if (string.IsNullOrEmpty(user.EmailAddress)) { throw new InvalidRequestDtoException { ErrorMessage = "Emailaddress 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; * }); */ if (config.Development == true) { AddDummyUserIfRequired(container); } } }
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 }); }