android: Migrate to the Gradle build system
[strongswan.git] / src / frontends / android / app / src / main / java / org / strongswan / android / data / VpnProfileDataSource.java
1 /*
2 * Copyright (C) 2012-2015 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * 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
47 private DatabaseHelper mDbHelper;
48 private SQLiteDatabase mDatabase;
49 private final Context mContext;
50
51 private static final String DATABASE_NAME = "strongswan.db";
52 private static final String TABLE_VPNPROFILE = "vpnprofile";
53
54 private static final int DATABASE_VERSION = 7;
55
56 public static final String DATABASE_CREATE =
57 "CREATE TABLE " + TABLE_VPNPROFILE + " (" +
58 KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
59 KEY_NAME + " TEXT NOT NULL," +
60 KEY_GATEWAY + " TEXT NOT NULL," +
61 KEY_VPN_TYPE + " TEXT NOT NULL," +
62 KEY_USERNAME + " TEXT," +
63 KEY_PASSWORD + " TEXT," +
64 KEY_CERTIFICATE + " TEXT," +
65 KEY_USER_CERTIFICATE + " TEXT," +
66 KEY_MTU + " INTEGER," +
67 KEY_PORT + " INTEGER," +
68 KEY_SPLIT_TUNNELING + " INTEGER" +
69 ");";
70 private static final String[] ALL_COLUMNS = new String[] {
71 KEY_ID,
72 KEY_NAME,
73 KEY_GATEWAY,
74 KEY_VPN_TYPE,
75 KEY_USERNAME,
76 KEY_PASSWORD,
77 KEY_CERTIFICATE,
78 KEY_USER_CERTIFICATE,
79 KEY_MTU,
80 KEY_PORT,
81 KEY_SPLIT_TUNNELING,
82 };
83
84 private static class DatabaseHelper extends SQLiteOpenHelper
85 {
86 public DatabaseHelper(Context context)
87 {
88 super(context, DATABASE_NAME, null, DATABASE_VERSION);
89 }
90
91 @Override
92 public void onCreate(SQLiteDatabase database)
93 {
94 database.execSQL(DATABASE_CREATE);
95 }
96
97 @Override
98 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
99 {
100 Log.w(TAG, "Upgrading database from version " + oldVersion +
101 " to " + newVersion);
102 if (oldVersion < 2)
103 {
104 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_USER_CERTIFICATE +
105 " TEXT;");
106 }
107 if (oldVersion < 3)
108 {
109 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_VPN_TYPE +
110 " TEXT DEFAULT '';");
111 }
112 if (oldVersion < 4)
113 { /* remove NOT NULL constraint from username column */
114 updateColumns(db);
115 }
116 if (oldVersion < 5)
117 {
118 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_MTU +
119 " INTEGER;");
120 }
121 if (oldVersion < 6)
122 {
123 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_PORT +
124 " INTEGER;");
125 }
126 if (oldVersion < 7)
127 {
128 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_SPLIT_TUNNELING +
129 " INTEGER;");
130 }
131 }
132
133 private void updateColumns(SQLiteDatabase db)
134 {
135 db.beginTransaction();
136 try
137 {
138 db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " RENAME TO tmp_" + TABLE_VPNPROFILE + ";");
139 db.execSQL(DATABASE_CREATE);
140 StringBuilder insert = new StringBuilder("INSERT INTO " + TABLE_VPNPROFILE + " SELECT ");
141 SQLiteQueryBuilder.appendColumns(insert, ALL_COLUMNS);
142 db.execSQL(insert.append(" FROM tmp_" + TABLE_VPNPROFILE + ";").toString());
143 db.execSQL("DROP TABLE tmp_" + TABLE_VPNPROFILE + ";");
144 db.setTransactionSuccessful();
145 }
146 finally
147 {
148 db.endTransaction();
149 }
150 }
151 }
152
153 /**
154 * Construct a new VPN profile data source. The context is used to
155 * open/create the database.
156 * @param context context used to access the database
157 */
158 public VpnProfileDataSource(Context context)
159 {
160 this.mContext = context;
161 }
162
163 /**
164 * Open the VPN profile data source. The database is automatically created
165 * if it does not yet exist. If that fails an exception is thrown.
166 * @return itself (allows to chain initialization calls)
167 * @throws SQLException if the database could not be opened or created
168 */
169 public VpnProfileDataSource open() throws SQLException
170 {
171 if (mDbHelper == null)
172 {
173 mDbHelper = new DatabaseHelper(mContext);
174 mDatabase = mDbHelper.getWritableDatabase();
175 }
176 return this;
177 }
178
179 /**
180 * Close the data source.
181 */
182 public void close()
183 {
184 if (mDbHelper != null)
185 {
186 mDbHelper.close();
187 mDbHelper = null;
188 }
189 }
190
191 /**
192 * Insert the given VPN profile into the database. On success the Id of
193 * the object is updated and the object returned.
194 *
195 * @param profile the profile to add
196 * @return the added VPN profile or null, if failed
197 */
198 public VpnProfile insertProfile(VpnProfile profile)
199 {
200 ContentValues values = ContentValuesFromVpnProfile(profile);
201 long insertId = mDatabase.insert(TABLE_VPNPROFILE, null, values);
202 if (insertId == -1)
203 {
204 return null;
205 }
206 profile.setId(insertId);
207 return profile;
208 }
209
210 /**
211 * Updates the given VPN profile in the database.
212 * @param profile the profile to update
213 * @return true if update succeeded, false otherwise
214 */
215 public boolean updateVpnProfile(VpnProfile profile)
216 {
217 long id = profile.getId();
218 ContentValues values = ContentValuesFromVpnProfile(profile);
219 return mDatabase.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + id, null) > 0;
220 }
221
222 /**
223 * Delete the given VPN profile from the database.
224 * @param profile the profile to delete
225 * @return true if deleted, false otherwise
226 */
227 public boolean deleteVpnProfile(VpnProfile profile)
228 {
229 long id = profile.getId();
230 return mDatabase.delete(TABLE_VPNPROFILE, KEY_ID + " = " + id, null) > 0;
231 }
232
233 /**
234 * Get a single VPN profile from the database.
235 * @param id the ID of the VPN profile
236 * @return the profile or null, if not found
237 */
238 public VpnProfile getVpnProfile(long id)
239 {
240 VpnProfile profile = null;
241 Cursor cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS,
242 KEY_ID + "=" + id, null, null, null, null);
243 if (cursor.moveToFirst())
244 {
245 profile = VpnProfileFromCursor(cursor);
246 }
247 cursor.close();
248 return profile;
249 }
250
251 /**
252 * Get a list of all VPN profiles stored in the database.
253 * @return list of VPN profiles
254 */
255 public List<VpnProfile> getAllVpnProfiles()
256 {
257 List<VpnProfile> vpnProfiles = new ArrayList<VpnProfile>();
258
259 Cursor cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS, null, null, null, null, null);
260 cursor.moveToFirst();
261 while (!cursor.isAfterLast())
262 {
263 VpnProfile vpnProfile = VpnProfileFromCursor(cursor);
264 vpnProfiles.add(vpnProfile);
265 cursor.moveToNext();
266 }
267 cursor.close();
268 return vpnProfiles;
269 }
270
271 private VpnProfile VpnProfileFromCursor(Cursor cursor)
272 {
273 VpnProfile profile = new VpnProfile();
274 profile.setId(cursor.getLong(cursor.getColumnIndex(KEY_ID)));
275 profile.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME)));
276 profile.setGateway(cursor.getString(cursor.getColumnIndex(KEY_GATEWAY)));
277 profile.setVpnType(VpnType.fromIdentifier(cursor.getString(cursor.getColumnIndex(KEY_VPN_TYPE))));
278 profile.setUsername(cursor.getString(cursor.getColumnIndex(KEY_USERNAME)));
279 profile.setPassword(cursor.getString(cursor.getColumnIndex(KEY_PASSWORD)));
280 profile.setCertificateAlias(cursor.getString(cursor.getColumnIndex(KEY_CERTIFICATE)));
281 profile.setUserCertificateAlias(cursor.getString(cursor.getColumnIndex(KEY_USER_CERTIFICATE)));
282 profile.setMTU(getInt(cursor, cursor.getColumnIndex(KEY_MTU)));
283 profile.setPort(getInt(cursor, cursor.getColumnIndex(KEY_PORT)));
284 profile.setSplitTunneling(getInt(cursor, cursor.getColumnIndex(KEY_SPLIT_TUNNELING)));
285 return profile;
286 }
287
288 private ContentValues ContentValuesFromVpnProfile(VpnProfile profile)
289 {
290 ContentValues values = new ContentValues();
291 values.put(KEY_NAME, profile.getName());
292 values.put(KEY_GATEWAY, profile.getGateway());
293 values.put(KEY_VPN_TYPE, profile.getVpnType().getIdentifier());
294 values.put(KEY_USERNAME, profile.getUsername());
295 values.put(KEY_PASSWORD, profile.getPassword());
296 values.put(KEY_CERTIFICATE, profile.getCertificateAlias());
297 values.put(KEY_USER_CERTIFICATE, profile.getUserCertificateAlias());
298 values.put(KEY_MTU, profile.getMTU());
299 values.put(KEY_PORT, profile.getPort());
300 values.put(KEY_SPLIT_TUNNELING, profile.getSplitTunneling());
301 return values;
302 }
303
304 private Integer getInt(Cursor cursor, int columnIndex)
305 {
306 return cursor.isNull(columnIndex) ? null : cursor.getInt(columnIndex);
307 }
308 }