├── .gitignore ├── LICENSE ├── Procfile ├── README.md ├── _config.yml ├── app.json ├── doc └── intro.md ├── project.clj ├── src └── little_finger │ └── web.clj └── test └── little_finger └── core_test.clj /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .envrc -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Avinash Sajjanshetty 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: java $JVM_OPTS -cp target/little-finger-standalone.jar clojure.main -m little-finger.web 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Little Finger 2 | 3 | Little Finger is a set of simple server/client libraries which lets you add a backdoor to your Android/iOS app easily, with a single line of code. The project is based on [this anonymous Quora answer](https://www.quora.com/As-a-software-developer-how-often-do-you-leave-a-backdoor-in-your-code/answers/42071021?share=8fc91108&srid=J6SM). Say, you are a freelancer and often you must have had faced really bad clients who vanish without paying the money promised. Now, using Little Finger you can crash the app remotely if the client vanishes. And when you do receive money, you can make the app work as expected. 4 | 5 | ## How it works 6 | 7 | The Little finger comes with a server component. The client library makes a call to this server and based on the response HTTP status code received it takes an action. If the money is received, it lets the work as expected and never makes another call to the server again. However, if money is not received then it crashes the app. 8 | 9 | From the server, you can also send a local push notification, which app can display. 10 | 11 | It takes only one line of code to start the Little Finger. Start it everytime in `AppDelegate(_:didFinishLaunchingWithOptions:)` if Swift or `Mainactivity.onCreate` if Android. 12 | 13 | ### HTTP Status codes 14 | 15 | Following HTTP status codes are used: 16 | 17 | - If the server sends `HTTP_PAYMENT_REQUIRED` (402) or `HTTP_OK` (200), then payment is expected to receive and Litte Finger lets the app work as usual. Little Finger will keep calling the server everytime it is started to know the status of the payment. 18 | - If the server sends `HTTP_ACCEPTED` (202), then payment has been received. Little Finger updates the app's preferences so that no future network calls are made again. 19 | - If the server sends `HTTP_CONFLICT` (409), then no payment has been received and there is a 20 | conflict. When Little Finger receives 409, it crashes the app. The server also can notification data and Little Finger uses that to display a local notification before crashing. You can be creative and send a notification text saying "You have won $10 million dollars" or other such spammy messages to make the matter worse. 21 | 22 | ## Default behaviours 23 | 24 | 1. If there is no internet available and if app fails to make a HTTP call, then app crashes 25 | 2. If server sends any other responses, other than 202 or 409, app continues to work as expected 26 | 3. If your heroku app is down and app fails to reach then app will continue to work as expected, as heroku sends 404 27 | 28 | Little Finger is fully open source, so you are free to fork, modify these behaviours as per your taste. 29 | 30 | ## Quick instructions 31 | 32 | 1. Install the server on Heroku (click on Deploy on Heroku button at the bottom). Give the response status code as `402` or `200`. 33 | 2. Include Little Finger calling code in your app. If [iOS](https://github.com/avinassh/little-finger-ios): 34 | 35 | ```swift 36 | LittleFinger.start("https://your-heroku-app.heroku.com/status/"); 37 | ``` 38 | 39 | if [Android](https://github.com/avinassh/little-finger-android): 40 | 41 | ```java 42 | LittleFinger.start(this, "https://your-heroku-app.heroku.com/status/"); 43 | ``` 44 | 45 | 3. If you have received the payment or if there is a conflict, then update the Heroku App's environment variable (usually located at - https://dashboard.heroku.com/apps/your-heroku-app/settings, `Config Variables`) accordingly. 46 | 47 | 48 | ## Detailed instructions 49 | 50 | 1. The [Little Finger server](https://github.com/avinassh/little-finger) is written in Clojure and comes with one click Heroku deploy (located at bottom). Click on it and it will do the server installation. 51 | 2. For Swift, check the [swift repo's README](https://github.com/avinassh/little-finger-ios) for detailed installation instructions. 52 | 3. For Android, check the [android repo's README](https://github.com/avinassh/little-finger-android) for detailed installation instructions. 53 | 54 | ## Demo 55 | 56 | Very simple and crude demo apps: [iOS](https://github.com/avinassh/LFDemo-iOS) and [Android](https://github.com/avinassh/LFDemo-Android) 57 | 58 | ## Heroku 59 | 60 | [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/avinassh/little-finger/tree/master) 61 | 62 | ## Name 63 | 64 | The name Little Finger comes from GRRM's A Song of Ice and Fire character [Petyr Baelish](https://en.wikipedia.org/wiki/Petyr_Baelish). 65 | 66 | ## License 67 | 68 | The libraries and server are released under the mighty [MIT license](https://v.mit-license.org/). Please check the `LICENSE` file of respective repository for more details. 69 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-modernist -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "little-finger", 3 | "description": "Little Finger server", 4 | "repository": "https://github.com/avinassh/little-finger", 5 | "keywords": ["clojure", "little-finger"], 6 | "env": { 7 | "RESPONSE_STATUS": { 8 | "description": "The HTTP response status you want from server. Read Little Finger's documentation for more details", 9 | "required": true 10 | }, 11 | "NOTIFICATION_TITLE": { 12 | "description": "Push notification title", 13 | "required": false 14 | }, 15 | "NOTIFICATION_TEXT": { 16 | "description": "Push notification text/body", 17 | "required": false 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /doc/intro.md: -------------------------------------------------------------------------------- 1 | # Introduction to little-finger 2 | 3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/) 4 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject little-finger "0.1.0-SNAPSHOT" 2 | :description "The server for Little Finger app" 3 | :url "http://avi.im/little-finger" 4 | :license {:name "MIT License" 5 | :url "https://v.mit-license.org/"} 6 | :dependencies [[org.clojure/clojure "1.8.0"] 7 | [ring/ring-core "1.6.1"] 8 | [ring/ring-jetty-adapter "1.6.1"] 9 | [compojure "1.6.0"] 10 | [org.clojure/data.json "0.2.6"] 11 | [environ "1.1.0"]] 12 | :min-lein-version "2.0.0" 13 | :uberjar-name "little-finger-standalone.jar" 14 | :profiles {:production {:env {:production true}}}) 15 | -------------------------------------------------------------------------------- /src/little_finger/web.clj: -------------------------------------------------------------------------------- 1 | (ns little-finger.web 2 | (:require [compojure.core :refer [defroutes GET PUT POST DELETE ANY]] 3 | [compojure.handler :refer [site]] 4 | [ring.adapter.jetty :as jetty] 5 | [clojure.data.json :as json] 6 | [environ.core :refer [env]])) 7 | 8 | (defn get-json-response [] 9 | (json/write-str {:NotificationTitle (env :notification-title) 10 | :NotificationText (env :notification-text)})) 11 | 12 | (defn index [] 13 | {:status 200 14 | :headers {"Content-Type" "text/plain"} 15 | :body "The Little Finger is up"}) 16 | 17 | (defn status-handler [] 18 | {:status (Integer. (env :response-status)) 19 | :headers {"Content-Type" "application/json"} 20 | :body (get-json-response)}) 21 | 22 | (defroutes app 23 | (GET "/" [] 24 | (index)) 25 | (GET "/status" [] 26 | (status-handler)) 27 | (ANY "*" [] 28 | {:status 404})) 29 | 30 | (defn -main [& [port]] 31 | (let [port (Integer. (or port (env :port) 5000))] 32 | (jetty/run-jetty (site #'app) {:port port :join? false}))) 33 | -------------------------------------------------------------------------------- /test/little_finger/core_test.clj: -------------------------------------------------------------------------------- 1 | (ns little-finger.core-test 2 | (:require [clojure.test :refer :all] 3 | [little-finger.core :refer :all])) 4 | 5 | (deftest a-test 6 | (testing "FIXME, I fail." 7 | (is (= 0 1)))) 8 | --------------------------------------------------------------------------------