receiver.go 3.04 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"
Ghost User's avatar
Ghost User committed
23 24
  helpers "git.feneas.org/ganggo/federation/helpers"
  "git.feneas.org/ganggo/federation"
25
  run "github.com/revel/modules/jobs/app/jobs"
zauberstuhl's avatar
zauberstuhl committed
26 27
  "git.feneas.org/ganggo/ganggo/app/models"
  "git.feneas.org/ganggo/ganggo/app/jobs"
28
  "io/ioutil"
zauberstuhl's avatar
zauberstuhl committed
29 30 31 32 33 34 35
)

type Receiver struct {
  *revel.Controller
}

func (r Receiver) Public() revel.Result {
36
  db, err := models.OpenDatabase()
zauberstuhl's avatar
zauberstuhl committed
37
  if err != nil {
38 39
    r.Log.Error("Cannot open database", "error", err)
    return r.RenderError(err)
zauberstuhl's avatar
zauberstuhl committed
40 41 42
  }
  defer db.Close()

43 44
  request := r.Request.In.GetRaw().(*http.Request)
  content, err := ioutil.ReadAll(request.Body)
zauberstuhl's avatar
zauberstuhl committed
45 46 47 48 49
  if err != nil {
    r.Response.Status = http.StatusNotAcceptable
    return r.Render()
  }

50
  r.Log.Debug("received publicly", "message", string(content))
51 52 53 54

  // in case it succeeds reply with status 202
  r.Response.Status = http.StatusAccepted

Ghost User's avatar
Ghost User committed
55
  msg, err := federation.DiasporaParse(content)
56
  if err != nil {
Ghost User's avatar
Ghost User committed
57 58 59
    r.Log.Error("Cannot parse content", err.Error(), err)
  } else {
    run.Now(jobs.Receiver{Message: msg})
60
  }
zauberstuhl's avatar
zauberstuhl committed
61 62 63 64 65 66 67 68 69 70
  return r.Render()
}

func (r Receiver) Private() revel.Result {
  var (
    guid string
    person models.Person
    user models.User
  )

71
  db, err := models.OpenDatabase()
zauberstuhl's avatar
zauberstuhl committed
72
  if err != nil {
73 74
    r.Log.Error("Cannot open database", "error", err)
    return r.RenderError(err)
zauberstuhl's avatar
zauberstuhl committed
75 76 77 78
  }
  defer db.Close()

  r.Params.Bind(&guid, "guid")
79 80
  r.Response.Status = http.StatusAccepted

Ghost User's avatar
Ghost User committed
81
  r.Log.Debug("received privately", "message", string(r.Params.JSON))
zauberstuhl's avatar
zauberstuhl committed
82 83 84

  err = db.Where("guid like ?", guid).First(&person).Error
  if err != nil {
85
    r.Log.Error("Cannot find person", "error", err)
zauberstuhl's avatar
zauberstuhl committed
86 87 88 89 90 91
    // diaspora will not process on StatusNotAcceptable
    return r.Render()
  }

  err = db.First(&user, person.UserID).Error
  if err != nil {
92
    r.Log.Error("Cannot find user", "error", err)
zauberstuhl's avatar
zauberstuhl committed
93 94 95 96
    r.Response.Status = http.StatusNotAcceptable
    return r.Render()
  }

Ghost User's avatar
Ghost User committed
97
  privKey, err := helpers.ParseRSAPrivateKey(
98 99 100 101 102 103 104
    []byte(user.SerializedPrivateKey))
  if err != nil {
    r.Log.Error(err.Error())
    r.Response.Status = http.StatusInternalServerError
    return r.Render()
  }

Ghost User's avatar
Ghost User committed
105
  msg, err := federation.DiasporaParseEncrypted(r.Params.JSON, privKey)
zauberstuhl's avatar
zauberstuhl committed
106
  if err != nil {
Ghost User's avatar
Ghost User committed
107 108 109
    r.Log.Error("Cannot parse content", err.Error(), err)
  } else {
    run.Now(jobs.Receiver{Message: msg, Guid: guid})
zauberstuhl's avatar
zauberstuhl committed
110 111 112
  }
  return r.Render()
}