fetch.go 2.96 KB
Newer Older
zauberstuhl's avatar
zauberstuhl committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
package controllers
//
// GangGo Application Server
// Copyright (C) 2017 Lukas Matt <lukas@zauberstuhl.de>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

import (
  "net/http"
  "github.com/revel/revel"
zauberstuhl's avatar
zauberstuhl committed
23 24
  "git.feneas.org/ganggo/ganggo/app/models"
  "git.feneas.org/ganggo/ganggo/app/helpers"
Ghost User's avatar
Ghost User committed
25 26
  fhelpers "git.feneas.org/ganggo/federation/helpers"
  "git.feneas.org/ganggo/federation"
zauberstuhl's avatar
zauberstuhl committed
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
  "strings"
)

type Fetch struct {
  *revel.Controller
}

type RenderBytes []byte

func (b RenderBytes) Apply(req *revel.Request, resp *revel.Response) {
  resp.WriteHeader(http.StatusOK, "application/magic-envelope+xml")
  resp.GetWriter().Write(b)
}

func (f Fetch) Index(shareable, guid string) revel.Result {
  var payload []byte
  switch {
  case strings.EqualFold(shareable, models.ShareablePost):
    fallthrough
  // XXX hard-coded status message type
  case strings.EqualFold(shareable, "status_message"):
    var post models.Post
    err := post.FindByGuid(guid)
    if err != nil {
      f.Log.Debug("Fetch post error", "err", err)
      return f.NotFound(err.Error())
    }

    if !post.Public {
      // only public entities should be fetchable
      return f.NotFound("record not found")
    }

    if user, ok := post.IsLocal(); ok {
Ghost User's avatar
Ghost User committed
61
      privKey, err := fhelpers.ParseRSAPrivateKey(
zauberstuhl's avatar
zauberstuhl committed
62 63 64 65 66 67
        []byte(user.SerializedPrivateKey))
      if err != nil {
        f.Log.Error("Fetch parse key error", "err", err)
        return f.NotFound("record not found")
      }

Ghost User's avatar
Ghost User committed
68
      entity, err := federation.NewMessagePost(federation.DiasporaProtocol)
zauberstuhl's avatar
zauberstuhl committed
69
      if err != nil {
Ghost User's avatar
Ghost User committed
70 71
        f.Log.Error("Fetch message error", "err", err)
        return f.NotFound("record not found")
zauberstuhl's avatar
zauberstuhl committed
72
      }
Ghost User's avatar
Ghost User committed
73 74 75 76 77 78
      entity.SetText(post.Text)
      entity.SetAuthor(post.Person.Author)
      entity.SetGuid(post.Guid)
      entity.SetProvider(post.ProviderName)
      entity.SetPublic(post.Public)
      entity.SetCreatedAt(post.CreatedAt)
zauberstuhl's avatar
zauberstuhl committed
79

Ghost User's avatar
Ghost User committed
80
      payload, err = entity.Marshal(privKey, nil)
zauberstuhl's avatar
zauberstuhl committed
81 82 83 84 85
      if err != nil {
        f.Log.Error("Fetch magic envelope error", "err", err)
        return f.RenderError(err)
      }
    } else {
Ghost User's avatar
Ghost User committed
86
      host, err := helpers.ParseHost(post.Person.Author)
zauberstuhl's avatar
zauberstuhl committed
87 88 89 90 91 92 93 94 95 96 97
      if err != nil {
        f.Log.Error("Fetch parse author error", "err", err)
        return f.RenderError(err)
      }
      return f.Redirect("http://%s/fetch/%s/%s", host, shareable, guid)
    }
  default:
    return f.NotFound("not supported type")
  }
  return RenderBytes(payload)
}