Add some GitHub compatible API, close #2079

This commit is contained in:
KOUNOIKE
2018-10-08 23:23:18 +09:00
parent 06b2bf5333
commit f42ff60772
12 changed files with 148 additions and 17 deletions

View File

@@ -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"
}
}

View File

@@ -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
)
}

View File

@@ -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]
)

View File

@@ -24,6 +24,7 @@ object JsonFormat {
}, { case x: Date => JString(OffsetDateTime.ofInstant(x.toInstant, ZoneId.of("UTC")).format(parserISO)) }
)
) + FieldSerializer[ApiUser]() +
FieldSerializer[ApiGroup]() +
FieldSerializer[ApiPullRequest]() +
FieldSerializer[ApiRepository]() +
FieldSerializer[ApiCommitListItem.Parent]() +

View File

@@ -5,7 +5,7 @@ import gitbucket.core.model.{Account, Issue}
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 @@ trait ApiIssueControllerBase extends ControllerBase {
/*
* i. List issues
* https://developer.github.com/v3/issues/#list-issues
* requested: 1743
*/
/*

View File

@@ -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 @@ trait ApiOrganizationControllerBase extends ControllerBase {
*/
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?
*/
}

View File

@@ -100,6 +100,7 @@ trait ApiPullRequestControllerBase extends ControllerBase {
/*
* iv. Create a pull request
* https://developer.github.com/v3/pulls/#create-a-pull-request
* requested #1843
*/
/*

View File

@@ -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 @@ trait ApiRepositoryCollaboratorControllerBase extends ControllerBase {
/*
* 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()
})
}

View File

@@ -103,16 +103,19 @@ trait ApiRepositoryContentsControllerBase extends ControllerBase {
/*
* 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
*/
/*

View File

@@ -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 @@ trait ApiUserControllerBase extends ControllerBase {
*/
/*
* 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
*/
}

View File

@@ -163,8 +163,8 @@ trait AccountService {
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 @@ trait AccountService {
isRemoved = false,
description = description
)
Accounts insert account
account
}
def updateAccount(account: Account)(implicit s: Session): Unit =
Accounts

View File

@@ -560,6 +560,14 @@ trait RepositoryService { self: AccountService =>
): Unit =
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.
*/