diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 1b397b3..0000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM mcr.microsoft.com/devcontainers/go:1-1.21-bullseye - -# [Optional] Uncomment this section to install additional OS packages. -RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ - && apt-get -y install --no-install-recommends postgresql-client - -# [Optional] Uncomment the next lines to use go get to install anything else you need -# USER vscode -# RUN go get -x -# USER root - -# [Optional] Uncomment this line to install global node packages. -# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 816ba3c..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,23 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/go-postgres -{ - "name": "Go & PostgreSQL", - "dockerComposeFile": "docker-compose.yml", - "service": "app", - "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}" - - // Features to add to the dev container. More info: https://containers.dev/features. - // "features": {}, - - // Configure tool-specific properties. - // "customizations": {}, - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [5432], - - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "go version", - - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" -} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml deleted file mode 100644 index 071a939..0000000 --- a/.devcontainer/docker-compose.yml +++ /dev/null @@ -1,38 +0,0 @@ -version: '3.8' - -volumes: - postgres-data: - -services: - app: - build: - context: . - dockerfile: Dockerfile - env_file: - # Ensure that the variables in .env match the same variables in devcontainer.json - - .env - - volumes: - - ../..:/workspaces:cached - - # Overrides default command so things don't shut down after the process ends. - command: sleep infinity - - # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function. - network_mode: service:db - - # Use "forwardPorts" in **devcontainer.json** to forward an app port locally. - # (Adding the "ports" property to this file will not forward from a Codespace.) - - db: - image: postgres:latest - restart: unless-stopped - volumes: - - postgres-data:/var/lib/postgresql/data - env_file: - # Ensure that the variables in .env match the same variables in devcontainer.json - - .env - - - # Add "forwardPorts": ["5432"] to **devcontainer.json** to forward PostgreSQL locally. - # (Adding the "ports" property to this file will not forward from a Codespace.) diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 2142c36..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "licenser.projectName": "Linstrom", - "licenser.customTermsAndConditions": " EUROPEAN UNION PUBLIC LICENCE v. 1.2\n EUPL © the European Union 2007, 2016\n\nThis European Union Public Licence (the ‘EUPL’) applies to the Work (as defined\nbelow) which is provided under the terms of this Licence. Any use of the Work,\nother than as authorised under this Licence is prohibited (to the extent such\nuse is covered by a right of the copyright holder of the Work).\n\nThe Work is provided under the terms of this Licence when the Licensor (as\ndefined below) has placed the following notice immediately following the\ncopyright notice for the Work:\n\n Licensed under the EUPL\n\nor has expressed by any other means his willingness to license under the EUPL.\n\n1. Definitions\n\nIn this Licence, the following terms have the following meaning:\n\n- ‘The Licence’: this Licence.\n\n- ‘The Original Work’: the work or software distributed or communicated by the\n Licensor under this Licence, available as Source Code and also as Executable\n Code as the case may be.\n\n- ‘Derivative Works’: the works or software that could be created by the\n Licensee, based upon the Original Work or modifications thereof. This Licence\n does not define the extent of modification or dependence on the Original Work\n required in order to classify a work as a Derivative Work; this extent is\n determined by copyright law applicable in the country mentioned in Article 15.\n\n- ‘The Work’: the Original Work or its Derivative Works.\n\n- ‘The Source Code’: the human-readable form of the Work which is the most\n convenient for people to study and modify.\n\n- ‘The Executable Code’: any code which has generally been compiled and which is\n meant to be interpreted by a computer as a program.\n\n- ‘The Licensor’: the natural or legal person that distributes or communicates\n the Work under the Licence.\n\n- ‘Contributor(s)’: any natural or legal person who modifies the Work under the\n Licence, or otherwise contributes to the creation of a Derivative Work.\n\n- ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of\n the Work under the terms of the Licence.\n\n- ‘Distribution’ or ‘Communication’: any act of selling, giving, lending,\n renting, distributing, communicating, transmitting, or otherwise making\n available, online or offline, copies of the Work or providing access to its\n essential functionalities at the disposal of any other natural or legal\n person.\n\n2. Scope of the rights granted by the Licence\n\nThe Licensor hereby grants You a worldwide, royalty-free, non-exclusive,\nsublicensable licence to do the following, for the duration of copyright vested\nin the Original Work:\n\n- use the Work in any circumstance and for all usage,\n- reproduce the Work,\n- modify the Work, and make Derivative Works based upon the Work,\n- communicate to the public, including the right to make available or display\n the Work or copies thereof to the public and perform publicly, as the case may\n be, the Work,\n- distribute the Work or copies thereof,\n- lend and rent the Work or copies thereof,\n- sublicense rights in the Work or copies thereof.\n\nThose rights can be exercised on any media, supports and formats, whether now\nknown or later invented, as far as the applicable law permits so.\n\nIn the countries where moral rights apply, the Licensor waives his right to\nexercise his moral right to the extent allowed by law in order to make effective\nthe licence of the economic rights here above listed.\n\nThe Licensor grants to the Licensee royalty-free, non-exclusive usage rights to\nany patents held by the Licensor, to the extent necessary to make use of the\nrights granted on the Work under this Licence.\n\n3. Communication of the Source Code\n\nThe Licensor may provide the Work either in its Source Code form, or as\nExecutable Code. If the Work is provided as Executable Code, the Licensor\nprovides in addition a machine-readable copy of the Source Code of the Work\nalong with each copy of the Work that the Licensor distributes or indicates, in\na notice following the copyright notice attached to the Work, a repository where\nthe Source Code is easily and freely accessible for as long as the Licensor\ncontinues to distribute or communicate the Work.\n\n4. Limitations on copyright\n\nNothing in this Licence is intended to deprive the Licensee of the benefits from\nany exception or limitation to the exclusive rights of the rights owners in the\nWork, of the exhaustion of those rights or of other applicable limitations\nthereto.\n\n5. Obligations of the Licensee\n\nThe grant of the rights mentioned above is subject to some restrictions and\nobligations imposed on the Licensee. Those obligations are the following:\n\nAttribution right: The Licensee shall keep intact all copyright, patent or\ntrademarks notices and all notices that refer to the Licence and to the\ndisclaimer of warranties. The Licensee must include a copy of such notices and a\ncopy of the Licence with every copy of the Work he/she distributes or\ncommunicates. The Licensee must cause any Derivative Work to carry prominent\nnotices stating that the Work has been modified and the date of modification.\n\nCopyleft clause: If the Licensee distributes or communicates copies of the\nOriginal Works or Derivative Works, this Distribution or Communication will be\ndone under the terms of this Licence or of a later version of this Licence\nunless the Original Work is expressly distributed only under this version of the\nLicence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee\n(becoming Licensor) cannot offer or impose any additional terms or conditions on\nthe Work or Derivative Work that alter or restrict the terms of the Licence.\n\nCompatibility clause: If the Licensee Distributes or Communicates Derivative\nWorks or copies thereof based upon both the Work and another work licensed under\na Compatible Licence, this Distribution or Communication can be done under the\nterms of this Compatible Licence. For the sake of this clause, ‘Compatible\nLicence’ refers to the licences listed in the appendix attached to this Licence.\nShould the Licensee's obligations under the Compatible Licence conflict with\nhis/her obligations under this Licence, the obligations of the Compatible\nLicence shall prevail.\n\nProvision of Source Code: When distributing or communicating copies of the Work,\nthe Licensee will provide a machine-readable copy of the Source Code or indicate\na repository where this Source will be easily and freely available for as long\nas the Licensee continues to distribute or communicate the Work.\n\nLegal Protection: This Licence does not grant permission to use the trade names,\ntrademarks, service marks, or names of the Licensor, except as required for\nreasonable and customary use in describing the origin of the Work and\nreproducing the content of the copyright notice.\n\n6. Chain of Authorship\n\nThe original Licensor warrants that the copyright in the Original Work granted\nhereunder is owned by him/her or licensed to him/her and that he/she has the\npower and authority to grant the Licence.\n\nEach Contributor warrants that the copyright in the modifications he/she brings\nto the Work are owned by him/her or licensed to him/her and that he/she has the\npower and authority to grant the Licence.\n\nEach time You accept the Licence, the original Licensor and subsequent\nContributors grant You a licence to their contributions to the Work, under the\nterms of this Licence.\n\n7. Disclaimer of Warranty\n\nThe Work is a work in progress, which is continuously improved by numerous\nContributors. It is not a finished work and may therefore contain defects or\n‘bugs’ inherent to this type of development.\n\nFor the above reason, the Work is provided under the Licence on an ‘as is’ basis\nand without warranties of any kind concerning the Work, including without\nlimitation merchantability, fitness for a particular purpose, absence of defects\nor errors, accuracy, non-infringement of intellectual property rights other than\ncopyright as stated in Article 6 of this Licence.\n\nThis disclaimer of warranty is an essential part of the Licence and a condition\nfor the grant of any rights to the Work.\n\n8. Disclaimer of Liability\n\nExcept in the cases of wilful misconduct or damages directly caused to natural\npersons, the Licensor will in no event be liable for any direct or indirect,\nmaterial or moral, damages of any kind, arising out of the Licence or of the use\nof the Work, including without limitation, damages for loss of goodwill, work\nstoppage, computer failure or malfunction, loss of data or any commercial\ndamage, even if the Licensor has been advised of the possibility of such damage.\nHowever, the Licensor will be liable under statutory product liability laws as\nfar such laws apply to the Work.\n\n9. Additional agreements\n\nWhile distributing the Work, You may choose to conclude an additional agreement,\ndefining obligations or services consistent with this Licence. However, if\naccepting obligations, You may act only on your own behalf and on your sole\nresponsibility, not on behalf of the original Licensor or any other Contributor,\nand only if You agree to indemnify, defend, and hold each Contributor harmless\nfor any liability incurred by, or claims asserted against such Contributor by\nthe fact You have accepted any warranty or additional liability.\n\n10. Acceptance of the Licence\n\nThe provisions of this Licence can be accepted by clicking on an icon ‘I agree’\nplaced under the bottom of a window displaying the text of this Licence or by\naffirming consent in any other similar way, in accordance with the rules of\napplicable law. Clicking on that icon indicates your clear and irrevocable\nacceptance of this Licence and all of its terms and conditions.\n\nSimilarly, you irrevocably accept this Licence and all of its terms and\nconditions by exercising any rights granted to You by Article 2 of this Licence,\nsuch as the use of the Work, the creation by You of a Derivative Work or the\nDistribution or Communication by You of the Work or copies thereof.\n\n11. Information to the public\n\nIn case of any Distribution or Communication of the Work by means of electronic\ncommunication by You (for example, by offering to download the Work from a\nremote location) the distribution channel or media (for example, a website) must\nat least provide to the public the information requested by the applicable law\nregarding the Licensor, the Licence and the way it may be accessible, concluded,\nstored and reproduced by the Licensee.\n\n12. Termination of the Licence\n\nThe Licence and the rights granted hereunder will terminate automatically upon\nany breach by the Licensee of the terms of the Licence.\n\nSuch a termination will not terminate the licences of any person who has\nreceived the Work from the Licensee under the Licence, provided such persons\nremain in full compliance with the Licence.\n\n13. Miscellaneous\n\nWithout prejudice of Article 9 above, the Licence represents the complete\nagreement between the Parties as to the Work.\n\nIf any provision of the Licence is invalid or unenforceable under applicable\nlaw, this will not affect the validity or enforceability of the Licence as a\nwhole. Such provision will be construed or reformed so as necessary to make it\nvalid and enforceable.\n\nThe European Commission may publish other linguistic versions or new versions of\nthis Licence or updated versions of the Appendix, so far this is required and\nreasonable, without reducing the scope of the rights granted by the Licence. New\nversions of the Licence will be published with a unique version number.\n\nAll linguistic versions of this Licence, approved by the European Commission,\nhave identical value. Parties can take advantage of the linguistic version of\ntheir choice.\n\n14. Jurisdiction\n\nWithout prejudice to specific agreement between parties,\n\n- any litigation resulting from the interpretation of this License, arising\n between the European Union institutions, bodies, offices or agencies, as a\n Licensor, and any Licensee, will be subject to the jurisdiction of the Court\n of Justice of the European Union, as laid down in article 272 of the Treaty on\n the Functioning of the European Union,\n\n- any litigation arising between other parties and resulting from the\n interpretation of this License, will be subject to the exclusive jurisdiction\n of the competent court where the Licensor resides or conducts its primary\n business.\n\n15. Applicable Law\n\nWithout prejudice to specific agreement between parties,\n\n- this Licence shall be governed by the law of the European Union Member State\n where the Licensor has his seat, resides or has his registered office,\n\n- this licence shall be governed by Belgian law if the Licensor has no seat,\n residence or registered office inside a European Union Member State.\n\nAppendix\n\n‘Compatible Licences’ according to Article 5 EUPL are:\n\n- GNU General Public License (GPL) v. 2, v. 3\n- GNU Affero General Public License (AGPL) v. 3\n- Open Software License (OSL) v. 2.1, v. 3.0\n- Eclipse Public License (EPL) v. 1.0\n- CeCILL v. 2.0, v. 2.1\n- Mozilla Public Licence (MPL) v. 2\n- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3\n- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for\n works other than software\n- European Union Public Licence (EUPL) v. 1.1, v. 1.2\n- Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong\n Reciprocity (LiLiQ-R+).\n\nThe European Commission may update this Appendix to later versions of the above\nlicences without producing a new version of the EUPL, as long as they provide\nthe rights granted in Article 2 of this Licence and protect the covered Source\nCode from exclusive appropriation.\n\nAll other changes or additions to this Appendix require the production of a new\nEUPL version.\n", - "licenser.customHeader": "Copyright (c) @YEAR@ @AUTHOR@\\n\\nLicensed under the EUPL, Version 1.2\\n\\nYou may not use this work except in compliance with the Licence.\\nYou should have received a copy of the Licence along with this work. If not, see:\\n.\\nSee the Licence for the specific language governing permissions and limitations under the Licence.", - "licenser.customSPDXId": "EUPL-1.2", -} \ No newline at end of file diff --git a/FeatureTargets.md b/FeatureTargets.md deleted file mode 100644 index 12dc341..0000000 --- a/FeatureTargets.md +++ /dev/null @@ -1,25 +0,0 @@ -# Feature targets - -## UI - -- Firefish like -- htmx - -## Features - -### QoL - -- [ ] Reactions -- [ ] Qoute tweets -- [ ] misskey/firefish markdown - -### Moderation - -- [ ] Authorized Fetch -- [ ] Lockdown (user/server) (block/ignore any incoming messages) -- [ ] Filter-based (maybe regex) auto-block/refuse follow requests - -### General - -- [ ] Masto, MK/FF, Akoma/Plemora API -- [ ] is_cat diff --git a/README.md b/README.md deleted file mode 100644 index 4032898..0000000 --- a/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Linstrom -An ActivityPub enabled social media server - -## Goals -- A server for interacting with other ActivityPub enabled servers, also known as the fediverse -- Provide powerful, yet easy to use moderation tools for both admins and users to support the effort of keeping the users safe - -## Todos -Todos can be found on [https://planka.evilthings.de]. Since Planka has no anonymous access as far as I can tell, there's an account for readonly access. - -Details: -- Username: `public` -- Password: `Public user` \ No newline at end of file diff --git a/ap/accept-action.go b/ap/accept-action.go deleted file mode 100644 index 7132a49..0000000 --- a/ap/accept-action.go +++ /dev/null @@ -1,12 +0,0 @@ -package ap - -import "net/url" - -// Sent when a follow request is approved, manually or automatically -type AcceptAction struct { - Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object - Id url.URL `json:"id"` // Url to this action - Type string `json:"type"` // Should always be "Accept" - Actor url.URL `json:"actor"` // Who is accepting what - Object FollowAction `json:"object"` // Action that is being accepted -} diff --git a/ap/announce-action.go b/ap/announce-action.go deleted file mode 100644 index adb1751..0000000 --- a/ap/announce-action.go +++ /dev/null @@ -1,14 +0,0 @@ -package ap - -import "net/url" - -// Announce == boost/share/retweet -type AnnounceAction struct { - Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object - Id url.URL `json:"id"` // Url to this action - Type string `json:"type"` // Should always be "Announce" - Actor url.URL `json:"actor"` // Who is announcing something - To []url.URL `json:"to"` // Targets to share to - Cc []url.URL `json:"cc"` // More targets to send to - Object any `json:"object"` // Url to announced object. Url or embedded object, usually a note or survey -} diff --git a/ap/attachment.go b/ap/attachment.go deleted file mode 100644 index eca2a2a..0000000 --- a/ap/attachment.go +++ /dev/null @@ -1,8 +0,0 @@ -package ap - -// An info field on an account page -type PersonInfoField struct { - Type string `json:"type"` // Type of the attachment. Probably should always be "PropertyValue" - Name string `json:"name"` // Name of the property. Example: Source - Value string `json:"value"` // Value of the property. Link or html or just some text. Example: https://gitlab.com/mstarongitlab/Linstrom -} diff --git a/ap/create-action.go b/ap/create-action.go deleted file mode 100644 index 36f1730..0000000 --- a/ap/create-action.go +++ /dev/null @@ -1,19 +0,0 @@ -package ap - -import ( - "net/url" - "time" -) - -// Sent when posting something -type CreateAction struct { - Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object - ID url.URL `json:"id"` // URL to this resource - Actor url.URL `json:"actor"` // Account that created this action, links to the AP url - Type string `json:"type"` // Should always be "Create" - Published time.Time `json:"published"` // When this action was created - Object any `json:"object"` // Content of the action, is an AP object, like notes or questions (survey) - To []url.URL `json:"to"` // Array of url targets to deliver it to. With dms, oonly includes target accounts. Followers only goes to followers url of posting account - Cc []url.URL `json:"cc"` // More targets to deliver to? - Signature Signature `json:"signature"` // Signature of the message -} diff --git a/ap/delete-action.go b/ap/delete-action.go deleted file mode 100644 index c249d65..0000000 --- a/ap/delete-action.go +++ /dev/null @@ -1,15 +0,0 @@ -package ap - -import ( - "net/url" -) - -// When a message is deleted -type DeleteAction struct { - Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object - Id url.URL `json:"id"` // Location of this resource - Type string `json:"type"` // Should always be "Delete" - Actor url.URL `json:"actor"` // Account deleting something - Target any `json:"object"` // What is being deleted, url or some object - Signature any `json:"signature"` // Probably useless -} diff --git a/ap/emote.go b/ap/emote.go deleted file mode 100644 index d261cb1..0000000 --- a/ap/emote.go +++ /dev/null @@ -1,15 +0,0 @@ -package ap - -import ( - "net/url" - "time" -) - -// Custom emote information -type Emote struct { - Icon Media `json:"icon"` // Emote source file - ID url.URL `json:"id"` // Url of the image - Name string `json:"name"` // Name of the emote, example: ":neocat_heart:" - Type string `json:"type"` // Should always be "Emoji" - Updated time.Time `json:"updated"` // When this was last updated. Akkoma seems to set this to unix epoch -} diff --git a/ap/follow-action.go b/ap/follow-action.go deleted file mode 100644 index f517a84..0000000 --- a/ap/follow-action.go +++ /dev/null @@ -1,12 +0,0 @@ -package ap - -import "net/url" - -// A follow request -type FollowAction struct { - Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object - Id url.URL `json:"id"` // Location of this resource - Type string `json:"type"` // Should always be "Follow" - Actor url.URL `json:"actor"` // Account instanciating the follow request - Target url.URL `json:"object"` // Account that the actor wants to follow -} diff --git a/ap/like-action.go b/ap/like-action.go deleted file mode 100644 index d8e3b51..0000000 --- a/ap/like-action.go +++ /dev/null @@ -1,17 +0,0 @@ -package ap - -import "net/url" - -// Action to like a post -type LikeAction struct { - Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object - Id url.URL `json:"id"` // Url to this action - Type string `json:"type"` // Should always be "Like" - Actor url.URL `json:"actor"` // Who is liking something - Object url.URL `json:"object"` // What is being liked - - // Reaction data Misskey style - Content *string `json:"content,omitempty"` // Raw emote name - MkReaction *string `json:"_misskey_reaction,omitempty"` // Misskey version of content - Tag []Emote `json:"tag,omitempty"` // Emote in use -} diff --git a/ap/media.go b/ap/media.go deleted file mode 100644 index 30532ed..0000000 --- a/ap/media.go +++ /dev/null @@ -1,10 +0,0 @@ -package ap - -import "net/url" - -// Media content (video files, images, audio) -type Media struct { - Type string `json:"type"` // Should probably always be "Image", "Video" or similar. Dunno if "Video" is correct - MediaType *string `json:"mediaType,omitempty"` // What media type the linked resource is. Something like "image/png" - Url url.URL `json:"url"` // Where to find the media file -} diff --git a/ap/mention.go b/ap/mention.go deleted file mode 100644 index 92aae0c..0000000 --- a/ap/mention.go +++ /dev/null @@ -1,10 +0,0 @@ -package ap - -import "net/url" - -// Tag type for mentions -type Mention struct { - Type string `json:"type"` // Should always be "Mention" - Href url.URL `json:"href"` // Url to mentioned account - Name string `json:"name"` // Name of the account ("@foo@example.com") -} diff --git a/ap/note-object.go b/ap/note-object.go deleted file mode 100644 index 7e7a384..0000000 --- a/ap/note-object.go +++ /dev/null @@ -1,30 +0,0 @@ -package ap - -import ( - "net/url" - "time" -) - -// A post -type Note struct { - Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if note is embedded as object in another object - ID url.URL `json:"id"` // Url to this resource - Type string `json:"type"` // Should always be "Note" - AttributedTo url.URL `json:"attributedTo"` // Author of this note - Content string `json:"content"` // Content of this note - Source *RawNoteContent `json:"source"` // Raw content - InReplyTo *url.URL `json:"inReplyTo,omitempty"` // Note this is a reply to. Empty if not a reply - Attachment []map[string]string `json:"attachment"` // Media attachments - TODO: Make proper type for this - Tag []any `json:"tag"` // List of hashtags, mentions & custom emotes - Published time.Time `json:"published"` // When this note was created - To []url.URL `json:"to"` // Where this note should get sent to - Cc []url.URL `json:"cc"` // More where this note should get sent to - - Summary *string `json:"summary"` // Summary of a post (also known as content warning) - Sensitive bool `json:"sensitive"` // Does this note have a content warning? - - MkContent *string `json:"_misskey_content,omitempty"` // Misskey version of content - MkQuote *url.URL `json:"_misskey_quote,omitempty"` // Misskey link to note this quotes - QuoteUrl *url.URL `json:"quoteUrl,omitempty"` // Link to quoted note object - QuoteUri *url.URL `json:"quoteUri,omitempty"` // Same as Quote Url? -} diff --git a/ap/ordered-collection.go b/ap/ordered-collection.go deleted file mode 100644 index 4fbcdb6..0000000 --- a/ap/ordered-collection.go +++ /dev/null @@ -1,25 +0,0 @@ -package ap - -import "net/url" - -// Ordered collection of things (paged) -type OrderedCollection struct { - Context map[string]any `json:"@context"` // Big chunk of hopefully don't give a fuck - ID url.URL `json:"id"` // URL to this resource - Type string `json:"type"` // Should always be "OrderedCollection" - TotalItems *int `json:"totalItems,omitempty"` // Number of resources in this collection, Akoma doesn't include this - First url.URL `json:"first"` // Link to the first resource in this collection, an OrderedCollectionPage object - Last url.URL `json:"last"` // Link to the last resource in this collection, an OrderedCollectionPage object -} - -// One page of an ordered collection -type OrderedCollectionPage struct { - Context map[string]any `json:"@context"` // Big chunk of hopefully don't give a fuck - ID url.URL `json:"id"` // URL to this resource - PartOf url.URL `json:"partOf"` // URL to the collection this is a part of - Type string `json:"type"` // Should always be "OrderedCollectionPage" - TotalItems *int `json:"totalItems,omitempty"` // Number of resources in this collection. Mk yes, Masto no, Akoma no - OrderedItems []map[string]any `json:"orderedItems"` // Items in this list. Should all be AP objects/actions - Previous *url.URL `json:"prev"` // Previous page, empty if no items? I think? - Next *url.URL `json:"next"` // Next page -} diff --git a/ap/person.go b/ap/person.go deleted file mode 100644 index 37b0114..0000000 --- a/ap/person.go +++ /dev/null @@ -1,51 +0,0 @@ -package ap - -import ( - "net/url" - "time" -) - -// An account -type Person struct { - Context map[string]any `json:"@context"` // Big chunk of hopefully don't give a fuck - ID url.URL `json:"id"` // URL to this resource - Type string `json:"type"` // Should always be of content "Person" (or "Service", if a bot) - Following url.URL `json:"following"` // Ordered collection of accounts this account follows - Followers url.URL `json:"followers"` // Ordered collection of accounts following this account - Inbox url.URL `json:"inbox"` // Where others send activities to (posts, follow requests, reactions, etc) - Outbox url.URL `json:"outbox"` // Where others can read this account's activities from - Featured url.URL `json:"featured"` // Ordered collection of something featured - TODO: Find out what this is - PreferredUsername string `json:"preferredUsername"` // Username - Name string `json:"name"` // Vanity name - Summary string `json:"summary"` // Description of the account. Could contain html or maybe mfm for *key - Url url.URL `json:"url"` // Public location of the account - ManualApproval bool `json:"manuallyApprovesFollowers"` // Does this account have to approve of follows before they are actual follows? - Discoverable bool `json:"discoverable"` // If this account can be found via search things? I guess? - PublicKey PublicKey `json:"publicKey"` // public key of that account. For verifying that that account is actually them - Tag []Emote `json:"tag"` // Contains custom emote info - TODO: Add proper type - Attachment PersonInfoField `json:"attachment"` // Additional profile information (fields below the description, like "Source: https://gitlab.com/mstarongitlab/linstrom") - Endpoints map[string]string `json:"endpoints"` // Stores at least the shared inbox of the server this account is on in "sharedInbox", which is an url - Icon *Media `json:"icon"` // Profile image of the account, null if not set - Image *Media `json:"image"` // Header image of the account, null if not set - - // Section: Mastodon only - Indexable *bool `json:"indexable,omitempty"` // Probably if this account will be shown to search engines and crawlers? - FeaturedTags *url.URL `json:"featuredTags,omitempty"` // Collection of something, not ordered - TODO: Find out what this is - Published *time.Time `json:"published,omitempty"` // When this account was created I guess? - Memorial *bool `json:"memorial,omitempty"` // If this account is closed? Or moved? Probably closed - Devices *url.URL `json:"devices,omitempty"` // Collection of something - TODO: Find out what this is - - // Section: Misskey only - SharedInbox *url.URL `json:"sharedInbox,omitempty"` // Replicates the shared inbox url here I guess - MkSummary *string `json:"_misskey_summary,omitempty"` // Misskey's version of the summary - Background *url.URL `json:"backgroundUrl,omitempty"` // Background image - IsCat *bool `json:"isCat,omitempty"` // Is the user a cat (apply cat ears in that case) - NoIndex *bool `json:"noindex,omitempty"` // probably the same as Indexable, just reversed? - SpeakAsCat *bool `json:"speakAsCat,omitempty"` // Does the account speak like a cat - Birthday *string `json:"vcard:bday,omitempty"` // Birthday date, but doesn't quite follow normalised datetime - Location *string `json:"vcard:Address,omitempty"` // Where the user of the account lives, could technically be anything as just a string - - // Section: Akkoma things - AlsoKnownAs *[]any `json:"alsoKnownAs"` // Meaning unknown - Capabilities *map[string]any `json:"capabilities"` // Meaning unknown -} diff --git a/ap/public_key.go b/ap/public_key.go deleted file mode 100644 index 22f3c4d..0000000 --- a/ap/public_key.go +++ /dev/null @@ -1,22 +0,0 @@ -package ap - -import "net/url" - -// The public key associated with an account -type PublicKey struct { - ID url.URL `json:"id"` // ID of the key - Owner url.URL `json:"owner"` // Who this key belongs to - Content string `json:"publicKeyPem"` // Actual content of the key, example below -} - -/* - -Example for a public key - -""" ------BEGIN PUBLIC KEY----- -Big blob of random characters ------END PUBLIC KEY----- - -""" -*/ diff --git a/ap/question-entry.go b/ap/question-entry.go deleted file mode 100644 index 603a3db..0000000 --- a/ap/question-entry.go +++ /dev/null @@ -1,11 +0,0 @@ -package ap - -// One option for a survey -type QuestionEntry struct { - Type string `json:"type"` // Should always be "Note" - Name string `json:"name"` // Name of the entry - Replies struct { - Type string `json:"type"` // Should always be "Collection" - TotalItems int // Nr of people that selected this - } `json:"replies"` // Nr of people that selected this option -} diff --git a/ap/question-object.go b/ap/question-object.go deleted file mode 100644 index d9090fd..0000000 --- a/ap/question-object.go +++ /dev/null @@ -1,28 +0,0 @@ -package ap - -import ( - "net/url" - "time" -) - -// A survey. Options are in the field OneOf if it's single choice, AnyOf if multipleChoice -type Question struct { - Context map[string]any `json:"@context,omitempty"` // Lots of something. Not included if note is embedded as object in another object - ID url.URL `json:"id"` // Url to this object - Type string `json:"type"` // Should always be "Question" - AttributedTo url.URL `json:"attributedTo"` // Creator of this object - Content string `json:"content"` // Preformated text content - MkContent string `json:"_misskey_content"` // Misskey version of the content - Source RawNoteContent `json:"source"` // Raw version of the content - Published time.Time `json:"published"` // When this object was published - To []url.URL `json:"to"` // Who to send this to - Cc []url.URL `json:"cc"` // More targets to send to - InReplyTo *url.URL `json:"inReplyTo"` // Object this post replies to - Attachment []map[string]string `json:"attachment"` // File attachments - TODO: Move to concrete type - Sensitive bool `json:"sensitive"` // Whether this post has a content warning - Summary *string `json:"summary"` // Summary of a post (also known as content warning) - Tag []Hashtag `json:"tag"` // Hashtags - EndTime *time.Time `json:"endTime"` // Timestamp of when the question ends - OneOf []QuestionEntry `json:"oneOf,omitempty"` // All available options to vote for. Used if single choice vote - AnyOf []QuestionEntry `json:"anyOf,omitempty"` // All available options to vote for. Used if multiple choice vote -} diff --git a/ap/raw-note-content.go b/ap/raw-note-content.go deleted file mode 100644 index 39a025c..0000000 --- a/ap/raw-note-content.go +++ /dev/null @@ -1,7 +0,0 @@ -package ap - -// Raw content of a note I think. Added by Misskey and Akkoma -type RawNoteContent struct { - Content string `json:"content"` - MediaType string `json:"mediaType"` -} diff --git a/ap/reject-action.go b/ap/reject-action.go deleted file mode 100644 index 144e38f..0000000 --- a/ap/reject-action.go +++ /dev/null @@ -1,12 +0,0 @@ -package ap - -import "net/url" - -// Follow request rejected (or maybe I think "confirmation" on unfollow) -type RejectAction struct { - Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object - Id url.URL `json:"id"` // Location of this resource - Type string `json:"type"` // Should always be "Reject" - Actor url.URL `json:"actor"` // Account rejecting the follow request - Request FollowAction `json:"object"` // Request that's being rejected -} diff --git a/ap/signature.go b/ap/signature.go deleted file mode 100644 index de4b821..0000000 --- a/ap/signature.go +++ /dev/null @@ -1,13 +0,0 @@ -package ap - -import ( - "net/url" - "time" -) - -type Signature struct { - Created time.Time `json:"created"` // When this signature was created - Creator url.URL `json:"creator"` // What key was used to create it - Value string `json:"signatureValue"` // The signature itself - Type string `json:"type"` // What algorithm was used -} diff --git a/ap/tag.go b/ap/tag.go deleted file mode 100644 index 773c720..0000000 --- a/ap/tag.go +++ /dev/null @@ -1,10 +0,0 @@ -package ap - -import "net/url" - -// Describes a hashtag's data -type Hashtag struct { - Type string `json:"type"` // Should always be "Hashtag" - Href url.URL `json:"href"` // Url to that hashtag - Name string `json:"name"` // Name of the hashtag, example: "#some-hashtag" -} diff --git a/ap/tombstone-object.go b/ap/tombstone-object.go deleted file mode 100644 index 3a06bc4..0000000 --- a/ap/tombstone-object.go +++ /dev/null @@ -1,10 +0,0 @@ -package ap - -import "net/url" - -// The tombstone of a message -type Tombstone struct { - Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object - Id url.URL `json:"id"` // Location of this resource - Type string `json:"type"` // Should always be "Tombstone" -} diff --git a/ap/undo-action.go b/ap/undo-action.go deleted file mode 100644 index 544509b..0000000 --- a/ap/undo-action.go +++ /dev/null @@ -1,12 +0,0 @@ -package ap - -import "net/url" - -// Undoes one action -type UndoAction struct { - Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object - Id url.URL `json:"id"` // Location of this resource - Type string `json:"type"` // Should always be "Undo" - Actor url.URL `json:"actor"` // Account instanciating the follow request - Target any `json:"object"` // Action to undo, usually a like or follow -} diff --git a/config.toml b/config.toml deleted file mode 100644 index 10b0f55..0000000 --- a/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -[General] -database_path="postgres://postgres:postgres@localhost/postgres" -handle_ssl=true -enable_ui=true \ No newline at end of file diff --git a/config/config.go b/config/config.go deleted file mode 100644 index d18f285..0000000 --- a/config/config.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2024 mStar -// -// Licensed under the EUPL, Version 1.2 -// -// You may not use this work except in compliance with the Licence. -// You should have received a copy of the Licence along with this work. If not, see: -// . -// See the Licence for the specific language governing permissions and limitations under the Licence. -// - -package config - -import ( - "flag" - "os" - - "github.com/BurntSushi/toml" - "github.com/joho/godotenv" - "github.com/kelseyhightower/envconfig" - log "github.com/sirupsen/logrus" -) - -type CLIArguments struct { - // Path to a config file - ConfigFile string - // Path to a postgres database - // Nil if not provided - DbPath *string -} - -type Config struct { - General struct { - // Path to the postgres db - DbPath string `envconfig:"DATABASE_PATH" toml:"database_path"` - // Whether the server should handle ssl itself - HandleSSL bool `envconfig:"HANDLE_SSL" toml:"handle_ssl"` - // Whether to enable the builtin frontend - EnableUI bool `envconfig:"ENABLE_UI" toml:"enable_ui"` - Domain string `envconfig:"DOMAIN" toml:"domain"` - } -} - -// Reads arguments passed to the application -func ReadCLIArguments() CLIArguments { - configFlag := flag.String("config", "config.toml", "Path to a config file") - dbFlag := flag.String("db", "", "Path to a postgres database") - - flag.Parse() - - var dbString *string - if *dbFlag != "" { - dbString = dbFlag - } - - return CLIArguments{ - ConfigFile: *configFlag, - DbPath: dbString, - } -} - -// Read a config from the given CLI arguments as well as the config file specified in the cli args (default is config.toml) -func ReadConfig(cliArgs *CLIArguments) Config { - file, err := os.Open(cliArgs.ConfigFile) - if err != nil { - log.Fatalf("Failed to open file %s with error %v. Does it exist?\n", cliArgs.ConfigFile, err) - } - defer file.Close() - - var cfg Config - - decoder := toml.NewDecoder(file) - _, err = decoder.Decode(&cfg) - if err != nil { - log.Fatalf("Failed to parse config file %s with error %v\n", cliArgs.ConfigFile, err) - } - godotenv.Load() - err = envconfig.Process("", &cfg) - if err != nil { - log.Fatalf("Failed to overwrite config from env. Error %v\n", err) - } - - if cliArgs.DbPath != nil && *cliArgs.DbPath != "" { - cfg.General.DbPath = *cliArgs.DbPath - } - - return cfg -} diff --git a/endpoints/api/ap/ap.go b/endpoints/api/ap/ap.go deleted file mode 100644 index d98a97c..0000000 --- a/endpoints/api/ap/ap.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2024 mStar -// -// Licensed under the EUPL, Version 1.2 -// -// You may not use this work except in compliance with the Licence. -// You should have received a copy of the Licence along with this work. If not, see: -// . -// See the Licence for the specific language governing permissions and limitations under the Licence. -// - -package ap - -import ( - "net/http" - - "github.com/julienschmidt/httprouter" - "gitlab.com/mstarongitlab/linstrom/server" -) - -func Register(server *server.Server) { - server.Router.GET("/api/ap/user/:id", GetUser(server)) - server.Router.GET("/.well-known/webfinger", WebfingerEndpoint(server)) -} - -func GetUser(server *server.Server) func(http.ResponseWriter, *http.Request, httprouter.Params) { - return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {} -} diff --git a/endpoints/api/ap/mastodon/masto.go b/endpoints/api/ap/mastodon/masto.go deleted file mode 100644 index b190d74..0000000 --- a/endpoints/api/ap/mastodon/masto.go +++ /dev/null @@ -1,3 +0,0 @@ -package mastodon - -// https://docs.joinmastodon.org/spec/activitypub/ diff --git a/endpoints/api/ap/webfinger.go b/endpoints/api/ap/webfinger.go deleted file mode 100644 index 99142a2..0000000 --- a/endpoints/api/ap/webfinger.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2024 mStar -// -// Licensed under the EUPL, Version 1.2 -// -// You may not use this work except in compliance with the Licence. -// You should have received a copy of the Licence along with this work. If not, see: -// . -// See the Licence for the specific language governing permissions and limitations under the Licence. -// - -package ap - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" - "net/url" - "strings" - - "github.com/julienschmidt/httprouter" - "gitlab.com/mstarongitlab/goutils/other" - "gitlab.com/mstarongitlab/linstrom/server" - "gitlab.com/mstarongitlab/linstrom/storage" - "gitlab.com/mstarongitlab/linstrom/types" -) - -var ErrInvalidResource = errors.New("invalid resource") - -type webfingerLink struct { - Rel string `json:"self"` - Type string `json:"type"` - Target url.URL `json:"href"` -} - -type WebfingerResponse struct { - Subject string `json:"subject"` - Links []webfingerLink `json:"links"` -} - -func WebfingerEndpoint(server *server.Server) func(http.ResponseWriter, *http.Request, httprouter.Params) { - return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { - r.ParseForm() - req := r.FormValue("resource") - if req == "" { - http.NotFound(w, r) - return - } - acc, err := getAccountFromWebfingerResource(req) - if errors.Is(err, ErrInvalidResource) { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if acc.Host.Hostname() != server.Config.General.Domain { - http.Error(w, fmt.Sprintf("wrong host, try %s", &acc.Host), http.StatusNotFound) - return - } - - person, err := server.Storage.GetPersonByName(acc.Name) - if err != nil { - if errors.Is(err, storage.ErrNotFound) { - http.Error(w, fmt.Sprintf("Account %s not found", acc), http.StatusNotFound) - return - } else { - http.Error(w, fmt.Sprintf("Internal error: %s, please report", err.Error()), http.StatusInternalServerError) - } - } - - response := WebfingerResponse{ - Links: []webfingerLink{ - { - Rel: "me", - Type: "application/activity+json", - Target: *other.Must(url.Parse(fmt.Sprintf( - "https://%s/api/ap/user/%s", - server.Config.General.Domain, - person.Uid, - ))), - }, - }, - } - json.Marshal(response) - } -} - -// turns "acct:bugle@bugle.lol" into { Name: bugle, Host: bugle.lol } -func getAccountFromWebfingerResource(r string) (*types.AccountHandle, error) { - acctCheck, acc, found := strings.Cut(r, ":") - if !found || acctCheck != "acct" { - return nil, ErrInvalidResource - } - name, rawHost, found := strings.Cut(acc, "@") - if !found { - return nil, ErrInvalidResource - } - host, err := url.Parse(rawHost) - if err != nil { - return nil, fmt.Errorf("%w: Invalid url: %w", ErrInvalidResource, err) - } - - return &types.AccountHandle{ - Name: name, - Host: *host, - }, nil -} diff --git a/endpoints/endpoints.go b/endpoints/endpoints.go deleted file mode 100644 index 0a42ab4..0000000 --- a/endpoints/endpoints.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2024 mStar -// -// Licensed under the EUPL, Version 1.2 -// -// You may not use this work except in compliance with the Licence. -// You should have received a copy of the Licence along with this work. If not, see: -// . -// See the Licence for the specific language governing permissions and limitations under the Licence. -// - -package endpoints - -import ( - "gitlab.com/mstarongitlab/linstrom/endpoints/api/ap" - "gitlab.com/mstarongitlab/linstrom/server" -) - -func RegisterAll(s *server.Server) { - ap.Register(s) -} diff --git a/go.mod b/go.mod index dcf212b..611cf1a 100644 --- a/go.mod +++ b/go.mod @@ -1,28 +1,8 @@ module gitlab.com/mstarongitlab/linstrom -go 1.21.5 +go 1.22.2 require ( - github.com/BurntSushi/toml v1.3.2 - github.com/julienschmidt/httprouter v1.3.0 - github.com/kelseyhightower/envconfig v1.4.0 - github.com/sirupsen/logrus v1.9.3 - gorm.io/driver/postgres v1.5.4 - gorm.io/gorm v1.25.5 - gitlab.com/mstarongitlab/weblogger v0.0.0-20240123135616-d64461e3b20d -) - -require ( - github.com/MatejLach/astreams v0.6.0 // indirect - github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgx/v5 v5.4.3 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect - github.com/joho/godotenv v1.5.1 // indirect - github.com/lib/pq v1.10.9 // indirect - gitlab.com/mstarongitlab/goutils v0.0.0-20240117084827-7f9be06e1b58 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + github.com/piprate/json-gold v0.5.0 // indirect + github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect ) diff --git a/go.sum b/go.sum index 7a5908f..a726309 100644 --- a/go.sum +++ b/go.sum @@ -1,53 +1,4 @@ -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/MatejLach/astreams v0.6.0 h1:vOrPTVc0ZdByMKSGAB3Sq52C6EFgSikr7phwc/64yxw= -github.com/MatejLach/astreams v0.6.0/go.mod h1:4Ji/fRmm9wAv0JzNWbLULOlpQ8YZ45s9rQjl8Vp85yw= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= -github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= -github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= -github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -gitlab.com/mstarongitlab/goutils v0.0.0-20240117084827-7f9be06e1b58 h1:mRislY6modrbqu9ck/3d+P1b/fqxEcuN/s67ULMgATY= -gitlab.com/mstarongitlab/goutils v0.0.0-20240117084827-7f9be06e1b58/go.mod h1:SvqfzFxgashuZPqR9kPwQ9gFA7I1yskZjhmGmY2pAow= -gitlab.com/mstarongitlab/weblogger v0.0.0-20240123135616-d64461e3b20d h1:ixTYuViFIDQh9fs3xyc8sPKBr7dU7T98rs4kqM0q51k= -gitlab.com/mstarongitlab/weblogger v0.0.0-20240123135616-d64461e3b20d/go.mod h1:8G+BrXVs97wI7W+Z4E8M2MXFFKKy01cVnFazoCpNg9Y= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo= -gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0= -gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= -gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +github.com/piprate/json-gold v0.5.0 h1:RmGh1PYboCFcchVFuh2pbSWAZy4XJaqTMU4KQYsApbM= +github.com/piprate/json-gold v0.5.0/go.mod h1:WZ501QQMbZZ+3pXFPhQKzNwS1+jls0oqov3uQ2WasLs= +github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= +github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= diff --git a/guardian/guardian.go b/guardian/guardian.go deleted file mode 100644 index 6fd6538..0000000 --- a/guardian/guardian.go +++ /dev/null @@ -1,27 +0,0 @@ -package guardian - -import ( - "net/http" - - "gitlab.com/mstarongitlab/linstrom/config" - "gitlab.com/mstarongitlab/linstrom/storage" -) - -type GuardianMiddleware struct { - nextHandler http.Handler - config *config.Config - storage *storage.Storage -} - -func NewMiddleware(nextHandler http.Handler, cfg *config.Config, s *storage.Storage) *GuardianMiddleware { - return &GuardianMiddleware{ - nextHandler: nextHandler, - config: cfg, - storage: s, - } -} - -func (gm *GuardianMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // TODO: Add guardian filtering stuff here, see Planka - gm.nextHandler.ServeHTTP(w, r) -} diff --git a/main.go b/main.go deleted file mode 100644 index f3efef2..0000000 --- a/main.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2024 mStar -// -// Licensed under the EUPL, Version 1.2 -// -// You may not use this work except in compliance with the Licence. -// You should have received a copy of the Licence along with this work. If not, see: -// . -// See the Licence for the specific language governing permissions and limitations under the Licence. -// - -package main - -import ( - "fmt" - - "gitlab.com/mstarongitlab/linstrom/config" - "gitlab.com/mstarongitlab/linstrom/storage" -) - -func main() { - cliArgs := config.ReadCLIArguments() - fmt.Println(cliArgs) - cfg := config.ReadConfig(&cliArgs) - fmt.Println(cfg) - storage, err := storage.NewStorage(&cfg) - if err != nil { - panic(err) - } - fmt.Println(storage.GetFollowersFor("Placeholder")) -} diff --git a/server/server.go b/server/server.go deleted file mode 100644 index 9c23d43..0000000 --- a/server/server.go +++ /dev/null @@ -1,37 +0,0 @@ -package server - -import ( - "net/http" - - "github.com/julienschmidt/httprouter" - "gitlab.com/mstarongitlab/linstrom/config" - "gitlab.com/mstarongitlab/linstrom/guardian" - "gitlab.com/mstarongitlab/linstrom/storage" - "gitlab.com/mstarongitlab/weblogger" -) - -type Server struct { - // Register routes on here - Router *httprouter.Router - // Where to read and write stuff from - Storage *storage.Storage - // Global config. READ ONLY - Config *config.Config - // Final handler given to http.ListenAndServe - // Can be any router or middleware wrapped around a router - handler http.Handler -} - -func NewServer(cfg *config.Config, s *storage.Storage) *Server { - router := httprouter.New() - return &Server{ - Router: router, - Storage: s, - Config: cfg, - handler: guardian.NewMiddleware(weblogger.LoggingMiddleware(router), cfg, s), - } -} - -func (s *Server) Run() { - http.ListenAndServe(":8080", s.handler) -} diff --git a/storage/follows.go b/storage/follows.go deleted file mode 100644 index f15517d..0000000 --- a/storage/follows.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2024 mStar -// -// Licensed under the EUPL, Version 1.2 -// -// You may not use this work except in compliance with the Licence. -// You should have received a copy of the Licence along with this work. If not, see: -// . -// See the Licence for the specific language governing permissions and limitations under the Licence. -// - -package storage - -type Follow struct { - Follower Person - FollowerID uint - Follows Person - FollowsID uint -} - -func (s *Storage) GetFollowersFor(url string) ([]Follow, error) { - var pHit int64 - s.Db.Where("url = ?", url).Count(&pHit) - if pHit <= 0 { - return nil, ErrNotFound - } - var followed *Person = &Person{} - s.Db.Table("people").First(&followed, "url = ?", url) - var f []Follow = make([]Follow, 0) - s.Db.Table("follows").Find(&f, "follows_id = ?", followed.ID) - return f, nil -} diff --git a/storage/note.go b/storage/note.go deleted file mode 100644 index 4c9269d..0000000 --- a/storage/note.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2024 mStar -// -// Licensed under the EUPL, Version 1.2 -// -// You may not use this work except in compliance with the Licence. -// You should have received a copy of the Licence along with this work. If not, see: -// . -// See the Licence for the specific language governing permissions and limitations under the Licence. -// - -package storage - -import ( - "github.com/lib/pq" - "gorm.io/gorm" -) - -type Note struct { - gorm.Model // Includes primary key (uid) as well as various time info - - // Public data - - Uid string - Content string - CreatorID uint - Creator Person - Instance string // url - Local bool - Tags pq.StringArray `gorm:"type:text[]"` - RepliesTo *Note - RepliesToID *uint - DeliverTo pq.StringArray `gorm:"type:text[]"` // url - - // Private data - - // None yet -} diff --git a/storage/person.go b/storage/person.go deleted file mode 100644 index 975e664..0000000 --- a/storage/person.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2024 mStar -// -// Licensed under the EUPL, Version 1.2 -// -// You may not use this work except in compliance with the Licence. -// You should have received a copy of the Licence along with this work. If not, see: -// . -// See the Licence for the specific language governing permissions and limitations under the Licence. -// - -package storage - -import ( - "errors" - - "github.com/MatejLach/astreams" - "gorm.io/gorm" -) - -type Person struct { - gorm.Model // Includes primary key (uid) as well as various time info - - // Public data - - Uid string - ApID string - Name string - Instance string // url - Local bool - PublicKey string - Url string - ManuallyApprovesFollowers bool - - // Private data, set if local == true - - Mail *string // mail - PwHash *string - Inbox string // url - Outbox string // url - PrivateKey *string // private key -} - -func (pdb *Person) IntoAPPerson() (*astreams.Person, error) { - var actor astreams.Actor - actor.PublicKey = &astreams.PublicKey{ - ID: pdb.ApID, - Owner: pdb.Url, - PublicKeyPem: pdb.PublicKey, - } - actor.Inbox = &astreams.StringWithOrderedCollection{ - URL: pdb.Inbox, - } - actor.Outbox = &astreams.StringWithOrderedCollection{ - URL: pdb.Outbox, - } - actor.ManuallyApprovesFollowers = pdb.ManuallyApprovesFollowers - actor.PreferredUsername = pdb.Name - return nil, errors.New("unimplemented") -} - -// Gets a person from the db by name -func (s *Storage) GetPersonByName(name string) (*Person, error) { - var nrFound int64 - s.Db.Table("people").Where("name = ?", name).Count(&nrFound) - if nrFound <= 0 { - return nil, ErrNotFound - } - var p Person - s.Db.Table("people").Where("name = ?", name).First(&p) - return &p, nil -} diff --git a/storage/storage.go b/storage/storage.go deleted file mode 100644 index fc6480c..0000000 --- a/storage/storage.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2024 mStar -// -// Licensed under the EUPL, Version 1.2 -// -// You may not use this work except in compliance with the Licence. -// You should have received a copy of the Licence along with this work. If not, see: -// . -// See the Licence for the specific language governing permissions and limitations under the Licence. -// - -package storage - -import ( - "errors" - "fmt" - - "gitlab.com/mstarongitlab/linstrom/config" - "gorm.io/driver/postgres" - "gorm.io/gorm" -) - -var ErrNotFound = errors.New("entry not found") - -type Storage struct { - Db *gorm.DB -} - -func NewDb(cfg *config.Config) (*gorm.DB, error) { - db, err := gorm.Open(postgres.Open(cfg.General.DbPath)) - if err != nil { - return nil, fmt.Errorf("failed to connect to db %s: %w", cfg.General.DbPath, err) - } - err = db.AutoMigrate( - &Person{}, - &Note{ - Tags: make([]string, 0), - DeliverTo: make([]string, 0), - }, - &Follow{}, - ) - if err != nil { - return nil, fmt.Errorf("failed to apply migrations: %w", err) - } - return db, nil -} - -func NewStorage(cfg *config.Config) (*Storage, error) { - db, err := NewDb(cfg) - if err != nil { - return nil, fmt.Errorf("failed to create database connection while creating storage: %w", err) - } - return &Storage{ - Db: db, - }, nil -} diff --git a/types/types.go b/types/types.go deleted file mode 100644 index c83caae..0000000 --- a/types/types.go +++ /dev/null @@ -1,15 +0,0 @@ -package types - -import ( - "fmt" - "net/url" -) - -type AccountHandle struct { - Name string - Host url.URL -} - -func (a *AccountHandle) String() string { - return fmt.Sprintf("%s@%s", a.Name, a.Host.String()) -}