diff --git a/src/main/scala/gitbucket/core/api/AddACollaborator.scala b/src/main/scala/gitbucket/core/api/AddACollaborator.scala new file mode 100644 index 0000000..05b1768 --- /dev/null +++ b/src/main/scala/gitbucket/core/api/AddACollaborator.scala @@ -0,0 +1,9 @@ +package gitbucket.core.api + +case class AddACollaborator(permission: String) { + val role: String = permission match { + case "admin" => "ADMIN" + case "push" => "DEVELOPER" + case "pull" => "GUEST" + } +} diff --git a/src/main/scala/gitbucket/core/api/ApiGroup.scala b/src/main/scala/gitbucket/core/api/ApiGroup.scala new file mode 100644 index 0000000..5af6d4f --- /dev/null +++ b/src/main/scala/gitbucket/core/api/ApiGroup.scala @@ -0,0 +1,20 @@ +package gitbucket.core.api + +import java.util.Date + +import gitbucket.core.model.Account + +case class ApiGroup(login: String, description: Option[String], created_at: Date) { + val id = 0 // dummy id + val url = ApiPath(s"/api/v3/orgs/${login}") + val html_url = ApiPath(s"/${login}") + val avatar_url = ApiPath(s"/${login}/_avatar") +} + +object ApiGroup { + def apply(group: Account): ApiGroup = ApiGroup( + login = group.userName, + description = group.description, + created_at = group.registeredDate + ) +} diff --git a/src/main/scala/gitbucket/core/api/CreateAUser.scala b/src/main/scala/gitbucket/core/api/CreateAUser.scala new file mode 100644 index 0000000..f2cd9f0 --- /dev/null +++ b/src/main/scala/gitbucket/core/api/CreateAUser.scala @@ -0,0 +1,11 @@ +package gitbucket.core.api + +case class CreateAUser( + login: String, + password: String, + email: String, + fullName: Option[String], + isAdmin: Option[Boolean], + description: Option[String], + url: Option[String] +) diff --git a/src/main/scala/gitbucket/core/api/JsonFormat.scala b/src/main/scala/gitbucket/core/api/JsonFormat.scala index 8579926..96fbd69 100644 --- a/src/main/scala/gitbucket/core/api/JsonFormat.scala +++ b/src/main/scala/gitbucket/core/api/JsonFormat.scala @@ -24,6 +24,7 @@ }, { case x: Date => JString(OffsetDateTime.ofInstant(x.toInstant, ZoneId.of("UTC")).format(parserISO)) } ) ) + FieldSerializer[ApiUser]() + + FieldSerializer[ApiGroup]() + FieldSerializer[ApiPullRequest]() + FieldSerializer[ApiRepository]() + FieldSerializer[ApiCommitListItem.Parent]() + diff --git a/src/main/scala/gitbucket/core/controller/api/ApiIssueControllerBase.scala b/src/main/scala/gitbucket/core/controller/api/ApiIssueControllerBase.scala index 6fe0632..12f44be 100644 --- a/src/main/scala/gitbucket/core/controller/api/ApiIssueControllerBase.scala +++ b/src/main/scala/gitbucket/core/controller/api/ApiIssueControllerBase.scala @@ -5,7 +5,7 @@ import gitbucket.core.service.{AccountService, IssueCreationService, IssuesService, MilestonesService} import gitbucket.core.service.IssuesService.IssueSearchCondition import gitbucket.core.service.PullRequestService.PullRequestLimit -import gitbucket.core.util.{ReadableUsersAuthenticator, ReferrerAuthenticator, RepositoryName} +import gitbucket.core.util.{ReadableUsersAuthenticator, ReferrerAuthenticator, RepositoryName, UsersAuthenticator} import gitbucket.core.util.Implicits._ trait ApiIssueControllerBase extends ControllerBase { @@ -18,6 +18,7 @@ /* * i. List issues * https://developer.github.com/v3/issues/#list-issues + * requested: 1743 */ /* diff --git a/src/main/scala/gitbucket/core/controller/api/ApiOrganizationControllerBase.scala b/src/main/scala/gitbucket/core/controller/api/ApiOrganizationControllerBase.scala index 0b64c9f..85ca93c 100644 --- a/src/main/scala/gitbucket/core/controller/api/ApiOrganizationControllerBase.scala +++ b/src/main/scala/gitbucket/core/controller/api/ApiOrganizationControllerBase.scala @@ -1,26 +1,36 @@ package gitbucket.core.controller.api -import gitbucket.core.api.{ApiRepository, ApiUser, JsonFormat} +import gitbucket.core.api.{ApiGroup, ApiRepository, ApiUser, JsonFormat} import gitbucket.core.controller.ControllerBase import gitbucket.core.service.{AccountService, RepositoryService} import gitbucket.core.util.Implicits._ +import gitbucket.core.util.UsersAuthenticator trait ApiOrganizationControllerBase extends ControllerBase { - self: RepositoryService with AccountService => + self: RepositoryService with AccountService with UsersAuthenticator => /* * i. List your organizations * https://developer.github.com/v3/orgs/#list-your-organizations */ + get("/api/v3/user/orgs")(usersOnly { + JsonFormat(getGroupsByUserName(context.loginAccount.get.userName).flatMap(getAccountByUserName(_)).map(ApiGroup(_))) + }) /* * ii. List all organizations * https://developer.github.com/v3/orgs/#list-all-organizations */ + get("/api/v3/organizations") { + JsonFormat(getAllUsers(false, true).filter(a => a.isGroupAccount).map(ApiGroup(_))) + } /* * iii. List user organizations * https://developer.github.com/v3/orgs/#list-user-organizations */ + get("/api/v3/users/:userName/orgs") { + JsonFormat(getGroupsByUserName(params("userName")).flatMap(getAccountByUserName(_)).map(ApiGroup(_))) + } /** * iv. Get an organization @@ -28,7 +38,26 @@ */ get("/api/v3/orgs/:groupName") { getAccountByUserName(params("groupName")).filter(account => account.isGroupAccount).map { account => - JsonFormat(ApiUser(account)) + JsonFormat(ApiGroup(account)) } getOrElse NotFound() } + + /* + * v. Edit an organization + * https://developer.github.com/v3/orgs/#edit-an-organization + */ + + /* + * ghe: i. Create an organization + * https://developer.github.com/enterprise/2.14/v3/enterprise-admin/orgs/#create-an-organization + */ + + /* + * ghe: ii. Rename an organization + * https://developer.github.com/enterprise/2.14/v3/enterprise-admin/orgs/#rename-an-organization + */ + + /* + * should implement delete an organization API? + */ } diff --git a/src/main/scala/gitbucket/core/controller/api/ApiPullRequestControllerBase.scala b/src/main/scala/gitbucket/core/controller/api/ApiPullRequestControllerBase.scala index fe66183..d2d8357 100644 --- a/src/main/scala/gitbucket/core/controller/api/ApiPullRequestControllerBase.scala +++ b/src/main/scala/gitbucket/core/controller/api/ApiPullRequestControllerBase.scala @@ -100,6 +100,7 @@ /* * iv. Create a pull request * https://developer.github.com/v3/pulls/#create-a-pull-request + * requested #1843 */ /* diff --git a/src/main/scala/gitbucket/core/controller/api/ApiRepositoryCollaboratorControllerBase.scala b/src/main/scala/gitbucket/core/controller/api/ApiRepositoryCollaboratorControllerBase.scala index 402b7a3..f8fe1e5 100644 --- a/src/main/scala/gitbucket/core/controller/api/ApiRepositoryCollaboratorControllerBase.scala +++ b/src/main/scala/gitbucket/core/controller/api/ApiRepositoryCollaboratorControllerBase.scala @@ -1,12 +1,13 @@ package gitbucket.core.controller.api -import gitbucket.core.api.{ApiUser, JsonFormat} +import gitbucket.core.api.{AddACollaborator, ApiUser, JsonFormat} import gitbucket.core.controller.ControllerBase import gitbucket.core.service.{AccountService, RepositoryService} import gitbucket.core.util.Implicits._ -import gitbucket.core.util.ReferrerAuthenticator +import gitbucket.core.util.{OwnerAuthenticator, ReferrerAuthenticator} +import org.scalatra.NoContent trait ApiRepositoryCollaboratorControllerBase extends ControllerBase { - self: RepositoryService with AccountService with ReferrerAuthenticator => + self: RepositoryService with AccountService with ReferrerAuthenticator with OwnerAuthenticator => /* * i. List collaborators @@ -31,10 +32,24 @@ /* * iv. Add user as a collaborator * https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator + * requested #1586 */ + put("/api/v3/repos/:owner/:repository/collaborators/:userName")(ownerOnly { repository => + for { + data <- extractFromJsonBody[AddACollaborator] + } yield { + addCollaborator(repository.owner, repository.name, params("userName"), data.role) + NoContent() + } + }) /* - * v. Remove user as a collaborator - * https://developer.github.com/v3/repos/collaborators/#remove-user-as-a-collaborator - */ + * v. Remove user as a collaborator + * https://developer.github.com/v3/repos/collaborators/#remove-user-as-a-collaborator + * requested #1586 + */ + delete("/api/v3/repos/:owner/:repository/collaborators/:userName")(ownerOnly { repository => + removeCollaborator(repository.owner, repository.name, params("userName")) + NoContent() + }) } diff --git a/src/main/scala/gitbucket/core/controller/api/ApiRepositoryContentsControllerBase.scala b/src/main/scala/gitbucket/core/controller/api/ApiRepositoryContentsControllerBase.scala index c1d128b..d0dae95 100644 --- a/src/main/scala/gitbucket/core/controller/api/ApiRepositoryContentsControllerBase.scala +++ b/src/main/scala/gitbucket/core/controller/api/ApiRepositoryContentsControllerBase.scala @@ -103,16 +103,19 @@ /* * iii. Create a file * https://developer.github.com/v3/repos/contents/#create-a-file + * requested #2112 */ /* * iv. Update a file * https://developer.github.com/v3/repos/contents/#update-a-file + * requested #2112 */ /* * v. Delete a file * https://developer.github.com/v3/repos/contents/#delete-a-file + * should be implemented */ /* diff --git a/src/main/scala/gitbucket/core/controller/api/ApiUserControllerBase.scala b/src/main/scala/gitbucket/core/controller/api/ApiUserControllerBase.scala index 7c596fd..d5bbbd8 100644 --- a/src/main/scala/gitbucket/core/controller/api/ApiUserControllerBase.scala +++ b/src/main/scala/gitbucket/core/controller/api/ApiUserControllerBase.scala @@ -1,11 +1,12 @@ package gitbucket.core.controller.api -import gitbucket.core.api.{ApiUser, JsonFormat} +import gitbucket.core.api.{ApiUser, CreateAUser, JsonFormat} import gitbucket.core.controller.ControllerBase import gitbucket.core.service.{AccountService, RepositoryService} +import gitbucket.core.util.AdminAuthenticator import gitbucket.core.util.Implicits._ trait ApiUserControllerBase extends ControllerBase { - self: RepositoryService with AccountService => + self: RepositoryService with AccountService with AdminAuthenticator => /** * i. Get a single user @@ -39,8 +40,37 @@ */ /* - * v. Get all users - * https://developer.github.com/v3/users/#get-all-users - */ + * v. Get all users + * https://developer.github.com/v3/users/#get-all-users + */ + /* + * ghe: i. Create a new use + * https://developer.github.com/enterprise/2.14/v3/enterprise-admin/users/#create-a-new-user + */ + post("/api/v3/admin/users")(adminOnly { + for { + data <- extractFromJsonBody[CreateAUser] + } yield { + val user = createAccount( + data.login, + data.password, + data.fullName.getOrElse(data.login), + data.email, + data.isAdmin.getOrElse(false), + data.description, + data.url + ) + JsonFormat(ApiUser(user)) + } + }) + + /* + * ghe: vii. Suspend a user + * https://developer.github.com/enterprise/2.14/v3/enterprise-admin/users/#suspend-a-user + */ + /* + * ghe: vii. Unsuspend a user + * https://developer.github.com/enterprise/2.14/v3/enterprise-admin/users/#unsuspend-a-user + */ } diff --git a/src/main/scala/gitbucket/core/service/AccountService.scala b/src/main/scala/gitbucket/core/service/AccountService.scala index ea851b1..f5f9cdb 100644 --- a/src/main/scala/gitbucket/core/service/AccountService.scala +++ b/src/main/scala/gitbucket/core/service/AccountService.scala @@ -163,8 +163,8 @@ isAdmin: Boolean, description: Option[String], url: Option[String] - )(implicit s: Session): Unit = - Accounts insert Account( + )(implicit s: Session): Account = { + val account = Account( userName = userName, password = password, fullName = fullName, @@ -179,6 +179,9 @@ isRemoved = false, description = description ) + Accounts insert account + account + } def updateAccount(account: Account)(implicit s: Session): Unit = Accounts diff --git a/src/main/scala/gitbucket/core/service/RepositoryService.scala b/src/main/scala/gitbucket/core/service/RepositoryService.scala index 08f077d..e5295ed 100644 --- a/src/main/scala/gitbucket/core/service/RepositoryService.scala +++ b/src/main/scala/gitbucket/core/service/RepositoryService.scala @@ -561,6 +561,14 @@ Collaborators insert Collaborator(userName, repositoryName, collaboratorName, role) /** + * Remove specified collaborator from the repository. + */ + def removeCollaborator(userName: String, repositoryName: String, collaboratorName: String)( + implicit s: Session + ): Unit = + Collaborators.filter(_.byPrimaryKey(userName, repositoryName, collaboratorName)).delete + + /** * Remove all collaborators from the repository. */ def removeCollaborators(userName: String, repositoryName: String)(implicit s: Session): Unit =