Skip to content

Add service account to firebase event proxy #246

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ addons:
- expect
before_install:
- openssl aes-256-cbc -K $encrypted_37a4f399de75_key -iv $encrypted_37a4f399de75_iv -in service-account.json.enc -out service-account.json -d
&& openssl aes-256-cbc -K $encrypted_37a4f399de75_key -iv $encrypted_37a4f399de75_iv -in service-account.json.enc -out appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/gae-firebase-secrets.json -d
&& export GOOGLE_APPLICATION_CREDENTIALS=$TRAVIS_BUILD_DIR/service-account.json GCLOUD_PROJECT=cloud-samples-tests
|| true
# Skip the install step, since Maven will download the dependencies we need
Expand Down
2 changes: 1 addition & 1 deletion appengine/firebase-event-proxy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ mvn appengine:devserver
### Python App Engine Listener
```
cd gae-firebase-listener-python
dev_appserver .
dev_appserver.py .
```

## Deploying
Expand Down
12 changes: 6 additions & 6 deletions appengine/firebase-event-proxy/gae-firebase-event-proxy/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,19 @@
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.firebase</groupId>
<artifactId>firebase-client-jvm</artifactId>
<version>[1.0.8,)</version>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-server-sdk</artifactId>
<version>[3.0.0,)</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.firebase</groupId>
<artifactId>firebase-token-generator</artifactId>
<version>2.0.0</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>

<!-- Test Dependencies -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,49 @@

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.firebase.client.AuthData;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
import com.firebase.security.token.TokenGenerator;
import com.google.appengine.api.utils.SystemProperty;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;

public class FirebaseEventProxy {

private static final Logger log = Logger.getLogger(FirebaseEventProxy.class.getName());

private String firebaseAuthToken;

public FirebaseEventProxy() {
// Store Firebase authentication token as an instance variable.
this.firebaseAuthToken = this.getFirebaseAuthToken(this.getFirebaseSecret());
String firebaseLocation = "https://crackling-torch-392.firebaseio.com";
Map<String, Object> databaseAuthVariableOverride = new HashMap<String, Object>();
// uid and provider will have to match what you have in your firebase security rules
databaseAuthVariableOverride.put("uid", "gae-firebase-event-proxy");
databaseAuthVariableOverride.put("provider", "com.example");
try {
FirebaseOptions options = new FirebaseOptions.Builder()
.setServiceAccount(new FileInputStream("gae-firebase-secrets.json"))
.setDatabaseUrl(firebaseLocation)
.setDatabaseAuthVariableOverride(databaseAuthVariableOverride).build();
FirebaseApp.initializeApp(options);
} catch (IOException e) {
throw new RuntimeException(
"Error reading firebase secrets from file: src/main/webapp/gae-firebase-secrets.json: "
+ e.getMessage());
}
}

public void start() {
String firebaseLocation = "https://gae-fb-proxy.firebaseio.com/";
Firebase firebase = new Firebase(firebaseLocation);

// Authenticate with Firebase
firebase.authWithCustomToken(this.firebaseAuthToken, new Firebase.AuthResultHandler() {
@Override
public void onAuthenticationError(FirebaseError error) {
log.severe("Firebase login error: " + error.getMessage());
}

@Override
public void onAuthenticated(AuthData auth) {
log.info("Firebase login successful");
}
});
DatabaseReference firebase = FirebaseDatabase.getInstance().getReference();

// Subscribe to value events. Depending on use case, you may want to subscribe to child events
// through childEventListener.
Expand All @@ -73,10 +70,10 @@ public void onDataChange(DataSnapshot snapshot) {
if (snapshot.exists()) {
try {
// Convert value to JSON using Jackson
String json = new ObjectMapper().writeValueAsString(snapshot.getValue());
String json = new ObjectMapper().writeValueAsString(snapshot.getValue(false));

// Replace the URL with the url of your own listener app.
URL dest = new URL("http://gae-firebase-listener-python.appspot.com/log");
URL dest = new URL("http://localhost:8080/log");
HttpURLConnection connection = (HttpURLConnection) dest.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
Expand Down Expand Up @@ -109,36 +106,9 @@ public void onDataChange(DataSnapshot snapshot) {
}

@Override
public void onCancelled(FirebaseError error) {
public void onCancelled(DatabaseError error) {
log.severe("Firebase connection cancelled: " + error.getMessage());
}
});
}

private String getFirebaseSecret() {
Properties props = new Properties();
try {
// Read from src/main/webapp/firebase-secrets.properties
InputStream inputStream = new FileInputStream("firebase-secret.properties");
props.load(inputStream);
return props.getProperty("firebaseSecret");
} catch (java.net.MalformedURLException e) {
throw new RuntimeException(
"Error reading firebase secrets from file: src/main/webapp/firebase-sercrets.properties: "
+ e.getMessage());
} catch (IOException e) {
throw new RuntimeException(
"Error reading firebase secrets from file: src/main/webapp/firebase-sercrets.properties: "
+ e.getMessage());
}
}

private String getFirebaseAuthToken(String firebaseSecret) {
Map<String, Object> authPayload = new HashMap<String, Object>();
// uid and provider will have to match what you have in your firebase security rules
authPayload.put("uid", "gae-firebase-event-proxy");
authPayload.put("provider", "com.example");
TokenGenerator tokenGenerator = new TokenGenerator(firebaseSecret);
return tokenGenerator.createToken(authPayload);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def post(self):
user = self.request.headers.get('X-Appengine-Inbound-Appid', None)
if user and user in allowed_users:
firebaseSnapshot = self.request.params['fbSnapshot']
print firebaseSnapshot
print "Got data: %s" % firebaseSnapshot
else:
print "Got unauthenticated user: %s" % user

Expand Down
39 changes: 39 additions & 0 deletions appengine/firebase-event-proxy/run_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -e
set -x

# Expected to run this file from root of GitHub project.
(
cd appengine/firebase-event-proxy/

expect -c '
spawn dev_appserver.py gae-firebase-listener-python
set python_listener_id $spawn_id
spawn mvn --file gae-firebase-event-proxy appengine:devserver -Dappengine.port=8888
set event_proxy_id $spawn_id
expect {
# Listen for Got data from Python listener
-i $python_listener_id "Got data" {
exit
} -i $event_proxy_id "Sent" {
send_user Event proxy sent data successful
}
}
sleep 20
exit 1
'
)
1 change: 1 addition & 0 deletions travis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ for testdir in ${devserver_tests[@]} ; do
./java-repo-tools/test-devserver.sh "${testdir}"
done

appengine/firebase-event-proxy/run_tests.sh