using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; using IcgSoftware.Threema.CoreMsgApi.Exceptions; using Microsoft.Data.Sqlite; using Microsoft.Extensions.Configuration; namespace IcgSoftware.Threema.CoreMsgApi { class PublicKeyStoreDb : PublicKeyStore { private readonly string connectionString; public PublicKeyStoreDb(string connectionString) { if (string.IsNullOrEmpty(connectionString)) { throw new ArgumentException("connectionString must be not null or empty."); } this.connectionString = connectionString; this.CreateDatabase(); } /// /// Fetch public key in store for particular threema id /// /// Threema id to fetch /// Public key protected override byte[] FetchPublicKey(string threemaId) { using (DbConnection connection = GetConnection(this.connectionString)) { connection.Open(); string sql = "SELECT threema_id, key FROM public_key WHERE threema_id = @threemaId"; var command = connection.CreateCommand(); command.CommandType = CommandType.Text; command.CommandText = sql; var paramThreemaId = command.CreateParameter(); paramThreemaId.ParameterName = "threemaId"; paramThreemaId.Value = threemaId; command.Parameters.Add(paramThreemaId); byte[] publicKey = null; using (var reader = command.ExecuteReader(CommandBehavior.SingleRow)) { if (reader.HasRows) { if (reader.Read()) { publicKey = DataUtils.HexStringToByteArray(reader[1].ToString()); } } reader.Close(); } return publicKey; } } /// /// Save threema id and public key into store /// /// Threema id /// public key protected override void Save(string threemaId, byte[] publicKey) { using (DbConnection connection = GetConnection(this.connectionString)) { connection.Open(); string sql = "INSERT INTO public_key (threema_id, key) VALUES (@threemaId, @key)"; var command = connection.CreateCommand(); command.CommandType = CommandType.Text; command.CommandText = sql; var paramThreemaId = command.CreateParameter(); paramThreemaId.ParameterName = "threemaId"; paramThreemaId.Value = threemaId; var paramKey = command.CreateParameter(); paramKey.ParameterName = "key"; paramKey.Value = DataUtils.ByteArrayToHexString(publicKey); command.Parameters.Add(paramThreemaId); command.Parameters.Add(paramKey); command.ExecuteNonQuery(); connection.Close(); } } /// /// Create database and table for public key store /// private void CreateDatabase() { using (DbConnection connection = GetConnection(this.connectionString)) { connection.Open(); string sql = "CREATE TABLE IF NOT EXISTS public_key (id INTEGER PRIMARY KEY AUTOINCREMENT, threema_id VARCHAR(8) NOT NULL UNIQUE, key VARCHAR(64) NOT NULL)"; var command = connection.CreateCommand(); command.CommandText = sql; command.ExecuteNonQuery(); connection.Close(); } } /// /// Get connetion is configured in App.config /// /// Connect String /// Db Connection private DbConnection GetConnection(string connectionString) { //throw new CoreMigrationException("SQLite is not supported"); return new SqliteConnection(connectionString); //string providerName = "System.Data.SQLite"; //var dbProvider = Microsoft.Data.Sqlite.SqliteFactory.Instance; /* string providerName = null; DbConnectionStringBuilder connectionStringBuilder = new DbConnectionStringBuilder { ConnectionString = connectionString }; if (connectionStringBuilder.ContainsKey("provider")) { providerName = connectionStringBuilder["provider"].ToString(); } else { ConnectionStringSettings connectionStringSetting = ConfigurationManager .ConnectionStrings .Cast() .FirstOrDefault(x => x.ConnectionString == connectionString); if (connectionStringSetting != null) { providerName = connectionStringSetting.ProviderName; } } if (providerName != null) { bool providerExists = DbProviderFactories .GetFactoryClasses() .Rows.Cast() .Any(r => r[2].Equals(providerName)); if (providerExists) { DbProviderFactory factory = DbProviderFactories.GetFactory(providerName); DbConnection dbConnection = factory.CreateConnection(); dbConnection.ConnectionString = connectionString; return dbConnection; } } return null; */ } } }