Best way to store secret keys in Android applications - android

I have a Parse account that I'm using to store user data for my Android application. Because I'm using source control, I don't want to leave my secret key embedded in the code. Is there a way to have a "config" file that I would keep out of source control, that can then host the key? If that's not feasible, what are the best practices of handling such a situation?

Yes, you can create a folder outside of source control, put a file called app.properties in there, put your key in that properties file and add the folder to your build path. Then use a properties loader to load it from the classpath.
If you have many developers or more than one dev machine, you can set the local properties location as a variable in your build path so that each developer can configure their own.

One option is to put the key in an environment variable and then read it during your build.
in your pom.xml declare a property (secret.key)
<properties>
<secretKey>${env.SECRET_KEY}</secretKey>
<properties>
further down enable "filtering" on your resources
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
In resources maintain a "config.properties" to read with the variable ready for substitution:
secret_key=${secretKey}
Filtering in maven will replace ${secret.key} with the value from your environment variable.
If you are using gradle for your build with Android studio see section 16.6.6.2 on filtering files.
Within build.gradle add the following
import org.apache.tools.ant.filters.FixCrLfFilter
import org.apache.tools.ant.filters.ReplaceTokens
task copyProductionConfig(type: Copy) {
from 'source'
include 'config.properties'
into 'build/targetpath/config'
expand([
secretKey: System.getenv("SECRET_KEY")
])
}
In gradle you can also request input when you run gradlew using
Console console = System.console()
def password = console.readPassword("Enter Secret Key: ")
And then apply it to the appropriate config or source files.

Related

How to store app keys in a separate file locally and load from there in build.gradle?

I have some keys or app_id, for instance, fabric app_id, in my build.gradle, different for different build like -
manifestPlaceholders = [
appIcon : "#mipmap/kj_launcher",
roundappIcon: "#mipmap/kj_launcher",
fabric_id: "fabric_app_id"
]
which I indirectly use in AndroidManifest file.
So, my question is, a way to store that fabric_id inside any file which is present locally in my system and then load it over here in the above code, different for the different build?
Just like we do in .properties file and get the value from that inside build.gradle.
I don't want to expose these ids.
There's a number of ways to do this, but the way I do this is to define it the gradle.properties file.
In my local gradle.properties file:
MY_SECRET_API_KEY=Dev_Api_Key_That_I_Dont_Care_If_Devs_Have_Access_To
Then on my CI build server, I have a script that replaces Dev_Api_Key_That_I_Dont_Care_If_Devs_Have_Access_To with a value of the production API key.

How to set Default Organization of Sentry.io using sentry-cli

I'm going to use Sentry for My Android app. My company is using a self-hosted Sentry, version 9.0.0. I get the below answer when I run sentry-cli info command using sentry-cli:
Sentry Server: https://log.mydomain.com
Default Organization: -
Default Project: -
It didn't recognize Default Organization and Default Project. How can I set these data?
Did you define the Sentry Project and Organization somewhere?
Some commands require your Sentry Organization and/or Projects slugs.
There are multiple ways to provide these values:
Command line argument, like; --org
Environment variables, like; SENTRY_ORG
Adding to a configuration file
As per the docs:
You can add to the configuration file (~/.sentryclirc) the keys:
defaults.project
defaults.org
Or use the environment variables: SENTRY_PROJECT and SENTRY_ORG

Jenkins: adding CUSTOM variables for a build

Jenkins successfully create build for Android and then uploads to an S3 server. The build contains environment name, version number that is different for each build. These version number, environments are read from POM profiles. An example URL of s3 http://example.com/android/staging/ABC-Project-v0.1.58-staging-aligned.apk
I get the file name by this
cd $WORKSPACE/target/
FILE_NAME=$(echo *aligned.apk)
So my link will be http://example.com/dev/FILE_NAME
But this is only visible in shell script. I want to use this in an email template so that the Software test engineers can access it. I was looking for a way in which I can temporarily assign this value to a variable and then put that in the email template.
Email template is:
<html>
<body>
<h3>$PROJECT_NAME</h3>
<h4>Build #$BUILD_NUMBER - $BUILD_STATUS</h4>
<h4>${CAUSE}</h4>
<h4>$DEFAULT_CONTENT</h4>
<h4>Git Branch: ${GIT_BRANCH}</h4>
Changes since the last build:
${CHANGES}
</body>
</html>
Assuming that the email step is a later part of the Jenkins build process, you'll need to use the EnvInject plugin. From its own example use cases you can: inject variables as a build step obtained from a file filled in by a previous build step.
You could set these when parsing your POM (either in Maven directly, or you could parse it manually with something like a build step using the Groovy plugin and XmlSlurper (we do this actually)), and then they'd be available as environment variables (e.g. $CHANGES, $CAUSE etc) for your email templater script later on.
OK, I'm about to offer two things that are kind of ugly but working perfect:
In both you can put the output (the link you want) in a /tmp/job.output.tmp file and then:
use the post build task plugin - when the work ERROR or EXCEPTION or whatever you want is there, run sendEmail from bash to the people you want with the context of the file.
a little bash and everything is great.
this is probably more nice: use the https://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin editable mail notification to send your users the console output / the file in zip / not zipped as you like when the build fails / stable again and such. They have so much options..

