Compare commits

..

No commits in common. "oauth2" and "master" have entirely different histories.

12 changed files with 204 additions and 449 deletions

View File

@ -2,7 +2,6 @@ package controller
import (
"code.gitea.io/sdk/gitea"
"fmt"
"gitea-issue/giteaClient"
"gitea-issue/model"
"github.com/gin-gonic/gin"
@ -10,11 +9,11 @@ import (
"github.com/savaki/swag/swagger"
"net/http"
"strconv"
"fmt"
)
func PostIssue(c *gin.Context) {
var issueProxy model.PostCreateIssueProxy
if err := c.BindJSON(&issueProxy); err != nil {
c.AsciiJSON(http.StatusBadRequest, gin.H{
"message": "CREATE_ISSUE_ERROR",
@ -23,10 +22,6 @@ func PostIssue(c *gin.Context) {
return
}
sudo := c.GetHeader("X-Sudo")
if (sudo != "") {
giteaClient.SudoUser(sudo)
}
giteaIssue, err := issueProxy.TransformToGiteaCreateIssueOption()
if err != nil {
c.AsciiJSON(http.StatusBadRequest, gin.H{
@ -44,16 +39,16 @@ func PostIssue(c *gin.Context) {
})
return
}
c.AsciiJSON(http.StatusOK, model.IssueTransformFromGitea(response))
c.AsciiJSON(http.StatusOK, response)
}
func PostIssueSwagger() (*swagger.Endpoint) {
func PostIssueSwagger() (*swagger.Endpoint){
return endpoint.New("post", "/issues", "Create issue",
endpoint.Handler(PostIssue),
endpoint.Description("Post new issue"),
endpoint.Body(model.PostCreateIssueProxy{}, "Issue object", true),
endpoint.Tags("issues"),
endpoint.Response(http.StatusOK, model.GetCreateIssueProxy{}, "Gitea Issue list"),
endpoint.Response(http.StatusOK, gitea.Issue{}, "Gitea Issue list"),
)
}
@ -65,17 +60,16 @@ func GetIssues(c *gin.Context) {
proxyIssues = append(proxyIssues, model.IssueTransformFromGitea(issue))
}
if (err != nil) {
if(err != nil){
c.AbortWithStatus(http.StatusNotFound)
}
c.AsciiJSON(http.StatusOK, proxyIssues)
}
func GetIssuesSwagger() (*swagger.Endpoint) {
func GetIssuesSwagger() (*swagger.Endpoint){
return endpoint.New("get", "/issues", "List project issues",
endpoint.Handler(GetIssues),
endpoint.Description("Get all issues"),
endpoint.Security("token", "USER"),
endpoint.Tags("issues"),
endpoint.Response(http.StatusOK, []model.GetCreateIssueProxy{}, "Gitea Issue list"),
)
@ -91,14 +85,13 @@ func GetIssue(c *gin.Context) {
if err != nil {
c.AbortWithStatus(http.StatusNotFound)
}
c.AsciiJSON(http.StatusOK, model.IssueTransformFromGitea(issue))
c.AsciiJSON(http.StatusOK, issue)
}
func GetIssueSwagger() (*swagger.Endpoint) {
return endpoint.New("get", "/issues/:id", "Get one issue",
func GetIssueSwagger() (*swagger.Endpoint){
return endpoint.New("get", "/issue/:id", "Get one issue",
endpoint.Handler(GetIssue),
endpoint.Description("Get one issue"),
endpoint.Security("token", "USER"),
endpoint.Tags("issues"),
endpoint.Response(http.StatusOK, model.GetCreateIssueProxy{}, "Gitea Issue"),
)
@ -111,79 +104,17 @@ func GetIssueComments(c *gin.Context) {
c.AsciiJSON(http.StatusNotFound, err.Error())
}
issueComments, err := giteaClient.GetIssueComments(issueId)
proxyComments := []model.GetCommentProxy{}
for _, comment := range issueComments {
proxyComments = append(proxyComments, model.CommentTransformFromGitea(comment))
}
if (err != nil) {
c.AbortWithStatus(http.StatusNotFound)
}
c.AsciiJSON(http.StatusOK, proxyComments)
if err != nil {
c.AbortWithStatus(http.StatusNotFound)
}
c.AsciiJSON(http.StatusOK, issueComments)
}
func GetIssueCommentsSwagger() (*swagger.Endpoint) {
return endpoint.New("get", "/issues/:id/comments", "Get issue comments",
endpoint.Handler(GetIssueComments),
func GetIssueCommentsSwagger() (*swagger.Endpoint){
return endpoint.New("get", "/issue/:id/comments", "Get issue comments",
endpoint.Handler(GetIssue),
endpoint.Description("Get issue comments"),
endpoint.Security("token", "USER"),
endpoint.Tags("issues"),
endpoint.Response(http.StatusOK, []gitea.Comment{}, "Gitea issue comments"),
)
}
func PostIssueComment(c *gin.Context) {
var commentProxy model.PostCommentProxy
if err := c.BindJSON(&commentProxy); err != nil {
c.AsciiJSON(http.StatusBadRequest, gin.H{
"message": "CREATE_COMMENT_ERROR",
"error": err.Error(),
})
return
}
issueId, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
fmt.Println(fmt.Sprintf("ParseInt err: %+v", err))
c.AsciiJSON(http.StatusNotFound, err.Error())
}
giteaComment, err := commentProxy.TransformToGiteaComment()
if err != nil {
c.AsciiJSON(http.StatusBadRequest, gin.H{
"message": "CREATE_COMMENT_ERROR",
"error": err.Error(),
})
return
}
sudo := c.GetHeader("X-Sudo")
if (sudo != "") {
giteaClient.SudoUser(sudo)
}
response, err := giteaClient.CreateComment(issueId, giteaComment)
if err != nil {
c.AsciiJSON(http.StatusBadRequest, gin.H{
"message": "CREATE_ISSUE_ERROR",
"error": err.Error(),
})
return
}
c.AsciiJSON(http.StatusOK, model.CommentTransformFromGitea(response))
}
func PostIssueCommentSwagger() (*swagger.Endpoint) {
return endpoint.New("post", "/issues/:id/comments", "Create issue comment",
endpoint.Handler(PostIssueComment),
endpoint.Description("Add issue comment"),
endpoint.Body(model.PostCommentProxy{}, "Comment object", true),
endpoint.Security("token", "USER"),
endpoint.Tags("issues"),
endpoint.Response(http.StatusOK, model.GetCommentProxy{}, "Gitea issue comments"),
)
}

View File

@ -17,7 +17,7 @@ func GetLabels(c *gin.Context) {
c.AsciiJSON(http.StatusOK, labels)
}
func GetLabelsSwagger() (*swagger.Endpoint) {
func GetLabelsSwagger() (*swagger.Endpoint){
return endpoint.New("get", "/labels", "List project labels",
endpoint.Handler(GetLabels),
endpoint.Description("Get all labels"),

View File

@ -1,42 +0,0 @@
package controller
import (
"code.gitea.io/sdk/gitea"
"gitea-issue/giteaClient"
"gitea-issue/model"
"github.com/gin-gonic/gin"
"github.com/savaki/swag/endpoint"
"github.com/savaki/swag/swagger"
"net/http"
)
func PostUser(c *gin.Context) {
var userProxy model.PostUserProxy
if err := c.BindJSON(&userProxy); err != nil {
c.AsciiJSON(http.StatusBadRequest, gin.H{
"message": "CREATE_USER_ERROR",
"error": err.Error(),
})
return
}
response, err := giteaClient.CreateUser(userProxy.TransformToGiteaUser())
if err != nil {
c.AsciiJSON(http.StatusUnprocessableEntity, gin.H{
"message": "CREATE_USER_ERROR",
"error": err.Error(),
})
return
}
c.AsciiJSON(http.StatusOK, response)
}
func PostUserSwagger() (*swagger.Endpoint) {
return endpoint.New("post", "/user", "Create user",
endpoint.Handler(PostUser),
endpoint.Description("Post new user"),
endpoint.Body(model.PostUserProxy{}, "User object", true),
endpoint.Tags("user"),
endpoint.Response(http.StatusOK, gitea.User{}, "Gitea User"),
)
}

View File

@ -5,55 +5,41 @@ import (
"fmt"
)
var (
var(
giteaClient *gitea.Client
giteaOwner string
giteaRepo string
)
func SetUp(config GiteaConfig) {
func SetUp(config GiteaConfig){
giteaClient = gitea.NewClient(config.GiteaUrl, config.GiteaToken)
giteaOwner = config.GiteaOwner
giteaRepo = config.GiteaRepo
}
func GetUserInfo() (*gitea.User, error) {
func GetUserInfo() (*gitea.User, error){
usr, err := giteaClient.GetMyUserInfo()
if (err != nil) {
if(err != nil){
return nil, err
}
return usr, nil
}
func SudoUser(username string) {
giteaClient.SetSudo(username)
}
func GetServerInfo() (string, error) {
ver, err := giteaClient.ServerVersion()
if (err != nil) {
if(err != nil){
return "", err
}
return ver, nil
}
func CreateUser(user gitea.CreateUserOption) (*gitea.User, error) {
giteaUser, err := giteaClient.AdminCreateUser(user)
if (err != nil) {
fmt.Println(fmt.Sprintf("Gitea error: %+v", err.Error()))
return nil, err
}
return giteaUser, nil
}
func GetIssues() ([]*gitea.Issue, error) {
func GetIssues() ([]*gitea.Issue, error){
opt := gitea.ListIssueOption{
Page: 0,
State: "closed",
State: "open",
}
giteaIssues, err := giteaClient.ListRepoIssues(giteaOwner, giteaRepo, opt)
if (err != nil) {
if( err != nil){
fmt.Println(fmt.Sprintf("Gitea error: %+v", err.Error()))
return nil, err
}
@ -62,7 +48,7 @@ func GetIssues() ([]*gitea.Issue, error) {
func GetIssue(issueID int64) (*gitea.Issue, error) {
giteaIssue, err := giteaClient.GetIssue(giteaOwner, giteaRepo, issueID)
if (err != nil) {
if( err != nil){
fmt.Println(fmt.Sprintf("GetIssue gitea error: %+v", err.Error()))
return nil, err
}
@ -71,7 +57,7 @@ func GetIssue(issueID int64) (*gitea.Issue, error) {
func GetIssueComments(issueID int64) ([]*gitea.Comment, error) {
giteaIssueComments, err := giteaClient.ListIssueComments(giteaOwner, giteaRepo, issueID)
if (err != nil) {
if( err != nil){
fmt.Println(fmt.Sprintf("Gitea get isse comments error: %+v", err.Error()))
return nil, err
}
@ -80,28 +66,18 @@ func GetIssueComments(issueID int64) ([]*gitea.Comment, error) {
func GetLabels() ([]*gitea.Label, error) {
giteaLabels, err := giteaClient.ListRepoLabels(giteaOwner, giteaRepo)
if (err != nil) {
if( err != nil){
fmt.Println(fmt.Sprintf("Gitea get labels error: %+v", err.Error()))
return nil, err
}
return giteaLabels, nil
}
func CreateIssue(issue gitea.CreateIssueOption) (*gitea.Issue, error) {
func CreateIssue(issue gitea.CreateIssueOption) (*gitea.Issue, error){
giteaCreateIssue, err := giteaClient.CreateIssue(giteaOwner, giteaRepo, issue)
if (err != nil) {
if( err != nil){
fmt.Println(fmt.Sprintf("Gitea get labels error: %+v", err.Error()))
return nil, err
}
return giteaCreateIssue, nil
}
func CreateComment(id int64, option gitea.CreateIssueCommentOption) (*gitea.Comment, error) {
giteaComment, err := giteaClient.CreateIssueComment(giteaOwner, giteaRepo, id, option)
if (err != nil) {
fmt.Println(fmt.Sprintf("Gitea create comment error: %+v", err.Error()))
return nil, err
}
return giteaComment, nil
}

48
main.go
View File

@ -4,27 +4,37 @@ import (
"fmt"
"gitea-issue/controller"
"gitea-issue/giteaClient"
"gitea-issue/proxy"
"gitea-issue/security"
"github.com/caarlos0/env"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
"github.com/savaki/swag"
"github.com/savaki/swag/swagger"
ginSwagger "github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
"net/http"
"strconv"
"github.com/savaki/swag"
"github.com/savaki/swag/swagger"
)
var (
db *gorm.DB
giteaConfig giteaClient.GiteaConfig
proxyConfig proxy.ProxyConfig
proxyConfig ProxyConfig
)
func init() {
type ProxyConfig struct {
ProjectOrigin string `env:"PROJECT_ORIGIN,required"`
}
func init() {
//open a db connection
var err error
db, err := gorm.Open("sqlite3", "./database.db")
if err != nil {
panic("failed to connect database")
}
if err := env.Parse(&giteaConfig); err != nil {
panic(fmt.Sprintf("ENV error: %+v", err.Error()))
}
@ -33,8 +43,7 @@ func init() {
}
giteaClient.SetUp(giteaConfig)
proxy.SetUp(proxyConfig)
db.AutoMigrate(&userModel{})
}
func main() {
@ -44,7 +53,6 @@ func main() {
config.AllowOrigins = []string{proxyConfig.ProjectOrigin}
router.Use(gin.Logger())
router.Use(cors.New(config))
router.Use(gin.Recovery())
proxyApi := swag.New(
swag.Title("Gitea issues proxy"),
@ -54,34 +62,37 @@ func main() {
swag.Tag("issues", "Gitea issues proxy endpoints"),
swag.Tag("labels", "Gites labels for issue"),
swag.Endpoints(
controller.PostUserSwagger(),
controller.PostIssueSwagger(),
controller.PostIssueCommentSwagger(),
controller.GetIssuesSwagger(),
controller.GetIssueSwagger(),
controller.GetIssueCommentsSwagger(),
controller.GetLabelsSwagger()),
)
authorizedApi := router.Group("/", security.BearerToken())
proxyApi.Walk(func(path string, endpoint *swagger.Endpoint) {
h := endpoint.Handler.(func(c *gin.Context))
path = swag.ColonPath(path)
authorizedApi.Handle(endpoint.Method, path, h)
router.Handle(endpoint.Method, path, h)
})
docs := router.Group("/")
docs.GET("/swagger.json", gin.WrapH(proxyApi.Handler(true)))
router.GET("/swagger.json", gin.WrapH(proxyApi.Handler(true)))
url := ginSwagger.URL("/swagger.json")
docs.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, url))
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, url))
_ = router.Run()
}
type (
userModel struct {
gorm.Model
Email string `json:"email"`
Token int `json:"token"`
}
)
func getIssues(c *gin.Context) {
issues, err := giteaClient.GetIssues();
if (err != nil) {
if(err != nil){
c.AbortWithStatus(http.StatusNotFound)
}
c.AsciiJSON(http.StatusOK, issues)
@ -120,3 +131,4 @@ func getLabels(c *gin.Context) {
}
c.AsciiJSON(http.StatusOK, labels)
}

View File

@ -1,35 +0,0 @@
package model
import (
"code.gitea.io/sdk/gitea"
"time"
)
type GetCommentProxy struct {
Id int64 `json:"id"`
Body string `json:"body"`
OriginalAuthor string `json:"original_author"`
CreatedAt time.Time `json:"created_at"`
}
type PostCommentProxy struct {
Body string `json:"body"`
}
func (c PostCommentProxy) TransformToGiteaComment() (gitea.CreateIssueCommentOption, error) {
giteaObject := gitea.CreateIssueCommentOption{
Body: c.Body,
}
return giteaObject, nil
}
func CommentTransformFromGitea(comment *gitea.Comment) (GetCommentProxy) {
giteaComment := GetCommentProxy{
Id: comment.ID,
Body: comment.Body,
OriginalAuthor: comment.OriginalAuthor,
CreatedAt: comment.Created,
}
return giteaComment
}

View File

@ -7,7 +7,6 @@ import (
)
type GetCreateIssueProxy struct {
Id int64 `json:"id"`
Title string `json:"title"`
Body string `json:"body"`
Labels []*gitea.Label `json:"labels"`
@ -20,14 +19,14 @@ type PostCreateIssueProxy struct {
Labels []*gitea.Label `json:"labels"`
}
func (c PostCreateIssueProxy) TransformToGiteaCreateIssueOption() (gitea.CreateIssueOption, error) {
func (c PostCreateIssueProxy) TransformToGiteaCreateIssueOption() (gitea.CreateIssueOption, error){
giteaUser, err := giteaClient.GetUserInfo()
if (err != nil) {
if( err != nil){
return gitea.CreateIssueOption{}, err;
}
labels := []int64{}
for _, label := range c.Labels {
for _, label := range c.Labels{
labels = append(labels, label.ID)
}
giteaObject := gitea.CreateIssueOption{
@ -44,7 +43,6 @@ func (c PostCreateIssueProxy) TransformToGiteaCreateIssueOption() (gitea.CreateI
func IssueTransformFromGitea(issue *gitea.Issue) (GetCreateIssueProxy) {
giteaIssue := GetCreateIssueProxy{
Id: issue.Index,
Title: issue.Title,
Body: issue.Body,
Labels: issue.Labels,

View File

@ -1,47 +0,0 @@
package model
import (
"code.gitea.io/sdk/gitea"
"golang.org/x/text/transform"
"golang.org/x/text/unicode/norm"
"math/rand"
"unicode"
)
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456!@#$%")
func randSeq(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
type PostUserProxy struct {
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
func isMn(r rune) bool {
return unicode.Is(unicode.Mn, r)
}
func (c PostUserProxy) TransformToGiteaUser() (gitea.CreateUserOption) {
t := transform.Chain(norm.NFD, transform.RemoveFunc(isMn), norm.NFC)
username, _, _ := transform.String(t, c.FirstName+c.LastName)
giteaObject := gitea.CreateUserOption{
SourceID: 0,
LoginName: c.Email,
Username: username,
FullName: c.FirstName + " " + c.LastName,
Email: c.Email,
Password: randSeq(12),
MustChangePassword: nil,
SendNotify: false,
}
return giteaObject
}

View File

@ -1,9 +0,0 @@
package proxy
var (
Bearer string
)
func SetUp(config ProxyConfig) {
Bearer = config.ProxyToken
}

View File

@ -1,6 +0,0 @@
package proxy
type ProxyConfig struct {
ProjectOrigin string `env:"PROJECT_ORIGIN,required"`
ProxyToken string `env:"PROXY_TOKEN,required"`
}

View File

@ -1,23 +0,0 @@
package security
import (
"gitea-issue/proxy"
"github.com/gin-gonic/gin"
"net/http"
"strings"
)
func BearerToken() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if (token == "") {
c.AbortWithStatus(http.StatusBadRequest)
}
var tokenArr []string
tokenArr = strings.Split(token, " ")
if (tokenArr[1] != proxy.Bearer) {
c.AbortWithStatus(http.StatusUnauthorized)
}
c.Next()
}
}