You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

convert.go 12 kB

Sign merges, CRUD, Wiki and Repository initialisation with gpg key (#7631) This PR fixes #7598 by providing a configurable way of signing commits across the Gitea instance. Per repository configurability and import/generation of trusted secure keys is not provided by this PR - from a security PoV that's probably impossible to do properly. Similarly web-signing, that is asking the user to sign something, is not implemented - this could be done at a later stage however. ## Features - [x] If commit.gpgsign is set in .gitconfig sign commits and files created through repofiles. (merges should already have been signed.) - [x] Verify commits signed with the default gpg as valid - [x] Signer, Committer and Author can all be different - [x] Allow signer to be arbitrarily different - We still require the key to have an activated email on Gitea. A more complete implementation would be to use a keyserver and mark external-or-unactivated with an "unknown" trust level icon. - [x] Add a signing-key.gpg endpoint to get the default gpg pub key if available - Rather than add a fake web-flow user I've added this as an endpoint on /api/v1/signing-key.gpg - [x] Try to match the default key with a user on gitea - this is done at verification time - [x] Make things configurable? - app.ini configuration done - [x] when checking commits are signed need to check if they're actually verifiable too - [x] Add documentation I have decided that adjusting the docker to create a default gpg key is not the correct thing to do and therefore have not implemented this.
6 years ago
Sign merges, CRUD, Wiki and Repository initialisation with gpg key (#7631) This PR fixes #7598 by providing a configurable way of signing commits across the Gitea instance. Per repository configurability and import/generation of trusted secure keys is not provided by this PR - from a security PoV that's probably impossible to do properly. Similarly web-signing, that is asking the user to sign something, is not implemented - this could be done at a later stage however. ## Features - [x] If commit.gpgsign is set in .gitconfig sign commits and files created through repofiles. (merges should already have been signed.) - [x] Verify commits signed with the default gpg as valid - [x] Signer, Committer and Author can all be different - [x] Allow signer to be arbitrarily different - We still require the key to have an activated email on Gitea. A more complete implementation would be to use a keyserver and mark external-or-unactivated with an "unknown" trust level icon. - [x] Add a signing-key.gpg endpoint to get the default gpg pub key if available - Rather than add a fake web-flow user I've added this as an endpoint on /api/v1/signing-key.gpg - [x] Try to match the default key with a user on gitea - this is done at verification time - [x] Make things configurable? - app.ini configuration done - [x] when checking commits are signed need to check if they're actually verifiable too - [x] Add documentation I have decided that adjusting the docker to create a default gpg key is not the correct thing to do and therefore have not implemented this.
6 years ago
Sign merges, CRUD, Wiki and Repository initialisation with gpg key (#7631) This PR fixes #7598 by providing a configurable way of signing commits across the Gitea instance. Per repository configurability and import/generation of trusted secure keys is not provided by this PR - from a security PoV that's probably impossible to do properly. Similarly web-signing, that is asking the user to sign something, is not implemented - this could be done at a later stage however. ## Features - [x] If commit.gpgsign is set in .gitconfig sign commits and files created through repofiles. (merges should already have been signed.) - [x] Verify commits signed with the default gpg as valid - [x] Signer, Committer and Author can all be different - [x] Allow signer to be arbitrarily different - We still require the key to have an activated email on Gitea. A more complete implementation would be to use a keyserver and mark external-or-unactivated with an "unknown" trust level icon. - [x] Add a signing-key.gpg endpoint to get the default gpg pub key if available - Rather than add a fake web-flow user I've added this as an endpoint on /api/v1/signing-key.gpg - [x] Try to match the default key with a user on gitea - this is done at verification time - [x] Make things configurable? - app.ini configuration done - [x] when checking commits are signed need to check if they're actually verifiable too - [x] Add documentation I have decided that adjusting the docker to create a default gpg key is not the correct thing to do and therefore have not implemented this.
6 years ago
Sign merges, CRUD, Wiki and Repository initialisation with gpg key (#7631) This PR fixes #7598 by providing a configurable way of signing commits across the Gitea instance. Per repository configurability and import/generation of trusted secure keys is not provided by this PR - from a security PoV that's probably impossible to do properly. Similarly web-signing, that is asking the user to sign something, is not implemented - this could be done at a later stage however. ## Features - [x] If commit.gpgsign is set in .gitconfig sign commits and files created through repofiles. (merges should already have been signed.) - [x] Verify commits signed with the default gpg as valid - [x] Signer, Committer and Author can all be different - [x] Allow signer to be arbitrarily different - We still require the key to have an activated email on Gitea. A more complete implementation would be to use a keyserver and mark external-or-unactivated with an "unknown" trust level icon. - [x] Add a signing-key.gpg endpoint to get the default gpg pub key if available - Rather than add a fake web-flow user I've added this as an endpoint on /api/v1/signing-key.gpg - [x] Try to match the default key with a user on gitea - this is done at verification time - [x] Make things configurable? - app.ini configuration done - [x] when checking commits are signed need to check if they're actually verifiable too - [x] Add documentation I have decided that adjusting the docker to create a default gpg key is not the correct thing to do and therefore have not implemented this.
6 years ago
Sign merges, CRUD, Wiki and Repository initialisation with gpg key (#7631) This PR fixes #7598 by providing a configurable way of signing commits across the Gitea instance. Per repository configurability and import/generation of trusted secure keys is not provided by this PR - from a security PoV that's probably impossible to do properly. Similarly web-signing, that is asking the user to sign something, is not implemented - this could be done at a later stage however. ## Features - [x] If commit.gpgsign is set in .gitconfig sign commits and files created through repofiles. (merges should already have been signed.) - [x] Verify commits signed with the default gpg as valid - [x] Signer, Committer and Author can all be different - [x] Allow signer to be arbitrarily different - We still require the key to have an activated email on Gitea. A more complete implementation would be to use a keyserver and mark external-or-unactivated with an "unknown" trust level icon. - [x] Add a signing-key.gpg endpoint to get the default gpg pub key if available - Rather than add a fake web-flow user I've added this as an endpoint on /api/v1/signing-key.gpg - [x] Try to match the default key with a user on gitea - this is done at verification time - [x] Make things configurable? - app.ini configuration done - [x] when checking commits are signed need to check if they're actually verifiable too - [x] Add documentation I have decided that adjusting the docker to create a default gpg key is not the correct thing to do and therefore have not implemented this.
6 years ago
Add API endpoint for accessing repo topics (#7963) * Create API endpoints for repo topics. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Generate swagger Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Add documentation to functions Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Grammar fix Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Fix function comment Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Can't use FindTopics when looking for a single repo topic, as it doesnt use exact match Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Add PUT ​/repos​/{owner}​/{repo}​/topics and remove GET ​/repos​/{owner}​/{repo}​/topics * Ignore if topic is sent twice in same request, refactoring. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Fix topic dropdown with api changes. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Style fix Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Update API documentation Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Better way to handle duplicate topics in slice Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Make response element TopicName an array of strings, instead of using an array of TopicName Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Add test cases for API Repo Topics. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Fix format of tests Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Fix comments Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Fix unit tests after adding some more topics to the test fixture. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Update models/topic.go Limit multiple if else if ... Co-Authored-By: Antoine GIRARD <sapk@users.noreply.github.com> * Engine as first parameter in function Co-Authored-By: Antoine GIRARD <sapk@users.noreply.github.com> * Replace magic numbers with http status code constants. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Fix variable scope Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Test one read with login and one with token Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Add some more tests Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Apply suggestions from code review Use empty struct for efficiency Co-Authored-By: Lauris BH <lauris@nix.lv> * Add test case to check access for user with write access Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Fix access, repo admin required to change topics Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Correct first test to be without token Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Any repo reader should be able to access topics. * No need for string pointer Signed-off-by: David Svantesson <davidsvantesson@gmail.com>
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2018 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package convert
  6. import (
  7. "fmt"
  8. "strconv"
  9. "time"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/modules/git"
  12. "code.gitea.io/gitea/modules/log"
  13. "code.gitea.io/gitea/modules/structs"
  14. api "code.gitea.io/gitea/modules/structs"
  15. "code.gitea.io/gitea/modules/util"
  16. "code.gitea.io/gitea/modules/webhook"
  17. "github.com/unknwon/com"
  18. )
  19. // ToEmail convert models.EmailAddress to api.Email
  20. func ToEmail(email *models.EmailAddress) *api.Email {
  21. return &api.Email{
  22. Email: email.Email,
  23. Verified: email.IsActivated,
  24. Primary: email.IsPrimary,
  25. }
  26. }
  27. // ToBranch convert a git.Commit and git.Branch to an api.Branch
  28. func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models.ProtectedBranch, user *models.User, isRepoAdmin bool) (*api.Branch, error) {
  29. if bp == nil {
  30. var hasPerm bool
  31. var err error
  32. if user != nil {
  33. hasPerm, err = models.HasAccessUnit(user, repo, models.UnitTypeCode, models.AccessModeWrite)
  34. if err != nil {
  35. return nil, err
  36. }
  37. }
  38. return &api.Branch{
  39. Name: b.Name,
  40. Commit: ToPayloadCommit(repo, c),
  41. Protected: false,
  42. RequiredApprovals: 0,
  43. EnableStatusCheck: false,
  44. StatusCheckContexts: []string{},
  45. UserCanPush: hasPerm,
  46. UserCanMerge: hasPerm,
  47. }, nil
  48. }
  49. branch := &api.Branch{
  50. Name: b.Name,
  51. Commit: ToPayloadCommit(repo, c),
  52. Protected: true,
  53. RequiredApprovals: bp.RequiredApprovals,
  54. EnableStatusCheck: bp.EnableStatusCheck,
  55. StatusCheckContexts: bp.StatusCheckContexts,
  56. }
  57. if isRepoAdmin {
  58. branch.EffectiveBranchProtectionName = bp.BranchName
  59. }
  60. if user != nil {
  61. permission, err := models.GetUserRepoPermission(repo, user)
  62. if err != nil {
  63. return nil, err
  64. }
  65. branch.UserCanPush = bp.CanUserPush(user.ID)
  66. branch.UserCanMerge = bp.IsUserMergeWhitelisted(user.ID, permission)
  67. }
  68. return branch, nil
  69. }
  70. // ToBranchProtection convert a ProtectedBranch to api.BranchProtection
  71. func ToBranchProtection(bp *models.ProtectedBranch) *api.BranchProtection {
  72. pushWhitelistUsernames, err := models.GetUserNamesByIDs(bp.WhitelistUserIDs)
  73. if err != nil {
  74. log.Error("GetUserNamesByIDs (WhitelistUserIDs): %v", err)
  75. }
  76. mergeWhitelistUsernames, err := models.GetUserNamesByIDs(bp.MergeWhitelistUserIDs)
  77. if err != nil {
  78. log.Error("GetUserNamesByIDs (MergeWhitelistUserIDs): %v", err)
  79. }
  80. approvalsWhitelistUsernames, err := models.GetUserNamesByIDs(bp.ApprovalsWhitelistUserIDs)
  81. if err != nil {
  82. log.Error("GetUserNamesByIDs (ApprovalsWhitelistUserIDs): %v", err)
  83. }
  84. pushWhitelistTeams, err := models.GetTeamNamesByID(bp.WhitelistTeamIDs)
  85. if err != nil {
  86. log.Error("GetTeamNamesByID (WhitelistTeamIDs): %v", err)
  87. }
  88. mergeWhitelistTeams, err := models.GetTeamNamesByID(bp.MergeWhitelistTeamIDs)
  89. if err != nil {
  90. log.Error("GetTeamNamesByID (MergeWhitelistTeamIDs): %v", err)
  91. }
  92. approvalsWhitelistTeams, err := models.GetTeamNamesByID(bp.ApprovalsWhitelistTeamIDs)
  93. if err != nil {
  94. log.Error("GetTeamNamesByID (ApprovalsWhitelistTeamIDs): %v", err)
  95. }
  96. return &api.BranchProtection{
  97. BranchName: bp.BranchName,
  98. EnablePush: bp.CanPush,
  99. EnablePushWhitelist: bp.EnableWhitelist,
  100. PushWhitelistUsernames: pushWhitelistUsernames,
  101. PushWhitelistTeams: pushWhitelistTeams,
  102. PushWhitelistDeployKeys: bp.WhitelistDeployKeys,
  103. EnableMergeWhitelist: bp.EnableMergeWhitelist,
  104. MergeWhitelistUsernames: mergeWhitelistUsernames,
  105. MergeWhitelistTeams: mergeWhitelistTeams,
  106. EnableStatusCheck: bp.EnableStatusCheck,
  107. StatusCheckContexts: bp.StatusCheckContexts,
  108. RequiredApprovals: bp.RequiredApprovals,
  109. EnableApprovalsWhitelist: bp.EnableApprovalsWhitelist,
  110. ApprovalsWhitelistUsernames: approvalsWhitelistUsernames,
  111. ApprovalsWhitelistTeams: approvalsWhitelistTeams,
  112. BlockOnRejectedReviews: bp.BlockOnRejectedReviews,
  113. BlockOnOfficialReviewRequests: bp.BlockOnOfficialReviewRequests,
  114. BlockOnOutdatedBranch: bp.BlockOnOutdatedBranch,
  115. DismissStaleApprovals: bp.DismissStaleApprovals,
  116. RequireSignedCommits: bp.RequireSignedCommits,
  117. ProtectedFilePatterns: bp.ProtectedFilePatterns,
  118. Created: bp.CreatedUnix.AsTime(),
  119. Updated: bp.UpdatedUnix.AsTime(),
  120. }
  121. }
  122. // ToTag convert a git.Tag to an api.Tag
  123. func ToTag(repo *models.Repository, t *git.Tag) *api.Tag {
  124. return &api.Tag{
  125. Name: t.Name,
  126. ID: t.ID.String(),
  127. Commit: ToCommitMeta(repo, t),
  128. ZipballURL: util.URLJoin(repo.HTMLURL(), "archive", t.Name+".zip"),
  129. TarballURL: util.URLJoin(repo.HTMLURL(), "archive", t.Name+".tar.gz"),
  130. }
  131. }
  132. // ToVerification convert a git.Commit.Signature to an api.PayloadCommitVerification
  133. func ToVerification(c *git.Commit) *api.PayloadCommitVerification {
  134. verif := models.ParseCommitWithSignature(c)
  135. commitVerification := &api.PayloadCommitVerification{
  136. Verified: verif.Verified,
  137. Reason: verif.Reason,
  138. }
  139. if c.Signature != nil {
  140. commitVerification.Signature = c.Signature.Signature
  141. commitVerification.Payload = c.Signature.Payload
  142. }
  143. if verif.SigningUser != nil {
  144. commitVerification.Signer = &structs.PayloadUser{
  145. Name: verif.SigningUser.Name,
  146. Email: verif.SigningUser.Email,
  147. }
  148. }
  149. return commitVerification
  150. }
  151. // ToPublicKey convert models.PublicKey to api.PublicKey
  152. func ToPublicKey(apiLink string, key *models.PublicKey) *api.PublicKey {
  153. return &api.PublicKey{
  154. ID: key.ID,
  155. Key: key.Content,
  156. URL: apiLink + com.ToStr(key.ID),
  157. Title: key.Name,
  158. Fingerprint: key.Fingerprint,
  159. Created: key.CreatedUnix.AsTime(),
  160. }
  161. }
  162. // ToGPGKey converts models.GPGKey to api.GPGKey
  163. func ToGPGKey(key *models.GPGKey) *api.GPGKey {
  164. subkeys := make([]*api.GPGKey, len(key.SubsKey))
  165. for id, k := range key.SubsKey {
  166. subkeys[id] = &api.GPGKey{
  167. ID: k.ID,
  168. PrimaryKeyID: k.PrimaryKeyID,
  169. KeyID: k.KeyID,
  170. PublicKey: k.Content,
  171. Created: k.CreatedUnix.AsTime(),
  172. Expires: k.ExpiredUnix.AsTime(),
  173. CanSign: k.CanSign,
  174. CanEncryptComms: k.CanEncryptComms,
  175. CanEncryptStorage: k.CanEncryptStorage,
  176. CanCertify: k.CanSign,
  177. }
  178. }
  179. emails := make([]*api.GPGKeyEmail, len(key.Emails))
  180. for i, e := range key.Emails {
  181. emails[i] = ToGPGKeyEmail(e)
  182. }
  183. return &api.GPGKey{
  184. ID: key.ID,
  185. PrimaryKeyID: key.PrimaryKeyID,
  186. KeyID: key.KeyID,
  187. PublicKey: key.Content,
  188. Created: key.CreatedUnix.AsTime(),
  189. Expires: key.ExpiredUnix.AsTime(),
  190. Emails: emails,
  191. SubsKey: subkeys,
  192. CanSign: key.CanSign,
  193. CanEncryptComms: key.CanEncryptComms,
  194. CanEncryptStorage: key.CanEncryptStorage,
  195. CanCertify: key.CanSign,
  196. }
  197. }
  198. // ToGPGKeyEmail convert models.EmailAddress to api.GPGKeyEmail
  199. func ToGPGKeyEmail(email *models.EmailAddress) *api.GPGKeyEmail {
  200. return &api.GPGKeyEmail{
  201. Email: email.Email,
  202. Verified: email.IsActivated,
  203. }
  204. }
  205. // ToHook convert models.Webhook to api.Hook
  206. func ToHook(repoLink string, w *models.Webhook) *api.Hook {
  207. config := map[string]string{
  208. "url": w.URL,
  209. "content_type": w.ContentType.Name(),
  210. }
  211. if w.HookTaskType == models.SLACK {
  212. s := webhook.GetSlackHook(w)
  213. config["channel"] = s.Channel
  214. config["username"] = s.Username
  215. config["icon_url"] = s.IconURL
  216. config["color"] = s.Color
  217. }
  218. return &api.Hook{
  219. ID: w.ID,
  220. Type: w.HookTaskType.Name(),
  221. URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
  222. Active: w.IsActive,
  223. Config: config,
  224. Events: w.EventsArray(),
  225. Updated: w.UpdatedUnix.AsTime(),
  226. Created: w.CreatedUnix.AsTime(),
  227. }
  228. }
  229. // ToGitHook convert git.Hook to api.GitHook
  230. func ToGitHook(h *git.Hook) *api.GitHook {
  231. return &api.GitHook{
  232. Name: h.Name(),
  233. IsActive: h.IsActive,
  234. Content: h.Content,
  235. }
  236. }
  237. // ToDeployKey convert models.DeployKey to api.DeployKey
  238. func ToDeployKey(apiLink string, key *models.DeployKey) *api.DeployKey {
  239. return &api.DeployKey{
  240. ID: key.ID,
  241. KeyID: key.KeyID,
  242. Key: key.Content,
  243. Fingerprint: key.Fingerprint,
  244. URL: apiLink + com.ToStr(key.ID),
  245. Title: key.Name,
  246. Created: key.CreatedUnix.AsTime(),
  247. ReadOnly: key.Mode == models.AccessModeRead, // All deploy keys are read-only.
  248. }
  249. }
  250. // ToOrganization convert models.User to api.Organization
  251. func ToOrganization(org *models.User) *api.Organization {
  252. return &api.Organization{
  253. ID: org.ID,
  254. AvatarURL: org.AvatarLink(),
  255. UserName: org.Name,
  256. FullName: org.FullName,
  257. Description: org.Description,
  258. Website: org.Website,
  259. Location: org.Location,
  260. Visibility: org.Visibility.String(),
  261. RepoAdminChangeTeamAccess: org.RepoAdminChangeTeamAccess,
  262. }
  263. }
  264. // ToTeam convert models.Team to api.Team
  265. func ToTeam(team *models.Team) *api.Team {
  266. if team == nil {
  267. return nil
  268. }
  269. return &api.Team{
  270. ID: team.ID,
  271. Name: team.Name,
  272. Description: team.Description,
  273. IncludesAllRepositories: team.IncludesAllRepositories,
  274. CanCreateOrgRepo: team.CanCreateOrgRepo,
  275. Permission: team.Authorize.String(),
  276. Units: team.GetUnitNames(),
  277. }
  278. }
  279. // ToAnnotatedTag convert git.Tag to api.AnnotatedTag
  280. func ToAnnotatedTag(repo *models.Repository, t *git.Tag, c *git.Commit) *api.AnnotatedTag {
  281. return &api.AnnotatedTag{
  282. Tag: t.Name,
  283. SHA: t.ID.String(),
  284. Object: ToAnnotatedTagObject(repo, c),
  285. Message: t.Message,
  286. URL: util.URLJoin(repo.APIURL(), "git/tags", t.ID.String()),
  287. Tagger: ToCommitUser(t.Tagger),
  288. Verification: ToVerification(c),
  289. }
  290. }
  291. // ToAnnotatedTagObject convert a git.Commit to an api.AnnotatedTagObject
  292. func ToAnnotatedTagObject(repo *models.Repository, commit *git.Commit) *api.AnnotatedTagObject {
  293. return &api.AnnotatedTagObject{
  294. SHA: commit.ID.String(),
  295. Type: string(git.ObjectCommit),
  296. URL: util.URLJoin(repo.APIURL(), "git/commits", commit.ID.String()),
  297. }
  298. }
  299. // ToTopicResponse convert from models.Topic to api.TopicResponse
  300. func ToTopicResponse(topic *models.Topic) *api.TopicResponse {
  301. return &api.TopicResponse{
  302. ID: topic.ID,
  303. Name: topic.Name,
  304. RepoCount: topic.RepoCount,
  305. Created: topic.CreatedUnix.AsTime(),
  306. Updated: topic.UpdatedUnix.AsTime(),
  307. }
  308. }
  309. // ToOAuth2Application convert from models.OAuth2Application to api.OAuth2Application
  310. func ToOAuth2Application(app *models.OAuth2Application) *api.OAuth2Application {
  311. return &api.OAuth2Application{
  312. ID: app.ID,
  313. Name: app.Name,
  314. ClientID: app.ClientID,
  315. ClientSecret: app.ClientSecret,
  316. RedirectURIs: app.RedirectURIs,
  317. Created: app.CreatedUnix.AsTime(),
  318. }
  319. }
  320. // ToCommitStatus converts models.CommitStatus to api.Status
  321. func ToCommitStatus(status *models.CommitStatus) *api.Status {
  322. apiStatus := &api.Status{
  323. Created: status.CreatedUnix.AsTime(),
  324. Updated: status.CreatedUnix.AsTime(),
  325. State: api.StatusState(status.State),
  326. TargetURL: status.TargetURL,
  327. Description: status.Description,
  328. ID: status.Index,
  329. URL: status.APIURL(),
  330. Context: status.Context,
  331. }
  332. if status.CreatorID != 0 {
  333. creator, _ := models.GetUserByID(status.CreatorID)
  334. apiStatus.Creator = ToUser(creator, false, false)
  335. }
  336. return apiStatus
  337. }
  338. // ToLFSLock convert a LFSLock to api.LFSLock
  339. func ToLFSLock(l *models.LFSLock) *api.LFSLock {
  340. return &api.LFSLock{
  341. ID: strconv.FormatInt(l.ID, 10),
  342. Path: l.Path,
  343. LockedAt: l.Created.Round(time.Second),
  344. Owner: &api.LFSLockOwner{
  345. Name: l.Owner.DisplayName(),
  346. },
  347. }
  348. }