How to pass a parameter to the Java code in run/debug configuration from Android Studio

My android app does some http requests to my server. However sometimes I am debugging the new api code that runs on my development machine. I would like to be able to pass something (like an environment variable) so in my code, if it's present I would be able to use that as the hostname for the api requests from the android emulator.
So I'm looking for a way to pass something like:
API_SERVER=http://10.0.2.2/myapp/
and in my code I would use it somehow, for example:
final static String API_SERVER_REAL = "http://example.com/";
final String apiServerOverride = System.getenv("API_SERVER");
final String API_SERVER = (null != apiServerOverride && !apiServerOverride.isEmpty() ? apiServerOverride : API_SERVER_REAL);
I know this thread is quite old, but in my opinion none of provided answers actually solves the problem. Flavors are ill-suited for parametrizing your build with things like API URLs, and even worse for things like API keys etc.
Firstly, build.gradle which defines flavors is part of project source, therefore it must not contain such information in order to be safely committed into source control systems.
Secondly, a need may arise to test different flavors against different API endpoints/keys. What if you just want to hit some debug http server you just created to solve a bug? Would you create a flavor for that? Probably not... Flavors are good for things like "free flavor" and "premium flavor".
This problem is easily solved using gradles -P flag. You can access gradle properties that are passed this way as regular variables inside your gradle.build, and you can vary it's behavior accordingly.
If you want to push this flags further into your application you can use Scott's solution that was posted here, combined with the provided flag.
The build command would then probably look like:
$ gradle build -Papiroot=http://www.example.com
And in your build.gradle you would define the writeValue task like this:
task writeValue(type:Exec) {
commandLine '/usr/local/bin/adb', 'shell', "echo 'API_SERVER=${apiroot}' > /data/data/values.properties"
}
FYI the -P flag can be easily configured in Android Studio by navigating from the menu:
Run -> Run/Debug Configurations -> Defaults -> Gradle -> Script Parameters
Probably the simplest thing is to write the data you want to pass to a file on the device in /data/data; your Android app can read the device trivially (perhaps make it a .properties file and use java.util.Properties to read it in). To write it out, use this kind of task in your build.gradle file (and use the correct path to the adb command for your setup):
task writeValue(type:Exec) {
commandLine '/usr/local/bin/adb', 'shell', 'echo \'API_SERVER=http://10.0.2.2/myapp/\' > /data/data/values.properties'
}
There's documentation on Gradle exec tasks at http://www.gradle.org/docs/current/dsl/org.gradle.api.tasks.Exec.html
You can execute this task manually from Android Studio by using the Gradle tasks view:
Due to a bug in Android Studio, you cannot pass vm or script parameters from a gradle configuration. The issue is here.
As a workaround in Linux envs (probably Mac too), you can create a bash configuration where you will be able to add all desired parameters.
I suggest using productFlavors. Each flavor can contain environment specific settings. I simply have a class called 'Environment' which contains all the public static final Strings that I need and each product flavor includes an different version of this class with the values set for the environment.

Android Eclipse Switching between debug and release for XML file

I have an XML file that contains some config data for my Android App. In it there is config info that can be used for development and production. E.g. the link to our api can be set as follows:
For production:
<api>api.example.com</api>
For development:
<api>dev.example.com</api>
I keep this config file under /assets/app-config.xml
It is quite a hassle to keep having to remember which setting I have in the XML. Is there a way to automatically configure eclipse/ android so that it uses the production for runtime (export etc.) and the development when in debug mode.
Define multiple resources and use BuildConfig.DEBUG to conditionally get a resource or another:
<string name="url_api">api.example.com</string>
<string name="url_api_dev">dev.example.com</string>
When extracting the resource:
getString(BuildConfig.DEBUG ? R.string.url_api_dev : R.string.url_api);
This constant is set to true as long as you run from Eclipse. When you select the Export Signed Application Package option, it will be set to false.
If you use this method, it is a good idea to be aware of this bug.
Customize your build using ANT
Please refer the following link for more information
http://playaprogrammer.blogspot.com/2013/01/android-build-configuration-tutorial.html
I use this to create test and production builds from single source. You can have different configurations for development, QA, Production...

Categories

Resources