android: Add fields for local and remote identities to data model
[strongswan.git] / src / frontends / android / app / src / main / java / org / strongswan / android / data / VpnProfileDataSource.java
1 /*
2 * Copyright (C) 2012-2016 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * HSR Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 package org.strongswan.android.data;
19
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import android.content.ContentValues;
24 import android.content.Context;
25 import android.database.Cursor;
26 import android.database.SQLException;
27 import android.database.sqlite.SQLiteDatabase;
28 import android.database.sqlite.SQLiteOpenHelper;
29 import android.database.sqlite.SQLiteQueryBuilder;
30 import android.util.Log;
31
32 public class VpnProfileDataSource
33 {
34 private static final String TAG = VpnProfileDataSource.class.getSimpleName();
35 public static final String KEY_ID = "_id";
36 public static final String KEY_NAME = "name";
37 public static final String KEY_GATEWAY = "gateway";
38 public static final String KEY_VPN_TYPE = "vpn_type";
39 public static final String KEY_USERNAME = "username";
40 public static final String KEY_PASSWORD = "password";
41 public static final String KEY_CERTIFICATE = "certificate";
42 public static final String KEY_USER_CERTIFICATE = "user_certificate";
43 public static final String KEY_MTU = "mtu";
44 public static final String KEY_PORT = "port";
45 public static final String KEY_SPLIT_TUNNELING = "split_tunneling";
46 public static final String KEY_LOCAL_ID = "local_id";
47 public static final String KEY_REMOTE_ID = "remote_id";
48
49 private DatabaseHelper mDbHelper;
50 private SQLiteDatabase mDatabase;
51 private final Context mContext;
52
53 private static final String DATABASE_NAME = "strongswan.db";
54 private static final String TABLE_VPNPROFILE = "vpnprofile";
55
56 private static final int DATABASE_VERSION = 8;
57
58 public static final String DATABASE_CREATE =
59 "CREATE TABLE " + TABLE_VPNPROFILE + " (" +
60 KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
61 KEY_NAME + " TEXT NOT NULL," +
62 KEY_GATEWAY + " TEXT NOT NULL," +
63 KEY_VPN_TYPE + " TEXT NOT NULL," +
64 KEY_USERNAME + " TEXT," +
65 KEY_PASSWORD + " TEXT," +
66 KEY_CERTIFICATE + " TEXT," +
67 KEY_USER_CERTIFICATE + " TEXT," +
68 KEY_MTU + " INTEGER," +
69 KEY_PORT + " INTEGER," +
70 KEY_SPLIT_TUNNELING + " INTEGER," +
71 KEY_LOCAL_ID + " TEXT," +
72 KEY_REMOTE_ID + " TEXT" +
73 ");";
74 private static final String[] ALL_COLUMNS = new String[] {
75 KEY_ID,
76 KEY_NAME,
77 KEY_GATEWAY,
78 KEY_VPN_TYPE,
79 KEY_USERNAME,
80 KEY_PASSWORD,
81 KEY_CERTIFICATE,
82 KEY_USER_CERTIFICATE,
83 KEY_MTU,
84 KEY_PORT,
85 KEY_SPLIT_TUNNELING,
86 KEY_LOCAL_ID,
87 KEY_REMOTE_ID,
88 };
89
90 private static class DatabaseHelper extends SQLiteOpenHelper
91 {
92 public DatabaseHelper(Context context)
93 {
94 super(context, DATABASE_NAME, null, DATABASE_VERSION);
95 }
96
97 @Override
98 public void onCreate(SQLiteDatabase database)
99 {
100 database.execSQL(DATABASE_CREATE);
101 }
102
103 @Override
104 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
105 {
106 Log.w(TAG, "Upgrading database from version " + oldVersion +
107 " to " + newVersion);
108 if (oldVersion < 2)
109 {
110 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_USER_CERTIFICATE +
111 " TEXT;");
112 }
113 if (oldVersion < 3)
114 {
115 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_VPN_TYPE +
116 " TEXT DEFAULT '';");
117 }
118 if (oldVersion < 4)
119 { /* remove NOT NULL constraint from username column */
120 updateColumns(db);
121 }
122 if (oldVersion < 5)
123 {
124 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_MTU +
125 " INTEGER;");
126 }
127 if (oldVersion < 6)
128 {
129 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_PORT +
130 " INTEGER;");
131 }
132 if (oldVersion < 7)
133 {
134 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_SPLIT_TUNNELING +
135 " INTEGER;");
136 }
137 if (oldVersion < 8)
138 {
139 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_LOCAL_ID +
140 " TEXT;");
141 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_REMOTE_ID +
142 " TEXT;");
143 }
144 }
145
146 private void updateColumns(SQLiteDatabase db)
147 {
148 db.beginTransaction();
149 try
150 {
151 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " RENAME TO tmp_" + TABLE_VPNPROFILE + ";");
152 db.execSQL(DATABASE_CREATE);
153 StringBuilder insert = new StringBuilder("INSERT INTO " + TABLE_VPNPROFILE + " SELECT ");
154 SQLiteQueryBuilder.appendColumns(insert, ALL_COLUMNS);
155 db.execSQL(insert.append(" FROM tmp_" + TABLE_VPNPROFILE + ";").toString());
156 db.execSQL("DROP TABLE tmp_" + TABLE_VPNPROFILE + ";");
157 db.setTransactionSuccessful();
158 }
159 finally
160 {
161 db.endTransaction();
162 }
163 }
164 }
165
166 /**
167 * Construct a new VPN profile data source. The context is used to
168 * open/create the database.
169 * @param context context used to access the database
170 */
171 public VpnProfileDataSource(Context context)
172 {
173 this.mContext = context;
174 }
175
176 /**
177 * Open the VPN profile data source. The database is automatically created
178 * if it does not yet exist. If that fails an exception is thrown.
179 * @return itself (allows to chain initialization calls)
180 * @throws SQLException if the database could not be opened or created
181 */
182 public VpnProfileDataSource open() throws SQLException
183 {
184 if (mDbHelper == null)
185 {
186 mDbHelper = new DatabaseHelper(mContext);
187 mDatabase = mDbHelper.getWritableDatabase();
188 }
189 return this;
190 }
191
192 /**
193 * Close the data source.
194 */
195 public void close()
196 {
197 if (mDbHelper != null)
198 {
199 mDbHelper.close();
200 mDbHelper = null;
201 }
202 }
203
204 /**
205 * Insert the given VPN profile into the database. On success the Id of
206 * the object is updated and the object returned.
207 *
208 * @param profile the profile to add
209 * @return the added VPN profile or null, if failed
210 */
211 public VpnProfile insertProfile(VpnProfile profile)
212 {
213 ContentValues values = ContentValuesFromVpnProfile(profile);
214 long insertId = mDatabase.insert(TABLE_VPNPROFILE, null, values);
215 if (insertId == -1)
216 {
217 return null;
218 }
219 profile.setId(insertId);
220 return profile;
221 }
222
223 /**
224 * Updates the given VPN profile in the database.
225 * @param profile the profile to update
226 * @return true if update succeeded, false otherwise
227 */
228 public boolean updateVpnProfile(VpnProfile profile)
229 {
230 long id = profile.getId();
231 ContentValues values = ContentValuesFromVpnProfile(profile);
232 return mDatabase.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + id, null) > 0;
233 }
234
235 /**
236 * Delete the given VPN profile from the database.
237 * @param profile the profile to delete
238 * @return true if deleted, false otherwise
239 */
240 public boolean deleteVpnProfile(VpnProfile profile)
241 {
242 long id = profile.getId();
243 return mDatabase.delete(TABLE_VPNPROFILE, KEY_ID + " = " + id, null) > 0;
244 }
245
246 /**
247 * Get a single VPN profile from the database.
248 * @param id the ID of the VPN profile
249 * @return the profile or null, if not found
250 */
251 public VpnProfile getVpnProfile(long id)
252 {
253 VpnProfile profile = null;
254 Cursor cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS,
255 KEY_ID + "=" + id, null, null, null, null);
256 if (cursor.moveToFirst())
257 {
258 profile = VpnProfileFromCursor(cursor);
259 }
260 cursor.close();
261 return profile;
262 }
263
264 /**
265 * Get a list of all VPN profiles stored in the database.
266 * @return list of VPN profiles
267 */
268 public List<VpnProfile> getAllVpnProfiles()
269 {
270 List<VpnProfile> vpnProfiles = new ArrayList<VpnProfile>();
271
272 Cursor cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS, null, null, null, null, null);
273 cursor.moveToFirst();
274 while (!cursor.isAfterLast())
275 {
276 VpnProfile vpnProfile = VpnProfileFromCursor(cursor);
277 vpnProfiles.add(vpnProfile);
278 cursor.moveToNext();
279 }
280 cursor.close();
281 return vpnProfiles;
282 }
283
284 private VpnProfile VpnProfileFromCursor(Cursor cursor)
285 {
286 VpnProfile profile = new VpnProfile();
287 profile.setId(cursor.getLong(cursor.getColumnIndex(KEY_ID)));
288 profile.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME)));
289 profile.setGateway(cursor.getString(cursor.getColumnIndex(KEY_GATEWAY)));
290 profile.setVpnType(VpnType.fromIdentifier(cursor.getString(cursor.getColumnIndex(KEY_VPN_TYPE))));
291 profile.setUsername(cursor.getString(cursor.getColumnIndex(KEY_USERNAME)));
292 profile.setPassword(cursor.getString(cursor.getColumnIndex(KEY_PASSWORD)));
293 profile.setCertificateAlias(cursor.getString(cursor.getColumnIndex(KEY_CERTIFICATE)));
294 profile.setUserCertificateAlias(cursor.getString(cursor.getColumnIndex(KEY_USER_CERTIFICATE)));
295 profile.setMTU(getInt(cursor, cursor.getColumnIndex(KEY_MTU)));
296 profile.setPort(getInt(cursor, cursor.getColumnIndex(KEY_PORT)));
297 profile.setSplitTunneling(getInt(cursor, cursor.getColumnIndex(KEY_SPLIT_TUNNELING)));
298 profile.setLocalId(cursor.getString(cursor.getColumnIndex(KEY_LOCAL_ID)));
299 profile.setRemoteId(cursor.getString(cursor.getColumnIndex(KEY_REMOTE_ID)));
300 return profile;
301 }
302
303 private ContentValues ContentValuesFromVpnProfile(VpnProfile profile)
304 {
305 ContentValues values = new ContentValues();
306 values.put(KEY_NAME, profile.getName());
307 values.put(KEY_GATEWAY, profile.getGateway());
308 values.put(KEY_VPN_TYPE, profile.getVpnType().getIdentifier());
309 values.put(KEY_USERNAME, profile.getUsername());
310 values.put(KEY_PASSWORD, profile.getPassword());
311 values.put(KEY_CERTIFICATE, profile.getCertificateAlias());
312 values.put(KEY_USER_CERTIFICATE, profile.getUserCertificateAlias());
313 values.put(KEY_MTU, profile.getMTU());
314 values.put(KEY_PORT, profile.getPort());
315 values.put(KEY_SPLIT_TUNNELING, profile.getSplitTunneling());
316 values.put(KEY_LOCAL_ID, profile.getLocalId());
317 values.put(KEY_REMOTE_ID, profile.getRemoteId());
318 return values;
319 }
320
321 private Integer getInt(Cursor cursor, int columnIndex)
322 {
323 return cursor.isNull(columnIndex) ? null : cursor.getInt(columnIndex);
324 }
325 }