diff --git a/collections.go b/collections.go index 9ce9d8e..431afd1 100644 --- a/collections.go +++ b/collections.go @@ -824,13 +824,14 @@ func handleViewMention(app *App, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) handle := vars["handle"] - remoteUser, err := getRemoteUserFromHandle(app, handle) + remoteUser, err := app.db.getProfilePageFromHandle(app, handle) if err != nil { - log.Error("Couldn't find this user in our database "+handle, err) - return err + log.Error("Couldn't find this user "+handle, err) + return nil } - w.Write([]byte("go to " + remoteUser.ActorID)) + http.Redirect(w, r, remoteUser, http.StatusSeeOther) + w.Write([]byte("go to " + remoteUser)) return nil } diff --git a/database.go b/database.go index a3235b6..a95bfca 100644 --- a/database.go +++ b/database.go @@ -20,6 +20,7 @@ import ( "github.com/guregu/null" "github.com/guregu/null/zero" uuid "github.com/nu7hatch/gouuid" + "github.com/writeas/activityserve" "github.com/writeas/impart" "github.com/writeas/nerds/store" "github.com/writeas/web-core/activitypub" @@ -2449,3 +2450,38 @@ func handleFailedPostInsert(err error) error { log.Error("Couldn't insert into posts: %v", err) return err } + +func (db *datastore) getProfilePageFromHandle(app *App, handle string) (actorIRI string, err error) { + remoteuser, errRemoteUser := getRemoteUserFromHandle(app, handle) + if errRemoteUser != nil { + // can't find using handle in the table but the table may already have this user without + // handle from a previous version + actorIRI = RemoteLookup(handle) + _, errRemoteUser := getRemoteUser(app, actorIRI) + // if it exists then we need to update the handle + if errRemoteUser == nil { + // query := "UPDATE remoteusers SET handle='" + handle + "' WHERE actor_id='" + iri + "';" + // log.Info(query) + _, err := app.db.Exec("UPDATE remoteusers SET handle=? WHERE actor_id=?;", handle, actorIRI) + if err != nil { + log.Error("Can't update handle (" + handle + ") in database for user " + actorIRI) + } + } else { + // this probably means we don't have the user in the table so let's try to insert it + // here we need to ask the server for the inboxes + remoteActor, err := activityserve.NewRemoteActor(actorIRI) + if err != nil { + log.Error("Couldn't fetch remote actor", err) + } + fmt.Println(actorIRI, remoteActor.GetInbox(), remoteActor.GetSharedInbox(), handle) + _, err = app.db.Exec("INSERT INTO remoteusers (actor_id, inbox, shared_inbox, handle) VALUES( ?, ?, ?, ?)", actorIRI, remoteActor.GetInbox(), remoteActor.GetSharedInbox(), handle) + if err != nil { + log.Error("Can't insert remote user in database", err) + return "", err + } + } + } else { + actorIRI = remoteuser.ActorID + } + return actorIRI, nil +} diff --git a/migrations/migrations.go b/migrations/migrations.go index 70e4b7b..145c6df 100644 --- a/migrations/migrations.go +++ b/migrations/migrations.go @@ -57,6 +57,7 @@ func (m *migration) Migrate(db *datastore) error { var migrations = []Migration{ New("support user invites", supportUserInvites), // -> V1 (v0.8.0) New("support dynamic instance pages", supportInstancePages), // V1 -> V2 (v0.9.0) + New("support activityPub mentions", supportActivityPubMentions), // V2 -> V3 (v0.1x.0) } // CurrentVer returns the current migration version the application is on diff --git a/migrations/v3.go b/migrations/v3.go new file mode 100644 index 0000000..5c3f5aa --- /dev/null +++ b/migrations/v3.go @@ -0,0 +1,23 @@ +/* + * Copyright © 2019 A Bunch Tell LLC. + * + * This file is part of WriteFreely. + * + * WriteFreely is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, included + * in the LICENSE file in this source code package. + */ + +package migrations + +func supportActivityPubMentions(db *datastore) error { + t, err := db.Begin() + + _, err = t.Exec(`ALTER TABLE remoteusers ADD COLUMN handle ` + db.typeVarChar(255) + ` DEFAULT '' NOT NULL`) + if err != nil { + t.Rollback() + return err + } + + return nil +} diff --git a/posts.go b/posts.go index 3eeb232..df8be93 100644 --- a/posts.go +++ b/posts.go @@ -25,7 +25,6 @@ import ( "github.com/guregu/null/zero" "github.com/kylemcc/twitter-text-go/extract" "github.com/microcosm-cc/bluemonday" - "github.com/writeas/activityserve" stripmd "github.com/writeas/go-strip-markdown" "github.com/writeas/impart" "github.com/writeas/monday" @@ -1118,37 +1117,10 @@ func (p *PublicPost) ActivityObject(app *App) *activitystreams.Object { mentions := mentionRegex.FindAllString(content, -1) for _, handle := range mentions { - var actorIRI string - remoteuser, errRemoteUser := getRemoteUserFromHandle(app, handle) - if errRemoteUser != nil { - // can't find using handle in the table but the table may already have this user without - // handle from a previous version - actorIRI = RemoteLookup(handle) - _, errRemoteUser := getRemoteUser(app, actorIRI) - // if it exists then we need to update the handle - if errRemoteUser == nil { - // query := "UPDATE remoteusers SET handle='" + handle + "' WHERE actor_id='" + iri + "';" - // log.Info(query) - _, err := app.db.Exec("UPDATE remoteusers SET handle=? WHERE actor_id=?;", handle, actorIRI) - if err != nil { - log.Error("Can't update handle (" + handle + ") in database for user " + actorIRI) - } - } else { - // this probably means we don't have the user in the table so let's try to insert it - // here we need to ask the server for the inboxes - remoteActor, err := activityserve.NewRemoteActor(actorIRI) - if err != nil { - log.Error("Couldn't fetch remote actor", err) - } - fmt.Println(actorIRI, remoteActor.GetInbox(), remoteActor.GetSharedInbox(), handle) - _, err = app.db.Exec("INSERT INTO remoteusers (actor_id, inbox, shared_inbox, handle) VALUES( ?, ?, ?, ?)", actorIRI, remoteActor.GetInbox(), remoteActor.GetSharedInbox(), handle) - if err != nil { - log.Error("Can't insert remote user in database", err) - return nil - } - } - } else { - actorIRI = remoteuser.ActorID + actorIRI, err := app.db.getProfilePageFromHandle(app, handle) + if err != nil { + log.Info("Can't find this user either in the database nor in the remote instance") + return nil } mentionedUsers[handle] = actorIRI } diff --git a/schema.sql b/schema.sql index b3fae97..ca8ec71 100644 --- a/schema.sql +++ b/schema.sql @@ -181,6 +181,7 @@ CREATE TABLE IF NOT EXISTS `remoteusers` ( `actor_id` varchar(255) NOT NULL, `inbox` varchar(255) NOT NULL, `shared_inbox` varchar(255) NOT NULL, + `handle` varchar(255) DEFAULT '' NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `collection_id` (`actor_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/sqlite.sql b/sqlite.sql index 90989ed..e1a6b96 100644 --- a/sqlite.sql +++ b/sqlite.sql @@ -172,6 +172,7 @@ CREATE TABLE IF NOT EXISTS `remoteusers` ( actor_id TEXT NOT NULL, inbox TEXT NOT NULL, shared_inbox TEXT NOT NULL, + handle TEXT DEFAULT '' NOT NULL, CONSTRAINT collection_id UNIQUE (actor_id) );