-
Notifications
You must be signed in to change notification settings - Fork 1
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
Initial implementation #4
Changes from all commits
17cd4ee
508e60e
443d622
6094a99
b575f8a
5aaeb8c
fc6eb74
74539f5
d892719
fa9061d
b986f33
bc7da8c
c9a0779
c57c74c
7a37566
7951a5c
b5bc5af
ab6fafb
b43c1f3
234648d
afed114
b541864
32a759f
6f6b42c
9a1c801
d486531
a4f7676
df6d3e2
a7f5b9e
6cc45f9
b850dfd
7bc6974
a1c1026
68ee0f7
26972a1
f369e51
b6b6c59
ed26c9e
640c579
f1f6c70
f38cbb7
8b3d8a3
af62007
e796c83
a87531c
fbeb6d2
604d0e0
a903b2d
d8bcfbd
2158116
915adce
5a9b045
50a4ae5
d45132a
3a190b4
42236fa
a5f7649
716be98
7f5060b
1ff141f
54de164
e3354a9
4166f8e
78883fc
8660b5a
3a198d3
93e12e5
26205f6
7c97610
952a0a1
2e83b85
c4dcc78
ce39b0d
9908c43
f60d230
b60c6d5
29e46a9
08f812d
390cef9
40d8089
63a74a3
6a35acc
3fffd01
60bc515
8d882cb
3ecc5d9
890f289
0219d31
1579c0a
caa2fbc
089205c
50369cd
816e475
4d9de90
99e9083
fc354d5
48db04a
8bb93a5
283a6e1
787d74d
4bb3a30
10cdbb5
3976c36
09ce412
9131aac
1d595a7
17a9642
ba51ef3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
messaging/src/androidTest/assets/image.jpg filter=lfs diff=lfs merge=lfs -text |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
*.iml | ||
.gradle | ||
/local.properties | ||
/.idea/caches | ||
/.idea/libraries | ||
/.idea/modules.xml | ||
/.idea/workspace.xml | ||
/.idea/navEditor.xml | ||
/.idea/assetWizardSettings.xml | ||
.DS_Store | ||
/build | ||
/captures | ||
.externalNativeBuild | ||
.cxx | ||
local.properties |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# messaging-android | ||
This library provides an API to facilitate secure end-to-end encrypted messaging on Android devices, | ||
backed by a [fork of libsignal](https://github.com/getlantern/libsignal-protocol-java/) and | ||
communicating via a [tassis](https://github.com/getlantern/tassis) messaging server. | ||
|
||
messaging-android is currently used in [Lantern](https://lantern.io/) but is intended to be usable | ||
by other parties in their own clients. tassis will eventually support federation, such that 3rd | ||
parties can host their own back end and interoperate with other messaging clients. | ||
|
||
## Protocol Buffers | ||
messaging-android communicates with Tassis and internally stores data using protocol buffers. | ||
Messages exchanged with tassis are defined in [Messages.proto](messaging/src/main/protos/Messages.proto), | ||
which is just a copy of the protocol buffers defined in [tassis](https://github.com/getlantern/tassis/blob/main/model/Messages.proto). | ||
|
||
The messaging-android data model is defined in [Model.proto](messaging/src/main/protos/Model.proto). | ||
|
||
## Data Model | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we possibly add a brief overview to the top of the README instead of starting out with the data model? That this is an Android messaging library, Lantern Android integrates it, it re-uses code from Signal's protocol, etc? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. Let me know if there's anything else you'd like to see in there. |
||
messaging-android stores data in an [encrypted key-value store](https://github.com/getlantern/db-android/) | ||
using keys that follow the below convention. | ||
|
||
### /me (Model.Contact) | ||
The contact entry for the user themselves. | ||
|
||
### /contacts/d/[identityKey] (Model.Contact) | ||
A direct contact, identified by their public IdentityKey | ||
|
||
### /contacts/g/[groupId] (Model.Contact) | ||
A group contact, identified by its group id | ||
|
||
### /cba/[timestamp]/[d/[identityKey]|g/[groupId]] | ||
An index of Contacts by most recent activity. A given Contact will appear only once in this index. | ||
|
||
### /m/[senderIdentityKey]/[messageId] (Model.StoredMessage) | ||
The full content of all Messages are stored here, including both sent and received messages. | ||
The messageId is an id that's unique for messages sent from the given senderIdentityKey (in practice | ||
it's a type 4 UUID). | ||
|
||
### /cm/[d/[identityKey]|g/[groupId]]/[timestamp]/[senderIdentityKey]/[messageId] | ||
An index of all messages for a given Contact, by the sent timestamp of the message. | ||
|
||
### /dm/[disappearAt]/[senderIdentityKey]/[messageId] | ||
An index of all messages that are supposed to auto disappear by some time (in unix milliseconds) | ||
|
||
### /spam/[senderIdentityKey]/[timestamp]/[messageId] (Model.StoredMessage) | ||
Messages that aren't worth showing to the user for one reason or another. | ||
|
||
### /o/[timestamp]/[messageId] (Model.OutboundMessage) | ||
A queue of outbound messages that are pending send. If sending to some recipients fails, messages | ||
will be re-queued here for a limited period of time until they either send successfully or time | ||
runs out. | ||
|
||
### /ia/[senderIdentityKey]/[timestamp]/[messageId]/[attachmentId] (Model.InboundAttachment) | ||
A queue of inbound attachments that are pending download. If downloading fails, downloads will be | ||
re-queued here for a limited period of time until they either send successfully or time runs out. | ||
hwh33 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Included Signal Code | ||
The included Signal code (like AttachmentCipherInputStream) comes from https://github.com/signalapp/Signal-Android, not from https://github.com/signalapp/libsignal-service-java | ||
|
||
## ktlint | ||
This project is formatted and linted with ktlint using the [ktlint-gradle plugin](https://github.com/JLLeitschuh/ktlint-gradle). | ||
|
||
You can install the [ktlint Intellij plugin](https://plugins.jetbrains.com/plugin/15057-ktlint-unofficial-) | ||
for some support for linting within Android Studio. | ||
|
||
### Add Commit Hook | ||
./gradlew addKtlintCheckGitPreCommitHook | ||
|
||
This adds a pre commit hook that lints all staged files upon commit. | ||
|
||
### Manually Auto-format | ||
./gradlew ktlintFormat | ||
|
||
This auto-formats all Kotlin files in the project. | ||
|
||
### Manually Check | ||
./gradlew ktlintCheck | ||
|
||
This manually runs the linter against all Kotlin files in the project. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Top-level build file where you can add configuration options common to all sub-projects/modules. | ||
buildscript { | ||
ext.kotlin_version = "1.4.32" | ||
ext.ktor_version = "1.5.2" | ||
|
||
repositories { | ||
google() | ||
jcenter() | ||
maven { | ||
url "https://plugins.gradle.org/m2/" | ||
} | ||
} | ||
|
||
dependencies { | ||
classpath "com.android.tools.build:gradle:4.1.3" | ||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||
classpath("org.jlleitschuh.gradle:ktlint-gradle:10.1.0") | ||
|
||
// NOTE: Do not place your application dependencies here; they belong | ||
// in the individual module build.gradle files | ||
} | ||
} | ||
|
||
allprojects { | ||
repositories { | ||
google() | ||
jcenter() | ||
mavenCentral() | ||
maven { url "https://www.jitpack.io" } | ||
} | ||
|
||
apply plugin: "org.jlleitschuh.gradle.ktlint" | ||
|
||
ktlint { | ||
android = true | ||
} | ||
} | ||
|
||
task clean(type: Delete) { | ||
delete rootProject.buildDir | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Project-wide Gradle settings. | ||
# IDE (e.g. Android Studio) users: | ||
# Gradle settings configured through the IDE *will override* | ||
# any settings specified in this file. | ||
# For more details on how to configure your build environment visit | ||
# http://www.gradle.org/docs/current/userguide/build_environment.html | ||
# Specifies the JVM arguments used for the daemon process. | ||
# The setting is particularly useful for tweaking memory settings. | ||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 | ||
# When configured, Gradle will run in incubating parallel mode. | ||
# This option should only be used with decoupled projects. More details, visit | ||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects | ||
# org.gradle.parallel=true | ||
# AndroidX package structure to make it clearer which packages are bundled with the | ||
# Android operating system, and which are packaged with your app"s APK | ||
# https://developer.android.com/topic/libraries/support-library/androidx-rn | ||
android.useAndroidX=true | ||
# Automatically convert third-party libraries to use AndroidX | ||
android.enableJetifier=true | ||
# Kotlin code style for this project: "official" or "obsolete": | ||
kotlin.code.style=official |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#Wed Mar 10 20:46:29 CST 2021 | ||
distributionBase=GRADLE_USER_HOME | ||
distributionPath=wrapper/dists | ||
zipStoreBase=GRADLE_USER_HOME | ||
zipStorePath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
#!/usr/bin/env sh | ||
|
||
############################################################################## | ||
## | ||
## Gradle start up script for UN*X | ||
## | ||
############################################################################## | ||
|
||
# Attempt to set APP_HOME | ||
# Resolve links: $0 may be a link | ||
PRG="$0" | ||
# Need this for relative symlinks. | ||
while [ -h "$PRG" ] ; do | ||
ls=`ls -ld "$PRG"` | ||
link=`expr "$ls" : '.*-> \(.*\)$'` | ||
if expr "$link" : '/.*' > /dev/null; then | ||
PRG="$link" | ||
else | ||
PRG=`dirname "$PRG"`"/$link" | ||
fi | ||
done | ||
SAVED="`pwd`" | ||
cd "`dirname \"$PRG\"`/" >/dev/null | ||
APP_HOME="`pwd -P`" | ||
cd "$SAVED" >/dev/null | ||
|
||
APP_NAME="Gradle" | ||
APP_BASE_NAME=`basename "$0"` | ||
|
||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
DEFAULT_JVM_OPTS="" | ||
|
||
# Use the maximum available, or set MAX_FD != -1 to use that value. | ||
MAX_FD="maximum" | ||
|
||
warn () { | ||
echo "$*" | ||
} | ||
|
||
die () { | ||
echo | ||
echo "$*" | ||
echo | ||
exit 1 | ||
} | ||
|
||
# OS specific support (must be 'true' or 'false'). | ||
cygwin=false | ||
msys=false | ||
darwin=false | ||
nonstop=false | ||
case "`uname`" in | ||
CYGWIN* ) | ||
cygwin=true | ||
;; | ||
Darwin* ) | ||
darwin=true | ||
;; | ||
MINGW* ) | ||
msys=true | ||
;; | ||
NONSTOP* ) | ||
nonstop=true | ||
;; | ||
esac | ||
|
||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||
|
||
# Determine the Java command to use to start the JVM. | ||
if [ -n "$JAVA_HOME" ] ; then | ||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||
# IBM's JDK on AIX uses strange locations for the executables | ||
JAVACMD="$JAVA_HOME/jre/sh/java" | ||
else | ||
JAVACMD="$JAVA_HOME/bin/java" | ||
fi | ||
if [ ! -x "$JAVACMD" ] ; then | ||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||
Please set the JAVA_HOME variable in your environment to match the | ||
location of your Java installation." | ||
fi | ||
else | ||
JAVACMD="java" | ||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
Please set the JAVA_HOME variable in your environment to match the | ||
location of your Java installation." | ||
fi | ||
|
||
# Increase the maximum file descriptors if we can. | ||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then | ||
MAX_FD_LIMIT=`ulimit -H -n` | ||
if [ $? -eq 0 ] ; then | ||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | ||
MAX_FD="$MAX_FD_LIMIT" | ||
fi | ||
ulimit -n $MAX_FD | ||
if [ $? -ne 0 ] ; then | ||
warn "Could not set maximum file descriptor limit: $MAX_FD" | ||
fi | ||
else | ||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | ||
fi | ||
fi | ||
|
||
# For Darwin, add options to specify how the application appears in the dock | ||
if $darwin; then | ||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||
fi | ||
|
||
# For Cygwin, switch paths to Windows format before running java | ||
if $cygwin ; then | ||
APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||
JAVACMD=`cygpath --unix "$JAVACMD"` | ||
|
||
# We build the pattern for arguments to be converted via cygpath | ||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | ||
SEP="" | ||
for dir in $ROOTDIRSRAW ; do | ||
ROOTDIRS="$ROOTDIRS$SEP$dir" | ||
SEP="|" | ||
done | ||
OURCYGPATTERN="(^($ROOTDIRS))" | ||
# Add a user-defined pattern to the cygpath arguments | ||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then | ||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | ||
fi | ||
# Now convert the arguments - kludge to limit ourselves to /bin/sh | ||
i=0 | ||
for arg in "$@" ; do | ||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | ||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | ||
|
||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | ||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | ||
else | ||
eval `echo args$i`="\"$arg\"" | ||
fi | ||
i=$((i+1)) | ||
done | ||
case $i in | ||
(0) set -- ;; | ||
(1) set -- "$args0" ;; | ||
(2) set -- "$args0" "$args1" ;; | ||
(3) set -- "$args0" "$args1" "$args2" ;; | ||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||
esac | ||
fi | ||
|
||
# Escape application args | ||
save () { | ||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | ||
echo " " | ||
} | ||
APP_ARGS=$(save "$@") | ||
|
||
# Collect all arguments for the java command, following the shell quoting and substitution rules | ||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | ||
|
||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong | ||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then | ||
cd "$(dirname "$0")" | ||
fi | ||
|
||
exec "$JAVACMD" "$@" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There must be a better way of sharing this model. Perhaps a repo which defines the shared models, even if it's currently only this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm on the fence about this. I agree it's a little iffy to copy it, but OTOH a git submodule for just one file seems like a lot of work of its own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a compromise of sorts: what if you added a note at the top of this file like: