2022-09-04 09:38:10 +00:00
package main
import (
"fmt"
"log"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
func declareAPIAuthRepositoriesRoutes ( router * gin . RouterGroup ) {
router . GET ( "/repositories" , func ( c * gin . Context ) {
var u * User
if user , ok := c . Get ( "user" ) ; ok {
u = user . ( * User )
} else {
u = c . MustGet ( "LoggedUser" ) . ( * User )
}
repositories , err := u . GetRepositories ( )
if err != nil {
log . Println ( "Unable to GetRepositories:" , err )
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Unable to retrieve your repositories. Please try again in a few moment." } )
return
}
c . JSON ( http . StatusOK , repositories )
} )
router . POST ( "/repositories" , func ( c * gin . Context ) {
var u * User
if user , ok := c . Get ( "user" ) ; ok {
u = user . ( * User )
} else {
u = c . MustGet ( "LoggedUser" ) . ( * User )
}
var repository Repository
if err := c . ShouldBindJSON ( & repository ) ; err != nil {
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : err . Error ( ) } )
return
}
2022-09-04 15:59:36 +00:00
var w * Work
if work , ok := c . Get ( "work" ) ; ok {
w = work . ( * Work )
} else if repository . IdWork > 0 {
var err error
w , err = getWork ( int ( repository . IdWork ) )
if err != nil {
c . AbortWithStatusJSON ( http . StatusNotFound , gin . H { "errmsg" : "Unable to find the given work identifier." } )
return
}
} else {
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : "Unable to find the given work identifier." } )
return
}
2022-09-04 09:38:10 +00:00
k , err := u . NewRepository ( w , repository . URI )
if err != nil {
log . Println ( "Unable to NewRepository:" , err )
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : "Unable to register your public repository. Please try again in a few moment." } )
return
}
c . JSON ( http . StatusOK , k )
} )
repositoriesRoutes := router . Group ( "/repositories/:rid" )
repositoriesRoutes . Use ( repositoryHandler )
repositoriesRoutes . GET ( "" , func ( c * gin . Context ) {
repo := c . MustGet ( "repository" ) . ( * Repository )
c . JSON ( http . StatusOK , repo )
} )
repositoriesRoutes . PUT ( "" , func ( c * gin . Context ) {
current := c . MustGet ( "repository" ) . ( * Repository )
var new Repository
if err := c . ShouldBindJSON ( & new ) ; err != nil {
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : err . Error ( ) } )
return
}
new . Id = current . Id
u := c . MustGet ( "LoggedUser" ) . ( * User )
if new . IdUser != current . IdUser && ! u . IsAdmin {
c . AbortWithStatusJSON ( http . StatusForbidden , gin . H { "errmsg" : "Operation not allowed." } )
return
}
if repository , err := new . Update ( ) ; err != nil {
log . Println ( "Unable to Update repository:" , err )
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : fmt . Sprintf ( "An error occurs during repository updation: %s" , err . Error ( ) ) } )
return
} else {
c . JSON ( http . StatusOK , repository )
}
} )
repositoriesRoutes . DELETE ( "" , func ( c * gin . Context ) {
repository := c . MustGet ( "repository" ) . ( * Repository )
if _ , err := repository . Delete ( ) ; err != nil {
log . Println ( "Unable to Delete repository:" , err )
c . AbortWithStatusJSON ( http . StatusInternalServerError , gin . H { "errmsg" : fmt . Sprintf ( "An error occurs during repository deletion: %s" , err . Error ( ) ) } )
return
} else {
c . JSON ( http . StatusOK , nil )
}
} )
}
func repositoryHandler ( c * gin . Context ) {
var u * User
if user , ok := c . Get ( "user" ) ; ok {
u = user . ( * User )
} else {
u = c . MustGet ( "LoggedUser" ) . ( * User )
}
if rid , err := strconv . Atoi ( string ( c . Param ( "rid" ) ) ) ; err != nil {
c . AbortWithStatusJSON ( http . StatusBadRequest , gin . H { "errmsg" : "Bad repository identifier." } )
return
} else if u . IsAdmin {
if repository , err := getRepository ( rid ) ; err != nil {
c . AbortWithStatusJSON ( http . StatusNotFound , gin . H { "errmsg" : "Repository not found." } )
return
} else {
c . Set ( "repository" , repository )
c . Next ( )
}
} else if repository , err := u . getRepository ( rid ) ; err != nil {
c . AbortWithStatusJSON ( http . StatusNotFound , gin . H { "errmsg" : "Repository not found." } )
return
} else {
c . Set ( "repository" , repository )
c . Next ( )
}
}
type Repository struct {
Id int64 ` json:"id" `
IdUser int64 ` json:"id_user" `
IdWork int64 ` json:"id_work" `
URI string ` json:"uri" `
LastCheck * time . Time ` json:"last_check" `
}
func ( u * User ) GetRepositories ( ) ( repositories [ ] * Repository , err error ) {
if rows , errr := DBQuery ( "SELECT id_repository, id_user, id_work, uri, last_check FROM user_work_repositories WHERE id_user=?" , u . Id ) ; errr != nil {
return nil , errr
} else {
defer rows . Close ( )
for rows . Next ( ) {
var repo Repository
if err = rows . Scan ( & repo . Id , & repo . IdUser , & repo . IdWork , & repo . URI , & repo . LastCheck ) ; err != nil {
return
}
repositories = append ( repositories , & repo )
}
if err = rows . Err ( ) ; err != nil {
return
}
return
}
}
func getRepository ( id int ) ( r * Repository , err error ) {
r = new ( Repository )
2022-09-04 15:59:36 +00:00
err = DBQueryRow ( "SELECT id_repository, id_user, id_work, uri, last_check FROM user_work_repositories WHERE id_repository=?" , id ) . Scan ( & r . Id , & r . IdUser , & r . IdWork , & r . URI , & r . LastCheck )
2022-09-04 09:38:10 +00:00
return
}
func ( u * User ) getRepository ( id int ) ( r * Repository , err error ) {
r = new ( Repository )
2022-09-04 15:59:36 +00:00
err = DBQueryRow ( "SELECT id_repository, id_user, id_work, uri, last_check FROM user_work_repositories WHERE id_repository=? AND id_user=?" , id , u . Id ) . Scan ( & r . Id , & r . IdUser , & r . IdWork , & r . URI , & r . LastCheck )
2022-09-04 09:38:10 +00:00
return
}
func ( u * User ) NewRepository ( w * Work , uri string ) ( * Repository , error ) {
if res , err := DBExec ( "INSERT INTO user_work_repositories (id_user, id_work, uri) VALUES (?, ?, ?)" , u . Id , w . Id , uri ) ; err != nil {
return nil , err
} else if rid , err := res . LastInsertId ( ) ; err != nil {
return nil , err
} else {
return & Repository { rid , u . Id , w . Id , uri , nil } , nil
}
}
func ( r * Repository ) Update ( ) ( * Repository , error ) {
if _ , err := DBExec ( "UPDATE user_work_repositories SET id_user = ?, id_work = ?, uri = ?, last_check = ? WHERE id_repository = ?" , r . IdUser , r . IdWork , r . URI , r . LastCheck , r . Id ) ; err != nil {
return nil , err
} else {
return r , err
}
}
func ( r Repository ) Delete ( ) ( int64 , error ) {
if res , err := DBExec ( "DELETE FROM user_work_repositories WHERE id_repository = ?" , r . Id ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}
func ClearRepositories ( ) ( int64 , error ) {
if res , err := DBExec ( "DELETE FROM user_work_repositories" ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}