Giter Site home page Giter Site logo

kiranandcode / ocamlot Goto Github PK

View Code? Open in Web Editor NEW
67.0 4.0 4.0 1.97 MB

An Activitypub server in OCaml!

Home Page: https://ocamlot.xyz

License: GNU Affero General Public License v3.0

OCaml 58.97% Roff 3.64% Shell 0.76% CSS 1.28% Raku 2.28% Perl 32.24% Elixir 0.20% Dockerfile 0.64%
activitypub dream ocaml social-media social-network

ocamlot's Introduction

OCamlot - An OCaml Activitypub Server

OCamlot is an activitypub server written in OCaml!

As with most non-mainstream activitypub servers, it's currently in very experimental status!

Features:

  • Creating posts
  • Replying to posts
  • Custom profiles
  • Liking posts (we call them toasts)
  • Reboosting posts (we call them cheers)
  • Replying to posts

Screenshot:

screenshot.png

You can see a running instance of the server at ocamlot.xyz!

Deploying OCamlot

The rest of this guide will be assuming that you have a server with OCaml installed, and nginx, setup with letsencrypt, such that an appropriate internal port is accessible via a public domain.

Your nginx config may look something like as follows (using PORT 7331 and DOMAIN ocamlot.xyz):

server {
    server_name ocamlot.xyz;

    listen 443 ssl; # managed by Certbot

    location / {
        proxy_pass http://localhost:7331;
    }
    ssl_certificate /etc/letsencrypt/live/ocamlot.xyz/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/ocamlot.xyz/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = ocamlot.xyz) {
        return 301 https://$host$request_uri;
   } # managed by Certbot

   listen 80 default_server;
   listen [::]:80 default_server;

   return 404; # managed by Certbot
}

To deploy the server, do the following:

  1. Create a new user to run the ocamlot process
$ sudo useradd -r -s /bin/false -m -d /var/lib/ocamlot -U ocamlot
  1. Create a new postgres user and database:
$ sudo -Hu postgres psql

postgres=# CREATE ROLE ocamlot WITH password = '<password>';
CREATE ROLE

postgres=# ALTER ROLE ocamlot WITH login;
ALTER ROLE

postgres=# CREATE DATABASE ocamlot WITH OWNER ocamlot;
CREATE DATABASE
  1. Clone the development repository:
$ sudo mkdir -p /opt/ocamlot
$ sudo chown -R ocamlot:ocamlot /opt/ocamlot
$ sudo -Hu ocamlot git clone https://codeberg.org/gopiandcode/ocamlot /opt/ocamlot
  1. Switch user to the ocamlot user:
$ sudo -Hu ocamlot bash
  1. Setup opam:
$ opam init

$ eval $(opam env)

$ opam update
  1. Install dev dependencies:
$ cd /var/lib/ocamlot

$ git clone https://github.com/gopiandcode/petrol

$ cd ./petrol

$ opam pin .
  1. Build the project
$ cd /opt/ocamlot

$ opam update && opam install --deps-only .

$ dune build
  1. Modify ./scripts/run.sh with domain and port:
# file: ./scripts/run.sh

#!/bin/bash
/opt/ocamlot/_build/default/bin/main.exe -u 'ocamlot:<password>@localhost:5432' -d "ocamlot.xyz" -p 7331 -D
  1. Create an account via the web UI, with username <username>

  2. Promote user <username> to admin

/opt/ocamlot/_build/default/bin/main.exe -u 'ocamlot:<password>@localhost:5432' -d "ocamlot.xyz" --promote-to-admin=<username>
  1. Copy over ./scripts/ocamlot.service to etc/systemd/system/ocamlot.service:
sudo cp /opt/ocamlot/scripts/ocamlot.service /etc/systemd/system/ocamlot.service
  1. Enable and start ocamlot.service:
sudo systemctl enable --now ocamlot.service

Development Setup

To develop OCamlot locally, we provide a docker-compose file for setting up a network with a running OCamlot (port 7331) and pleroma (port 4000) instance. The two containers are connected through a network in which the OCamlot server can be found under the domain name testing.ocamlot.xyz and the Pleroma server can be found under the domain name pleroma.ocamlot.xyz. (Note: because there is no easy way of updating the CA store that elixir uses, you will need to patch your local copy of pleroma to disable certification verification for interaction between the two containers to work).

You will need docker-compose and docker

  1. Clone a copy of pleroma to the tests/integration_test/ directory:
git clone -b  v2.5.0 --single-branch https://git.pleroma.social/pleroma/pleroma ./tests/integration_tests/pleroma
  1. Apply patch to pleroma to disable TLS validation (required for local testing)
(cd ./tests/integration_tests/pleroma && git apply ../pleroma.patch)
  1. Change directory into the tests/integration_test/ directory:
cd ./tests/integration_tests/
  1. Run docker-compose build with the local docker-compose file:
docker-compose -f ./docker-compose.local.yml build
  1. Run docker-compose up with the local docker-compose file:
docker-compose -f ./docker-compose.local.yml up

Now pleroma will be available at https://localhost:4000 and ocamlot at https://localhost:7331

  1. (optional), if you want to update the OCamlot server after making some changes locally, do the following:

    • 6.1. Find out the name of the OCamlot server container using docker container list
    • 6.2. Attach to the OCamlot container using docker container exec -it <container-id> bash
    • 6.3. Kill the running OCamlot process using pkill -9 main.exe
    • 6.4. Run eval $(opam env), then dune build then dune exec -- ./bin/main.exe -d testing.ocamlot.xyz -D

ocamlot's People

Contributors

kiranandcode avatar hannesm avatar mro avatar

Stargazers

 avatar Samuel Fadel avatar d0p1 avatar MarcC avatar  avatar Vladan Popovic avatar Andrejs Agejevs avatar Ryan Gibb avatar Guilherme avatar Nikita avatar Lucas Pluvinage avatar  avatar Andrés Ignacio Torres avatar Andrea Tupini avatar Tejas Sawant avatar Bozhidar Hristov avatar yuki avatar  avatar Hyeseong Kim avatar bronsen avatar Mohan Gowda avatar  avatar Brad Svercl avatar  avatar enterprisey avatar Yawar Amin avatar Tim ats avatar Virgile Robles avatar savi2w avatar Dmytro Kobza avatar Dejan Josifović avatar Brian Redfern avatar Nico Wagner avatar  avatar Dennis Dang avatar Calascibetta Romain avatar Zero avatar Allister Beharry avatar David.Gao avatar Glenn Y. Rolland avatar joseferben avatar X Caminhante avatar Joohun, Maeng avatar Tim McGilchrist avatar Dan Bruder avatar Daniel A. Matysiak avatar Ryan Murphy avatar Gonéri Le Bouder avatar Mike Linksvayer avatar  avatar Geoff deRosenroll avatar  avatar Paul Chobert avatar Jules Aguillon avatar Masanori Ogino avatar Ryotaro Banno avatar  avatar ejmg avatar Noel Kwan avatar Sora Morimoto avatar Thomas Gazagnaire avatar ᴍᴜǫɪᴜ ʜᴀɴ (韩暮秋) avatar Marcello Seri avatar Arsalan Cheema avatar Seb Mondet avatar Simon Cruanes avatar Xavier Van de Woestyne avatar

Watchers

 avatar  avatar  avatar  avatar

ocamlot's Issues

Contents of OrderedCollection should be a list of objects

Example courtesy of Adam Sjøgren via email:

