mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 06:29:02 +08:00
Add APIs for PAT
This commit is contained in:
parent
995e45713c
commit
388ef9453c
@ -122,6 +122,11 @@ func (ah *APIHandler) RegisterRoutes(router *mux.Router) {
|
|||||||
router.HandleFunc("/api/v1/traces/{traceId}", baseapp.ViewAccess(ah.searchTraces)).Methods(http.MethodGet)
|
router.HandleFunc("/api/v1/traces/{traceId}", baseapp.ViewAccess(ah.searchTraces)).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v2/metrics/query_range", baseapp.ViewAccess(ah.queryRangeMetricsV2)).Methods(http.MethodPost)
|
router.HandleFunc("/api/v2/metrics/query_range", baseapp.ViewAccess(ah.queryRangeMetricsV2)).Methods(http.MethodPost)
|
||||||
|
|
||||||
|
// PAT APIs
|
||||||
|
router.HandleFunc("/api/v1/pat", baseapp.SelfAccess(ah.createPAT)).Methods(http.MethodPost)
|
||||||
|
router.HandleFunc("/api/v1/pat", baseapp.SelfAccess(ah.getPATs)).Methods(http.MethodGet)
|
||||||
|
router.HandleFunc("/api/v1/pat/{id}", baseapp.SelfAccess(ah.deletePAT)).Methods(http.MethodDelete)
|
||||||
|
|
||||||
ah.APIHandler.RegisterRoutes(router)
|
ah.APIHandler.RegisterRoutes(router)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
78
ee/query-service/app/api/pat.go
Normal file
78
ee/query-service/app/api/pat.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"go.signoz.io/signoz/ee/query-service/model"
|
||||||
|
"go.signoz.io/signoz/pkg/query-service/auth"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func generatePATToken() string {
|
||||||
|
// Generate a 32-byte random token.
|
||||||
|
token := make([]byte, 32)
|
||||||
|
rand.Read(token)
|
||||||
|
// Encode the token in base64.
|
||||||
|
encodedToken := base64.StdEncoding.EncodeToString(token)
|
||||||
|
return encodedToken
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
req := model.PAT{}
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
RespondError(w, model.BadRequest(err), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user, err := auth.GetUserFromRequest(r)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{
|
||||||
|
Typ: model.ErrorUnauthorized,
|
||||||
|
Err: err,
|
||||||
|
}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.UserID = user.Id
|
||||||
|
req.CreatedAt = time.Now().Unix()
|
||||||
|
req.Token = generatePATToken()
|
||||||
|
|
||||||
|
zap.S().Infof("Got PAT request: %+v", req)
|
||||||
|
|
||||||
|
if apierr := ah.AppDao().CreatePAT(ctx, &req); apierr != nil {
|
||||||
|
RespondError(w, apierr, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ah.Respond(w, &req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ah *APIHandler) getPATs(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := context.Background()
|
||||||
|
user, _ := auth.GetUserFromRequest(r)
|
||||||
|
zap.S().Infof("Get PATs for user: %+v", user.Id)
|
||||||
|
pats, apierr := ah.AppDao().ListPATs(ctx, user.Id)
|
||||||
|
if apierr != nil {
|
||||||
|
RespondError(w, apierr, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ah.WriteJSON(w, r, pats)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ah *APIHandler) deletePAT(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := context.Background()
|
||||||
|
id := mux.Vars(r)["id"]
|
||||||
|
zap.S().Infof("Delete PAT with id: %+v", id)
|
||||||
|
if apierr := ah.AppDao().DeletePAT(ctx, id); apierr != nil {
|
||||||
|
RespondError(w, apierr, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ah.WriteJSON(w, r, map[string]string{"data": "pat deleted successfully"})
|
||||||
|
}
|
@ -3,6 +3,7 @@ package dao
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"go.signoz.io/signoz/ee/query-service/model"
|
"go.signoz.io/signoz/ee/query-service/model"
|
||||||
@ -32,4 +33,8 @@ type ModelDao interface {
|
|||||||
UpdateDomain(ctx context.Context, domain *model.OrgDomain) basemodel.BaseApiError
|
UpdateDomain(ctx context.Context, domain *model.OrgDomain) basemodel.BaseApiError
|
||||||
DeleteDomain(ctx context.Context, id uuid.UUID) basemodel.BaseApiError
|
DeleteDomain(ctx context.Context, id uuid.UUID) basemodel.BaseApiError
|
||||||
GetDomainByEmail(ctx context.Context, email string) (*model.OrgDomain, basemodel.BaseApiError)
|
GetDomainByEmail(ctx context.Context, email string) (*model.OrgDomain, basemodel.BaseApiError)
|
||||||
|
|
||||||
|
CreatePAT(ctx context.Context, p *model.PAT) basemodel.BaseApiError
|
||||||
|
ListPATs(ctx context.Context, userID string) ([]model.PAT, basemodel.BaseApiError)
|
||||||
|
DeletePAT(ctx context.Context, id string) basemodel.BaseApiError
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,17 @@ func InitDB(dataSourceName string) (*modelDao, error) {
|
|||||||
updated_at INTEGER,
|
updated_at INTEGER,
|
||||||
data TEXT NOT NULL,
|
data TEXT NOT NULL,
|
||||||
FOREIGN KEY(org_id) REFERENCES organizations(id)
|
FOREIGN KEY(org_id) REFERENCES organizations(id)
|
||||||
);`
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS personal_access_tokens (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
user_id TEXT NOT NULL,
|
||||||
|
token TEXT NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
created_at INTEGER NOT NULL,
|
||||||
|
expires_at INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY(user_id) REFERENCES users(id)
|
||||||
|
);
|
||||||
|
`
|
||||||
|
|
||||||
_, err = m.DB().Exec(table_schema)
|
_, err = m.DB().Exec(table_schema)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
44
ee/query-service/dao/sqlite/pat.go
Normal file
44
ee/query-service/dao/sqlite/pat.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package sqlite
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"go.signoz.io/signoz/ee/query-service/model"
|
||||||
|
basemodel "go.signoz.io/signoz/pkg/query-service/model"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (m *modelDao) CreatePAT(ctx context.Context, p *model.PAT) basemodel.BaseApiError {
|
||||||
|
_, err := m.DB().ExecContext(ctx,
|
||||||
|
"INSERT INTO personal_access_tokens (user_id, token, name, created_at, expires_at) VALUES ($1, $2, $3, $4, $5)",
|
||||||
|
p.UserID,
|
||||||
|
p.Token,
|
||||||
|
p.Name,
|
||||||
|
p.CreatedAt,
|
||||||
|
p.ExpiresAt)
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Errorf("Failed to insert PAT in db, err: %v", zap.Error(err))
|
||||||
|
return model.InternalError(fmt.Errorf("PAT insertion failed"))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *modelDao) ListPATs(ctx context.Context, userID string) ([]model.PAT, basemodel.BaseApiError) {
|
||||||
|
pats := []model.PAT{}
|
||||||
|
|
||||||
|
if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE user_id=?;`, userID); err != nil {
|
||||||
|
zap.S().Errorf("Failed to fetch PATs for user: %s, err: %v", userID, zap.Error(err))
|
||||||
|
return nil, model.InternalError(fmt.Errorf("Failed to fetch PATs"))
|
||||||
|
}
|
||||||
|
return pats, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *modelDao) DeletePAT(ctx context.Context, id string) basemodel.BaseApiError {
|
||||||
|
_, err := m.DB().ExecContext(ctx, `DELETE from personal_access_tokens where id=?;`, id)
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Errorf("Failed to delete PAT, err: %v", zap.Error(err))
|
||||||
|
return model.InternalError(fmt.Errorf("Failed to delete PAT"))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
10
ee/query-service/model/pat.go
Normal file
10
ee/query-service/model/pat.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type PAT struct {
|
||||||
|
Id string `json:"id" db:"id"`
|
||||||
|
UserID string `json:"userId" db:"user_id"`
|
||||||
|
Token string `json:"token" db:"token"`
|
||||||
|
Name string `json:"name" db:"name"`
|
||||||
|
CreatedAt int64 `json:"createdAt" db:"created_at"`
|
||||||
|
ExpiresAt int64 `json:"expiresAt" db:"expires_at"`
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user