v_exchange
v_exchange copied to clipboard
A scalable web app features LiveView authentication, user roles and permission system, and secure S3/Wasabi uploads. It calculates file hashes with Erlang crypto library and uses Oban for all most API...
VExchange
Features
- LiveView Authentication
- User Role and Permission system
- Direct to S3/Wasabi upload with LiveView
- https://hexdocs.pm/phoenix_live_view/uploads-external.html
- Generates presigned urls for secure download
- Calculates file hashes with
:crypto.hash/2
- ~~Uploads to Triage on upload to Vx Underground via Oban Job Scheduler and notifies the user of completion with
Phoenix.Channels
.~~ - Checks for VT Report on load of the
Sample
show page. - Uses
libcluster
andfly_postgres
for scalability - Has CI/CD setup and is deployed on Fly.io.
- ~~Custom Discord Logger backend~~
- Upload, login and get sample API routes
Built With
- Postgres
- erlang
- Elixir
- Phoenix
- Phoenix LiveView
- NodeJS
- TailwindCSS
Getting Started
Prerequisites
-
Install
erlang
,Elixir
,NodeJS
,Postgres
- With homebrew the commands are:
brew update brew install erlang elixir nodejs postgres
- Or if you prefer
asdf
brew update brew install asdf asdf plugin-add erlang asdf plugin-add elixir asdf plugin-add nodejs asdf install
Installation
- Clone this Repo and enter the directory.
- Set up the project with the command
mix setup
- Set the following env variables in order to get Wasabi/S3 to work.
-
AWS_ACCESS_KEY_ID
-
AWS_SECRET_ACCESS_KEY
-
S3_BUCKET_NAME
-
- Set the following env variables in order to get Triage / VT to work.
-
VIRUS_TOTAL_API_KEY
-
TRIAGE_API_KEY
-
- Set the following env variables in order to get Discord Logging to work. (optional)
-
DISCORD_BOT_TOKEN
-
DISCORD_CHANNEL_ID
-
- Start Phoenix server with
iex -S mix phx.server
- Now you can visit
localhost:4000
orlocalhost:4001
from your browser.
- Now you can visit
- Once you register a user, you make it admin by running this in the same window you ran
iex -S mix phx.server
in (yes we run commands in a running server)-
VExchange.Accounts.get_user!(1) |> VExchange.Accounts.add_role_to_user("Admin")
-
You can run unit tests with the command
mix test
API Routes
Documentation can be found at here and requires an API key generated when a user signs up.
Example script using the upload API to upload all files from a sub directory.
import requests, os, sys
from concurrent.futures import ThreadPoolExecutor
MAX_WORKERS = 10
API_LOGIN = "https://virus.exchange/api/login"
API_UPLOAD = "https://virus.exchange/api/upload"
TOKEN=""
EMAIL="ur email"
if TOKEN == "":
PASSWORD=input("Enter your password: ")
r = requests.post(API_LOGIN, data={"email":EMAIL, "password":PASSWORD})
TOKEN = r.json()["data"]["token"]
def process_file(subdir, file):
filename = os.path.join(subdir, file)
with open(filename, "rb+") as f:
file_content = f.read()
r = requests.post(API_UPLOAD, headers={'Authorization': f"Bearer {TOKEN}", "Content-Type": "application/x-www-form-urlencoded"}, data=file_content)
print(f"{os.path.basename(filename)}: STATUS({r.status_code}) {r.text}")
def main(directory):
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
for subdir, dirs, files in os.walk(directory):
for file in files:
executor.submit(process_file, subdir, file)
if __name__ == '__main__':
main(sys.argv[1])
TODO
- Setup Minio for Dev upload / download
- Better file types
- YARA Tags
Database architecture 🗂
classDiagram
class Sample{
+Integer size
+String md5
+String sha1
+String sha256
+String sha512
+String s3_object_key
+Array names
+Array tags
+DateTime first_seen
}
class Users {
+String email
+String username
+String password
+Integer role_id
+String hashed_password
+DateTime confirmed_at
}
class Role {
+String name
+Jsonb permissions
}