OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
SQLiteAuthenticationData.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Data;
32 using System.Reflection;
33 using log4net;
34 using OpenMetaverse;
35 using OpenSim.Framework;
36 
37 #if CSharpSqlite
38  using Community.CsharpSqlite.Sqlite;
39 #else
40  using Mono.Data.Sqlite;
41 #endif
42 
43 namespace OpenSim.Data.SQLite
44 {
46  {
47  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 
49  private string m_Realm;
50  private List<string> m_ColumnNames;
51  private int m_LastExpire;
52 
53  protected static SqliteConnection m_Connection;
54  private static bool m_initialized = false;
55 
56  protected virtual Assembly Assembly
57  {
58  get { return GetType().Assembly; }
59  }
60 
61  public SQLiteAuthenticationData(string connectionString, string realm)
62  : base(connectionString)
63  {
64  m_Realm = realm;
65 
66  if (!m_initialized)
67  {
68  if (Util.IsWindows())
69  Util.LoadArchSpecificWindowsDll("sqlite3.dll");
70 
71  m_Connection = new SqliteConnection(connectionString);
72  m_Connection.Open();
73 
74  Migration m = new Migration(m_Connection, Assembly, "AuthStore");
75  m.Update();
76 
77  m_initialized = true;
78  }
79  }
80 
81  public AuthenticationData Get(UUID principalID)
82  {
84  ret.Data = new Dictionary<string, object>();
85  IDataReader result;
86 
87  using (SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID"))
88  {
89  cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
90 
91  result = ExecuteReader(cmd, m_Connection);
92  }
93 
94  try
95  {
96  if (result.Read())
97  {
98  ret.PrincipalID = principalID;
99 
100  if (m_ColumnNames == null)
101  {
102  m_ColumnNames = new List<string>();
103 
104  DataTable schemaTable = result.GetSchemaTable();
105  foreach (DataRow row in schemaTable.Rows)
106  m_ColumnNames.Add(row["ColumnName"].ToString());
107  }
108 
109  foreach (string s in m_ColumnNames)
110  {
111  if (s == "UUID")
112  continue;
113 
114  ret.Data[s] = result[s].ToString();
115  }
116 
117  return ret;
118  }
119  else
120  {
121  return null;
122  }
123  }
124  catch
125  {
126  }
127 
128  return null;
129  }
130 
131  public bool Store(AuthenticationData data)
132  {
133  if (data.Data.ContainsKey("UUID"))
134  data.Data.Remove("UUID");
135 
136  string[] fields = new List<string>(data.Data.Keys).ToArray();
137  string[] values = new string[data.Data.Count];
138  int i = 0;
139  foreach (object o in data.Data.Values)
140  values[i++] = o.ToString();
141 
142  using (SqliteCommand cmd = new SqliteCommand())
143  {
144  if (Get(data.PrincipalID) != null)
145  {
146 
147 
148  string update = "update `" + m_Realm + "` set ";
149  bool first = true;
150  foreach (string field in fields)
151  {
152  if (!first)
153  update += ", ";
154  update += "`" + field + "` = :" + field;
155  cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
156 
157  first = false;
158  }
159 
160  update += " where UUID = :UUID";
161  cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
162 
163  cmd.CommandText = update;
164  try
165  {
166  if (ExecuteNonQuery(cmd, m_Connection) < 1)
167  {
168  //CloseCommand(cmd);
169  return false;
170  }
171  }
172  catch (Exception e)
173  {
174  m_log.Error("[SQLITE]: Exception storing authentication data", e);
175  //CloseCommand(cmd);
176  return false;
177  }
178  }
179  else
180  {
181  string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
182  String.Join("`, `", fields) +
183  "`) values (:UUID, :" + String.Join(", :", fields) + ")";
184 
185  cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
186  foreach (string field in fields)
187  cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
188 
189  cmd.CommandText = insert;
190 
191  try
192  {
193  if (ExecuteNonQuery(cmd, m_Connection) < 1)
194  {
195  return false;
196  }
197  }
198  catch (Exception e)
199  {
200  Console.WriteLine(e.ToString());
201  return false;
202  }
203  }
204  }
205 
206  return true;
207  }
208 
209  public bool SetDataItem(UUID principalID, string item, string value)
210  {
211  using (SqliteCommand cmd = new SqliteCommand("update `" + m_Realm +
212  "` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'"))
213  {
214  if (ExecuteNonQuery(cmd, m_Connection) > 0)
215  return true;
216  }
217 
218  return false;
219  }
220 
221  public bool SetToken(UUID principalID, string token, int lifetime)
222  {
223  if (System.Environment.TickCount - m_LastExpire > 30000)
224  DoExpire();
225 
226  using (SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() +
227  "', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))"))
228  {
229  if (ExecuteNonQuery(cmd, m_Connection) > 0)
230  return true;
231  }
232 
233  return false;
234  }
235 
236  public bool CheckToken(UUID principalID, string token, int lifetime)
237  {
238  if (System.Environment.TickCount - m_LastExpire > 30000)
239  DoExpire();
240 
241  using (SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() +
242  " minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')"))
243  {
244  if (ExecuteNonQuery(cmd, m_Connection) > 0)
245  return true;
246  }
247 
248  return false;
249  }
250 
251  private void DoExpire()
252  {
253  using (SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')"))
254  ExecuteNonQuery(cmd, m_Connection);
255 
256  m_LastExpire = System.Environment.TickCount;
257  }
258  }
259 }
AuthenticationData Get(UUID principalID)
SQLiteAuthenticationData(string connectionString, string realm)
Dictionary< string, object > Data
A database interface class to a user profile storage system
bool CheckToken(UUID principalID, string token, int lifetime)
bool SetDataItem(UUID principalID, string item, string value)
An interface for connecting to the authentication datastore
bool SetToken(UUID principalID, string token, int lifetime)