db_gin.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. package db
  2. import (
  3. "bufio"
  4. "encoding/json"
  5. "fmt"
  6. "net/http"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "github.com/G-Node/git-module"
  11. "github.com/G-Node/gogs/internal/conf"
  12. "github.com/G-Node/libgin/libgin"
  13. "github.com/G-Node/libgin/libgin/annex"
  14. "github.com/unknwon/com"
  15. "golang.org/x/crypto/bcrypt"
  16. log "gopkg.in/clog.v1"
  17. )
  18. // StartIndexing sends an indexing request to the configured indexing service
  19. // for a repository.
  20. func StartIndexing(repo Repository) {
  21. go func() {
  22. if conf.Search.IndexURL == "" {
  23. log.Trace("Indexing not enabled")
  24. return
  25. }
  26. log.Trace("Indexing repository %d", repo.ID)
  27. ireq := libgin.IndexRequest{
  28. RepoID: repo.ID,
  29. RepoPath: repo.FullName(),
  30. }
  31. data, err := json.Marshal(ireq)
  32. if err != nil {
  33. log.Error(2, "Could not marshal index request: %v", err)
  34. return
  35. }
  36. key := []byte(conf.Search.Key)
  37. encdata, err := libgin.EncryptString(key, string(data))
  38. if err != nil {
  39. log.Error(2, "Could not encrypt index request: %v", err)
  40. }
  41. req, err := http.NewRequest(http.MethodPost, conf.Search.IndexURL, strings.NewReader(encdata))
  42. if err != nil {
  43. log.Error(2, "Error creating index request")
  44. }
  45. client := http.Client{}
  46. resp, err := client.Do(req)
  47. if err != nil || resp.StatusCode != http.StatusOK {
  48. log.Error(2, "Error submitting index request for [%d: %s]: %v", repo.ID, repo.FullName(), err)
  49. return
  50. }
  51. }()
  52. }
  53. // RebuildIndex sends all repositories to the indexing service to be indexed.
  54. func RebuildIndex() error {
  55. indexurl := conf.Search.IndexURL
  56. if indexurl == "" {
  57. return fmt.Errorf("Indexing service not configured")
  58. }
  59. // collect all repo ID -> Path mappings directly from the DB
  60. repos := make(RepositoryList, 0, 100)
  61. if err := x.Find(&repos); err != nil {
  62. return fmt.Errorf("get all repos: %v", err)
  63. }
  64. log.Trace("Found %d repositories to index", len(repos))
  65. for _, repo := range repos {
  66. StartIndexing(*repo)
  67. }
  68. log.Trace("Rebuilding search index")
  69. return nil
  70. }
  71. func annexUninit(path string) {
  72. // walker sets the permission for any file found to 0660, to allow deletion
  73. var mode os.FileMode
  74. walker := func(path string, info os.FileInfo, err error) error {
  75. if info == nil {
  76. return nil
  77. }
  78. mode = 0660
  79. if info.IsDir() {
  80. mode = 0770
  81. }
  82. if err := os.Chmod(path, mode); err != nil {
  83. log.Error(3, "failed to change permissions on '%s': %v", path, err)
  84. }
  85. return nil
  86. }
  87. log.Trace("Uninit annex at '%s'", path)
  88. if msg, err := annex.Uninit(path); err != nil {
  89. log.Error(3, "uninit failed: %v (%s)", err, msg)
  90. if werr := filepath.Walk(path, walker); werr != nil {
  91. log.Error(3, "file permission change failed: %v", werr)
  92. }
  93. }
  94. }
  95. func annexSetup(path string) {
  96. log.Trace("Running annex add (with filesize filter) in '%s'", path)
  97. // Initialise annex in case it's a new repository
  98. if msg, err := annex.Init(path); err != nil {
  99. log.Error(2, "Annex init failed: %v (%s)", err, msg)
  100. return
  101. }
  102. // Upgrade to v8 in case the directory was here before and wasn't cleaned up properly
  103. if msg, err := annex.Upgrade(path); err != nil {
  104. log.Error(2, "Annex upgrade failed: %v (%s)", err, msg)
  105. return
  106. }
  107. // Enable addunlocked for annex v8
  108. if msg, err := annex.SetAddUnlocked(path); err != nil {
  109. log.Error(2, "Failed to set 'addunlocked' annex option: %v (%s)", err, msg)
  110. }
  111. // Set MD5 as default backend
  112. if msg, err := annex.MD5(path); err != nil {
  113. log.Error(2, "Failed to set default backend to 'MD5': %v (%s)", err, msg)
  114. }
  115. // Set size filter in config
  116. if msg, err := annex.SetAnnexSizeFilter(path, conf.Repository.Upload.AnnexFileMinSize*annex.MEGABYTE); err != nil {
  117. log.Error(2, "Failed to set size filter for annex: %v (%s)", err, msg)
  118. }
  119. }
  120. func annexSync(path string) error {
  121. log.Trace("Synchronising annexed data")
  122. if msg, err := annex.ASync(path, "--content"); err != nil {
  123. // TODO: This will also DOWNLOAD content, which is unnecessary for a simple upload
  124. // TODO: Use gin-cli upload function instead
  125. log.Error(2, "Annex sync failed: %v (%s)", err, msg)
  126. return fmt.Errorf("git annex sync --content [%s]", path)
  127. }
  128. // run twice; required if remote annex is not initialised
  129. if msg, err := annex.ASync(path, "--content"); err != nil {
  130. log.Error(2, "Annex sync failed: %v (%s)", err, msg)
  131. return fmt.Errorf("git annex sync --content [%s]", path)
  132. }
  133. return nil
  134. }
  135. func annexAdd(repoPath string, all bool, files ...string) error {
  136. cmd := git.NewCommand("annex", "add")
  137. if all {
  138. cmd.AddArguments(".")
  139. }
  140. _, err := cmd.AddArguments(files...).RunInDir(repoPath)
  141. return err
  142. }
  143. func annexUpload(repoPath, remote string) error {
  144. log.Trace("Synchronising annex info")
  145. if msg, err := git.NewCommand("annex", "sync").RunInDir(repoPath); err != nil {
  146. log.Error(2, "git-annex sync failed: %v (%s)", err, msg)
  147. }
  148. log.Trace("Uploading annexed data")
  149. cmd := git.NewCommand("annex", "copy", fmt.Sprintf("--to=%s", remote), "--all")
  150. if msg, err := cmd.RunInDir(repoPath); err != nil {
  151. log.Error(2, "git-annex copy failed: %v (%s)", err, msg)
  152. return fmt.Errorf("git annex copy [%s]", repoPath)
  153. }
  154. return nil
  155. }
  156. func IsBlockedDomain(email string) bool {
  157. // fpath := path.Join(setting.CustomPath, "blocklist")
  158. fpath := filepath.Join(conf.CustomDir(), "blocklist")
  159. if !com.IsExist(fpath) {
  160. return false
  161. }
  162. f, err := os.Open(fpath)
  163. if err != nil {
  164. log.Error(2, "Failed to open file %q: %v", fpath, err)
  165. return false
  166. }
  167. defer f.Close()
  168. scanner := bufio.NewScanner(f)
  169. for scanner.Scan() {
  170. // Check provided email address against each line as suffix
  171. if strings.HasSuffix(email, scanner.Text()) {
  172. log.Trace("New user email matched blocked domain: %q", email)
  173. return true
  174. }
  175. }
  176. return false
  177. }
  178. func (u *User) OldGinVerifyPassword(plain string) bool {
  179. err := bcrypt.CompareHashAndPassword([]byte(u.Passwd), []byte(plain))
  180. return err == nil
  181. }