Response from ocamlot from outbox:

      "orderedItems": [
        {
          "@context": [
            "https://www.w3.org/ns/activitystreams",
            "https://w3id.org/security/v1"
          ],
          "actor": "https://ocamlot.xyz/users/gopiandcode",
          "attachment": [
            {
              "mediaType": "image/gif",
              "name": "",
              "type": "Document",
              "url": "https://ocamlot.xyz/images/91eb9074-e08f-4deb-8588-be4b1c78e52d.gif"
            }
          ],
          "cc": [],
          "content": "Got the skeleton of an interaction system now working. As it turns out, sets in Rhombus are not the same as sets in Racket --- if you try to pass a Rhombus set to in-set, then you'll get a runtime crash. Ouch. Oh well, more hacks I guess.",
          "id": "https://ocamlot.xyz/activity/0f5de023-20f3-4319-b990-b5ab5d1ff54c",
          "published": "2023-05-07T15:08:13Z",
          "sensitive": false,
          "source": "Got the skeleton of an interaction system now working. As it turns out, sets in Rhombus are not the same as sets in Racket --- if you try to pass a Rhombus set to in-set, then you'll get a runtime crash. Ouch. Oh well, more hacks I guess.",
          "tags": [],
          "to": [],
          "type": "Note"
        },

whereas from pleroma:

   "orderedItems": [
      {
        "@context": [
          "https://www.w3.org/ns/activitystreams",
          "https://magnetic-ink.dk/schemas/litepub-0.1.jsonld",
          {
            "@language": "und"
          }
        ],
        "actor": "https://magnetic-ink.dk/users/kas",
        "cc": [
          "https://www.w3.org/ns/activitystreams#Public"
        ],
        "context": "https://magnetic-ink.dk/contexts/f021ce62-c5dd-4e79-8364-9ad19b45dc7d",
        "context_id": 35038,
        "directMessage": false,
        "id": "https://magnetic-ink.dk/activities/80818498-e244-4d45-a1c2-52363618845e",
        "object": {
          "actor": "https://magnetic-ink.dk/users/kas",
          "attachment": [],
          "attributedTo": "https://magnetic-ink.dk/users/kas",
          "cc": [
            "https://www.w3.org/ns/activitystreams#Public"
          ],
          "content": "<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"ATFK2cCxqACxzbo0wK\" href=\"https://mastodon.social/@selmins\" rel=\"ugc\">@<span>selmins</span></a></span> I don&#39;t think there is any community here in <a class=\"hashtag\" data-tag=\"denmark\" href=\"https://magnetic-ink.dk/tag/denmark\" rel=\"tag ugc\">#Denmark</a> either. Perhaps I can spend the accumulated <a class=\"hashtag\" data-tag=\"circlesubi\" href=\"https://magnetic-ink.dk/tag/circlesubi\" rel=\"tag ugc\">#circlesUBI</a> at the online market, it&#39;s been a while since I looked into it.",
          "context": "https://magnetic-ink.dk/contexts/f021ce62-c5dd-4e79-8364-9ad19b45dc7d",
          "conversation": "https://magnetic-ink.dk/contexts/f021ce62-c5dd-4e79-8364-9ad19b45dc7d",
          "id": "https://magnetic-ink.dk/objects/eb897a1c-861c-4c41-b7fc-3254ca59916c",
          "inReplyTo": "https://mastodon.social/users/selmins/statuses/110328079126407821",
          "published": "2023-05-07T15:47:48.228058Z",
          "sensitive": null,
          "source": "@[email protected] I don't think there is any community here in #Denmark either. Perhaps I can spend the accumulated #circlesUBI at the online market, it's been a while since I looked into it.",
          "summary": "",
          "tag": [
            {
              "href": "https://magnetic-ink.dk/tags/denmark",
              "name": "#denmark",
              "type": "Hashtag"
            },
            {
              "href": "https://magnetic-ink.dk/tags/circlesubi",
              "name": "#circlesubi",
              "type": "Hashtag"
            },
            {
              "href": "https://mastodon.social/users/selmins",
              "name": "@[email protected]",
              "type": "Mention"
            }
          ],
          "to": [
            "https://mastodon.social/users/selmins",
            "https://magnetic-ink.dk/users/kas/followers"
          ],
          "type": "Note"
        },
        "published": "2023-05-07T15:47:48.227965Z",
        "to": [
          "https://mastodon.social/users/selmins",
          "https://magnetic-ink.dk/users/kas/followers"
        ],
        "type": "Create"
      },

Separate salts per password

As pointed out to me by @hannesm, each password should have a randomly generated salt rather than hardcoding a single salt for the entire instance.

Compiling on macOS

First thanks for writing this project, I'm excited to have something like this written in OCaml and have a chance to hack on it. The blog post on https://gopiandcode.uk/logs/log-writing-activitypub.html was great.

I'm having issues with compiling this on macOS. The conan dependency fails with this error in an OCaml 4.14.1 sandbox. Have you encountered this issue? Is it possible to work around not having conan available?

$ opam install conan
The following actions will be performed:
  ∗ install conan 0.0.2

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><>  🐫 
⬇ retrieved conan.0.0.2  (cached)
[ERROR] The compilation of conan.0.0.2 failed at "dune install --create-install-files conan".

#=== ERROR while compiling conan.0.0.2 ========================================#
# context     2.1.4 | macos/x86_64 | ocaml-base-compiler.4.14.1 | https://opam.ocaml.org/#26770281
# path        ~/code/ocaml/ocamlot/_opam/.opam-switch/build/conan.0.0.2
# command     ~/.opam/opam-init/hooks/sandbox.sh build dune install --create-install-files conan
# exit-code   1
# env-file    ~/.opam/log/conan-14922-5c5eb5.env
# output-file ~/.opam/log/conan-14922-5c5eb5.out
### output ###
# Error: Unknown package conan!



<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><>  🐫 
┌─ The following actions failed
│ λ build conan 0.0.2
└─ 
╶─ No changes have been performed

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.