doi.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package routes
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/rand"
  6. "encoding/base64"
  7. "io"
  8. "net/http"
  9. "net/url"
  10. "github.com/G-Node/gogs/pkg/context"
  11. "github.com/G-Node/gogs/pkg/setting"
  12. log "gopkg.in/clog.v1"
  13. )
  14. func RequestDOI(c *context.Context) {
  15. if !c.Repo.IsAdmin() {
  16. c.Status(http.StatusUnauthorized)
  17. return
  18. }
  19. repo := c.Repo.Repository.FullName()
  20. username := c.User.Name
  21. verification, err := encrypt([]byte(setting.DOI.Key), repo+username)
  22. if err != nil {
  23. log.Error(2, "Could not encrypt token for DOI request: %s", err)
  24. c.Status(http.StatusInternalServerError)
  25. return
  26. }
  27. doiurl, err := url.Parse(setting.DOI.URL + "/register") // TODO: Handle error by notifying admin email
  28. if err != nil {
  29. log.Error(2, "Failed to parse DOI URL: %s", setting.DOI.URL)
  30. }
  31. params := url.Values{}
  32. params.Add("repo", repo)
  33. params.Add("user", username)
  34. params.Add("verification", verification)
  35. doiurl.RawQuery = params.Encode()
  36. target, _ := url.PathUnescape(doiurl.String())
  37. log.Trace(target)
  38. c.Redirect(target)
  39. }
  40. // NOTE: TEMPORARY COPY FROM gin-doi
  41. // encrypt string to base64 crypto using AES
  42. func encrypt(key []byte, text string) (string, error) {
  43. plaintext := []byte(text)
  44. block, err := aes.NewCipher(key)
  45. if err != nil {
  46. return "", err
  47. }
  48. // The IV needs to be unique, but not secure. Therefore it's common to
  49. // include it at the beginning of the ciphertext.
  50. ciphertext := make([]byte, aes.BlockSize+len(plaintext))
  51. iv := ciphertext[:aes.BlockSize]
  52. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  53. return "", err
  54. }
  55. stream := cipher.NewCFBEncrypter(block, iv)
  56. stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
  57. // convert to base64
  58. return base64.URLEncoding.EncodeToString(ciphertext), nil
  59. }