feat: add endpoint to generate a long-lived token to use inside ci actions
This commit is contained in:
parent
340240575f
commit
a1bc451d3e
|
@ -1,18 +1,27 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"git.lumeweb.com/LumeWeb/gitea-github-proxy/config"
|
||||
"git.lumeweb.com/LumeWeb/gitea-github-proxy/db/model"
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/gorilla/mux"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type appApi struct {
|
||||
config *config.Config
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func newAppApi(cfg *config.Config, logger *zap.Logger) *appApi {
|
||||
return &appApi{config: cfg, logger: logger}
|
||||
func newAppApi(cfg *config.Config, db *gorm.DB, logger *zap.Logger) *appApi {
|
||||
return &appApi{config: cfg, db: db, logger: logger}
|
||||
}
|
||||
|
||||
func (a *appApi) handlerNewAppInstall(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -21,16 +30,88 @@ func (a *appApi) handlerNewAppInstall(w http.ResponseWriter, r *http.Request) {
|
|||
w.Header().Set("Content-Type", "text/plain")
|
||||
}
|
||||
|
||||
func (a *appApi) handlerAppGetAccessToken(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
now := time.Now().Add(-30 * time.Second)
|
||||
expirationTime := now.Add(100 * 365 * 24 * time.Hour)
|
||||
|
||||
appName := mux.Vars(r)["app"]
|
||||
|
||||
appRecord := &model.Apps{}
|
||||
appRecord.Name = appName
|
||||
|
||||
if err := a.db.First(appRecord).Error; err != nil {
|
||||
http.Error(w, "Failed to find app", http.StatusNotFound)
|
||||
a.logger.Error("Failed to find app", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
block, _ := pem.Decode([]byte(appRecord.PrivateKey))
|
||||
if block == nil {
|
||||
http.Error(w, "Failed to parse PEM block containing the key", http.StatusInternalServerError)
|
||||
a.logger.Error("Failed to parse PEM block containing the key")
|
||||
return
|
||||
}
|
||||
|
||||
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to parse DER encoded private key", http.StatusInternalServerError)
|
||||
a.logger.Error("Failed to parse DER encoded private key", zap.Error(err))
|
||||
}
|
||||
|
||||
claims := jwt.MapClaims{
|
||||
"iss": appRecord.ID,
|
||||
"iat": now.Unix(),
|
||||
"exp": expirationTime,
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
||||
|
||||
signedToken, err := token.SignedString(privateKey)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to sign token", http.StatusInternalServerError)
|
||||
a.logger.Error("Failed to sign token", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
out := struct {
|
||||
Token string `json:"token"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
}{
|
||||
Token: signedToken,
|
||||
ExpiresAt: expirationTime,
|
||||
}
|
||||
|
||||
a.respond(w, http.StatusCreated, out)
|
||||
}
|
||||
|
||||
func (r appApi) respond(w http.ResponseWriter, status int, data interface{}) {
|
||||
jsonData, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to marshal response", http.StatusInternalServerError)
|
||||
r.logger.Error("Failed to marshal response", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
if data != nil {
|
||||
_, _ = w.Write(jsonData)
|
||||
}
|
||||
}
|
||||
|
||||
func setupAppRoutes(params RouteParams) {
|
||||
logger := params.Logger
|
||||
cfg := params.Config
|
||||
db := params.Db
|
||||
r := params.R
|
||||
|
||||
appApi := newAppApi(cfg, logger)
|
||||
appApi := newAppApi(cfg, db, logger)
|
||||
appRouter := r.PathPrefix("/apps").Subrouter()
|
||||
|
||||
appRouter.Use(giteaOauthVerifyMiddleware(cfg))
|
||||
appRouter.Use(requireAuthMiddleware(cfg))
|
||||
|
||||
appRouter.HandleFunc("/{app}/installations/new", appApi.handlerNewAppInstall).Methods("GET")
|
||||
appRouter.HandleFunc("/{app}/access_token", appApi.handlerAppGetAccessToken).Methods("GET")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue