mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-12-23 11:21:29 +00:00
Pass API key via command line instead of setting it in config.xml.
This commit is contained in:
parent
c17da6595a
commit
d81af707ec
8 changed files with 53 additions and 43 deletions
|
@ -47,7 +47,7 @@ public class PollWebGuiAvailableTaskTest extends AndroidTestCase {
|
||||||
}.execute(mConfig.getWebGuiUrl());
|
}.execute(mConfig.getWebGuiUrl());
|
||||||
latch.await(1, TimeUnit.SECONDS);
|
latch.await(1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
new PostTask().execute(mConfig.getWebGuiUrl(), PostTask.URI_SHUTDOWN, mConfig.getApiKey());
|
new PostTask().execute(mConfig.getWebGuiUrl(), PostTask.URI_SHUTDOWN,
|
||||||
|
mSyncthing.getApiKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,13 +45,14 @@ public class RestApiTest extends AndroidTestCase {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
}.execute(mConfig.getWebGuiUrl());
|
}.execute(mConfig.getWebGuiUrl());
|
||||||
mApi = new RestApi(getContext(), mConfig.getWebGuiUrl(), mConfig.getApiKey(),
|
mApi = new RestApi(getContext(), mConfig.getWebGuiUrl(),
|
||||||
new RestApi.OnApiAvailableListener() {
|
new RestApi.OnApiAvailableListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onApiAvailable() {
|
public void onApiAvailable() {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
mApi.setApiKey(mSyncthing.getApiKey());
|
||||||
latch.await(1, TimeUnit.SECONDS);
|
latch.await(1, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ public class RestApiTest extends AndroidTestCase {
|
||||||
assertTrue(aBoolean);
|
assertTrue(aBoolean);
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
}.execute(mConfig.getWebGuiUrl(), PostTask.URI_SHUTDOWN, mConfig.getApiKey());
|
}.execute(mConfig.getWebGuiUrl(), PostTask.URI_SHUTDOWN, mSyncthing.getApiKey());
|
||||||
latch.await(1, TimeUnit.SECONDS);
|
latch.await(1, TimeUnit.SECONDS);
|
||||||
ConfigXml.getConfigFile(new TestContext(getContext())).delete();
|
ConfigXml.getConfigFile(new TestContext(getContext())).delete();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,16 @@ public class SyncthingRunnableTest extends AndroidTestCase {
|
||||||
TestContext context = new TestContext(getContext());
|
TestContext context = new TestContext(getContext());
|
||||||
File testFile = new File(context.getFilesDir(), "was_running");
|
File testFile = new File(context.getFilesDir(), "was_running");
|
||||||
assertFalse(testFile.exists());
|
assertFalse(testFile.exists());
|
||||||
String x = testFile.getAbsolutePath();
|
|
||||||
// Inject a differenct command instead of the syncthing binary for testing.
|
// Inject a differenct command instead of the syncthing binary for testing.
|
||||||
new SyncthingRunnable(context, "touch " + testFile.getAbsolutePath() + "\n").run();
|
new SyncthingRunnable(context, "touch " + testFile.getAbsolutePath() + "\n").run();
|
||||||
assertTrue(testFile.exists());
|
assertTrue(testFile.exists());
|
||||||
testFile.delete();
|
testFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
public void testApiKey() {
|
||||||
|
SyncthingRunnable st = new SyncthingRunnable(new TestContext(getContext()), "ls\n");
|
||||||
|
assertEquals(20, st.getApiKey().length());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,6 @@ public class ConfigXmlTest extends AndroidTestCase {
|
||||||
mConfig.updateIfNeeded();
|
mConfig.updateIfNeeded();
|
||||||
assertNotSame(oldTime, ConfigXml.getConfigFile(mContext).lastModified());
|
assertNotSame(oldTime, ConfigXml.getConfigFile(mContext).lastModified());
|
||||||
assertNotSame(oldSize, ConfigXml.getConfigFile(mContext).lastModified());
|
assertNotSame(oldSize, ConfigXml.getConfigFile(mContext).lastModified());
|
||||||
assertNotNull(mConfig.getApiKey());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,15 +167,21 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
*/
|
*/
|
||||||
private HashMap<String, Model> mCachedModelInfo = new HashMap<>();
|
private HashMap<String, Model> mCachedModelInfo = new HashMap<>();
|
||||||
|
|
||||||
public RestApi(Context context, String url, String apiKey, OnApiAvailableListener listener) {
|
public RestApi(Context context, String url, OnApiAvailableListener listener) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mUrl = url;
|
mUrl = url;
|
||||||
mApiKey = apiKey;
|
|
||||||
mNotificationManager = (NotificationManager)
|
mNotificationManager = (NotificationManager)
|
||||||
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
mOnApiAvailableListener = listener;
|
mOnApiAvailableListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The API key set in the syncthing instance, required to access the API.
|
||||||
|
*/
|
||||||
|
public void setApiKey(String apiKey) {
|
||||||
|
mApiKey = apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of previous calls to {@link #tryIsAvailable()}.
|
* Number of previous calls to {@link #tryIsAvailable()}.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the syncthing binary from command line, and prints its output to logcat.
|
* Runs the syncthing binary from command line, and prints its output to logcat.
|
||||||
|
@ -24,11 +25,13 @@ public class SyncthingRunnable implements Runnable {
|
||||||
|
|
||||||
private static final String TAG_NATIVE = "SyncthingNativeCode";
|
private static final String TAG_NATIVE = "SyncthingNativeCode";
|
||||||
|
|
||||||
private Handler mHandler;
|
private final Context mContext;
|
||||||
|
|
||||||
private String mCommand;
|
private final String mCommand;
|
||||||
|
|
||||||
private Context mContext;
|
private final Handler mHandler;
|
||||||
|
|
||||||
|
private final String mApiKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs instance.
|
* Constructs instance.
|
||||||
|
@ -39,6 +42,18 @@ public class SyncthingRunnable implements Runnable {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mCommand = command;
|
mCommand = command;
|
||||||
mHandler = new Handler();
|
mHandler = new Handler();
|
||||||
|
|
||||||
|
char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
Random random = new Random();
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
sb.append(chars[random.nextInt(chars.length)]);
|
||||||
|
}
|
||||||
|
mApiKey = sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiKey() {
|
||||||
|
return mApiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,6 +66,7 @@ public class SyncthingRunnable implements Runnable {
|
||||||
dos = new DataOutputStream(process.getOutputStream());
|
dos = new DataOutputStream(process.getOutputStream());
|
||||||
// Set home directory to data folder for syncthing to use.
|
// Set home directory to data folder for syncthing to use.
|
||||||
dos.writeBytes("HOME=" + mContext.getFilesDir() + " ");
|
dos.writeBytes("HOME=" + mContext.getFilesDir() + " ");
|
||||||
|
dos.writeBytes("STGUIAPIKEY=" + mApiKey + " ");
|
||||||
// Call syncthing with -home (as it would otherwise use "~/.config/syncthing/".
|
// Call syncthing with -home (as it would otherwise use "~/.config/syncthing/".
|
||||||
dos.writeBytes(mCommand + " -home " + mContext.getFilesDir() + "\n");
|
dos.writeBytes(mCommand + " -home " + mContext.getFilesDir() + "\n");
|
||||||
dos.writeBytes("exit\n");
|
dos.writeBytes("exit\n");
|
||||||
|
|
|
@ -73,6 +73,8 @@ public class SyncthingService extends Service {
|
||||||
|
|
||||||
private RestApi mApi;
|
private RestApi mApi;
|
||||||
|
|
||||||
|
private SyncthingRunnable mSyncthingRunnable;
|
||||||
|
|
||||||
private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this);
|
private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -130,7 +132,7 @@ public class SyncthingService extends Service {
|
||||||
protected void onPostExecute(Boolean aBoolean) {
|
protected void onPostExecute(Boolean aBoolean) {
|
||||||
new StartupTask().execute();
|
new StartupTask().execute();
|
||||||
}
|
}
|
||||||
}.execute(mConfig.getWebGuiUrl(), PostTask.URI_RESTART, mConfig.getApiKey());
|
}.execute(mConfig.getWebGuiUrl(), PostTask.URI_RESTART, mSyncthingRunnable.getApiKey());
|
||||||
} else if (mCurrentState != State.INIT) {
|
} else if (mCurrentState != State.INIT) {
|
||||||
mDeviceStateHolder.update(intent);
|
mDeviceStateHolder.update(intent);
|
||||||
updateState();
|
updateState();
|
||||||
|
@ -161,8 +163,10 @@ public class SyncthingService extends Service {
|
||||||
mCurrentState = State.STARTING;
|
mCurrentState = State.STARTING;
|
||||||
registerOnWebGuiAvailableListener(mApi);
|
registerOnWebGuiAvailableListener(mApi);
|
||||||
new PollWebGuiAvailableTaskImpl().execute(mConfig.getWebGuiUrl());
|
new PollWebGuiAvailableTaskImpl().execute(mConfig.getWebGuiUrl());
|
||||||
new Thread(new SyncthingRunnable(
|
mSyncthingRunnable =
|
||||||
this, getApplicationInfo().dataDir + "/" + BINARY_NAME)).start();
|
new SyncthingRunnable(this, getApplicationInfo().dataDir + "/" + BINARY_NAME);
|
||||||
|
mApi.setApiKey(mSyncthingRunnable.getApiKey());
|
||||||
|
new Thread(mSyncthingRunnable).start();
|
||||||
}
|
}
|
||||||
// Stop syncthing.
|
// Stop syncthing.
|
||||||
else {
|
else {
|
||||||
|
@ -237,11 +241,11 @@ public class SyncthingService extends Service {
|
||||||
/**
|
/**
|
||||||
* Sets up the initial configuration, updates the config when coming from an old
|
* Sets up the initial configuration, updates the config when coming from an old
|
||||||
* version, and reads syncthing URL and API key (these are passed internally as
|
* version, and reads syncthing URL and API key (these are passed internally as
|
||||||
* {@code Pair<String, String>}.
|
* {@code Pair<String, String>}. TODO
|
||||||
*/
|
*/
|
||||||
private class StartupTask extends AsyncTask<Void, Void, Pair<String, String>> {
|
private class StartupTask extends AsyncTask<Void, Void, String> {
|
||||||
@Override
|
@Override
|
||||||
protected Pair<String, String> doInBackground(Void... voids) {
|
protected String doInBackground(Void... voids) {
|
||||||
moveConfigFiles();
|
moveConfigFiles();
|
||||||
mConfig = new ConfigXml(SyncthingService.this);
|
mConfig = new ConfigXml(SyncthingService.this);
|
||||||
mConfig.updateIfNeeded();
|
mConfig.updateIfNeeded();
|
||||||
|
@ -252,12 +256,12 @@ public class SyncthingService extends Service {
|
||||||
mConfig.createCameraRepo();
|
mConfig.createCameraRepo();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Pair<>(mConfig.getWebGuiUrl(), mConfig.getApiKey());
|
return mConfig.getWebGuiUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Pair<String, String> urlAndKey) {
|
protected void onPostExecute(String webGuiUrl) {
|
||||||
mApi = new RestApi(SyncthingService.this, urlAndKey.first, urlAndKey.second,
|
mApi = new RestApi(SyncthingService.this, webGuiUrl,
|
||||||
new RestApi.OnApiAvailableListener() {
|
new RestApi.OnApiAvailableListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onApiAvailable() {
|
public void onApiAvailable() {
|
||||||
|
|
|
@ -65,16 +65,12 @@ public class ConfigXml {
|
||||||
return "http://" + getGuiElement().getElementsByTagName("address").item(0).getTextContent();
|
return "http://" + getGuiElement().getElementsByTagName("address").item(0).getTextContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getApiKey() {
|
|
||||||
return getGuiElement().getElementsByTagName("apikey").item(0).getTextContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the config file.
|
* Updates the config file.
|
||||||
* <p/>
|
*
|
||||||
* Coming from 0.2.0 and earlier, globalAnnounceServer value "announce.syncthing.net:22025" is
|
* Coming from 0.2.0 and earlier, globalAnnounceServer value "announce.syncthing.net:22025" is
|
||||||
* replaced with "194.126.249.5:22025" (as domain resolve is broken).
|
* replaced with "194.126.249.5:22025" (as domain resolve is broken).
|
||||||
* <p/>
|
*
|
||||||
* Coming from 0.3.0 and earlier, the ignorePerms flag is set to true on every repository.
|
* Coming from 0.3.0 and earlier, the ignorePerms flag is set to true on every repository.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("SdCardPath")
|
@SuppressWarnings("SdCardPath")
|
||||||
|
@ -83,23 +79,6 @@ public class ConfigXml {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
Element options = (Element) mConfig.getDocumentElement()
|
Element options = (Element) mConfig.getDocumentElement()
|
||||||
.getElementsByTagName("options").item(0);
|
.getElementsByTagName("options").item(0);
|
||||||
Element gui = (Element) mConfig.getDocumentElement()
|
|
||||||
.getElementsByTagName("gui").item(0);
|
|
||||||
|
|
||||||
// Create an API key if it does not exist.
|
|
||||||
if (gui.getElementsByTagName("apikey").getLength() == 0) {
|
|
||||||
Log.i(TAG, "Initializing API key with random string");
|
|
||||||
char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
Random random = new Random();
|
|
||||||
for (int i = 0; i < 20; i++) {
|
|
||||||
sb.append(chars[random.nextInt(chars.length)]);
|
|
||||||
}
|
|
||||||
Element apiKey = mConfig.createElement("apikey");
|
|
||||||
apiKey.setTextContent(sb.toString());
|
|
||||||
gui.appendChild(apiKey);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hardcode default globalAnnounceServer ip.
|
// Hardcode default globalAnnounceServer ip.
|
||||||
Element globalAnnounceServer = (Element)
|
Element globalAnnounceServer = (Element)
|
||||||
|
|
Loading…
Reference in a new issue