ISM rewrite compatibility
This commit is contained in:
parent
cfead595ad
commit
1a2c461891
6
go.mod
6
go.mod
|
@ -3,10 +3,10 @@ module git.ailur.dev/ailur/datatracker
|
||||||
go 1.23.3
|
go 1.23.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.ailur.dev/ailur/fg-library/v2 v2.1.2
|
git.ailur.dev/ailur/fg-library/v3 v3.5.0
|
||||||
git.ailur.dev/ailur/fg-nucleus-library v1.0.5
|
git.ailur.dev/ailur/fg-nucleus-library v1.1.0
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require github.com/go-chi/chi/v5 v5.1.0 // indirect
|
require github.com/go-chi/chi/v5 v5.2.0 // indirect
|
||||||
|
|
10
go.sum
10
go.sum
|
@ -1,9 +1,11 @@
|
||||||
git.ailur.dev/ailur/fg-library/v2 v2.1.2 h1:Gk8ztytJfV2GYhsnfTDRWmvTzJ3Cn19V5p2suFCvu4E=
|
git.ailur.dev/ailur/fg-library/v3 v3.5.0 h1:BGDlS4nQ2PyZWNU4gH3eckVqhZUFIM/zKIj/HXx8RmA=
|
||||||
git.ailur.dev/ailur/fg-library/v2 v2.1.2/go.mod h1:gBnZQDV70YON6cnuwB+Jawm2EABbf9dGlV0Qw4obtxs=
|
git.ailur.dev/ailur/fg-library/v3 v3.5.0/go.mod h1:ArNsafpqES2JuxQM5aM+bNe0FwHLIsL6pbjpiWvDwGs=
|
||||||
git.ailur.dev/ailur/fg-nucleus-library v1.0.5 h1:0YVSHFOeydGR/pfq5AfiKQ5gWuxSnx8u2K8mHvEDDTI=
|
git.ailur.dev/ailur/fg-nucleus-library v1.0.5 h1:0YVSHFOeydGR/pfq5AfiKQ5gWuxSnx8u2K8mHvEDDTI=
|
||||||
git.ailur.dev/ailur/fg-nucleus-library v1.0.5/go.mod h1:nKYjJ+zJD1YcrEGWlyyA5r6CrzW8DWHVAnL9hkn2tNw=
|
git.ailur.dev/ailur/fg-nucleus-library v1.0.5/go.mod h1:nKYjJ+zJD1YcrEGWlyyA5r6CrzW8DWHVAnL9hkn2tNw=
|
||||||
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
|
git.ailur.dev/ailur/fg-nucleus-library v1.1.0 h1:D0eWwdlaw4IiOwz96MiRwHIdU/VIwiHUCeO00HkzzsU=
|
||||||
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
git.ailur.dev/ailur/fg-nucleus-library v1.1.0/go.mod h1:CHuOSByCmookwkcpjJBiinHEF27+IA70BhVtnR2cAhA=
|
||||||
|
github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0=
|
||||||
|
github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
|
218
main.go
218
main.go
|
@ -2,14 +2,13 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/url"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
library "git.ailur.dev/ailur/fg-library/v2"
|
library "git.ailur.dev/ailur/fg-library/v3"
|
||||||
authLibrary "git.ailur.dev/ailur/fg-nucleus-library"
|
authLibrary "git.ailur.dev/ailur/fg-nucleus-library"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
@ -23,6 +22,7 @@ var ServiceInformation = library.Service{
|
||||||
Permissions: library.Permissions{
|
Permissions: library.Permissions{
|
||||||
Authenticate: true, // This service does require authentication
|
Authenticate: true, // This service does require authentication
|
||||||
Database: true, // This service does require database access
|
Database: true, // This service does require database access
|
||||||
|
Router: true, // This service does require a router
|
||||||
BlobStorage: false, // This service does not require blob storage
|
BlobStorage: false, // This service does not require blob storage
|
||||||
InterServiceCommunication: true, // This service does require inter-service communication
|
InterServiceCommunication: true, // This service does require inter-service communication
|
||||||
Resources: true, // This service does require its HTTP templates and static files
|
Resources: true, // This service does require its HTTP templates and static files
|
||||||
|
@ -30,15 +30,13 @@ var ServiceInformation = library.Service{
|
||||||
ServiceID: uuid.MustParse("322dc186-04d2-4f69-89b5-403ab643cc1d"),
|
ServiceID: uuid.MustParse("322dc186-04d2-4f69-89b5-403ab643cc1d"),
|
||||||
}
|
}
|
||||||
|
|
||||||
func logFunc(message string, messageType uint64, information library.ServiceInitializationInformation) {
|
var (
|
||||||
|
loggerService = uuid.MustParse("00000000-0000-0000-0000-000000000002")
|
||||||
|
)
|
||||||
|
|
||||||
|
func logFunc(message string, messageType library.MessageCode, information library.ServiceInitializationInformation) {
|
||||||
// Log the message to the logger service
|
// Log the message to the logger service
|
||||||
information.Outbox <- library.InterServiceMessage{
|
information.SendISMessage(loggerService, messageType, message)
|
||||||
ServiceID: ServiceInformation.ServiceID,
|
|
||||||
ForServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000002"), // Logger service
|
|
||||||
MessageType: messageType,
|
|
||||||
SentAt: time.Now(),
|
|
||||||
Message: message,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(statusCode int, w http.ResponseWriter, data map[string]interface{}, templatePath string, information library.ServiceInitializationInformation) {
|
func renderTemplate(statusCode int, w http.ResponseWriter, data map[string]interface{}, templatePath string, information library.ServiceInitializationInformation) {
|
||||||
|
@ -104,6 +102,10 @@ func getUsername(token string, oauthHostName string, publicKey ed25519.PublicKey
|
||||||
Sub string `json:"sub"`
|
Sub string `json:"sub"`
|
||||||
}
|
}
|
||||||
request, err := http.NewRequest("GET", oauthHostName+"/api/oauth/userinfo", nil)
|
request, err := http.NewRequest("GET", oauthHostName+"/api/oauth/userinfo", nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
request.Header.Set("Authorization", "Bearer "+token)
|
request.Header.Set("Authorization", "Bearer "+token)
|
||||||
response, err := http.DefaultClient.Do(request)
|
response, err := http.DefaultClient.Do(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -165,165 +167,55 @@ func Main(information library.ServiceInitializationInformation) {
|
||||||
hostName := information.Configuration["hostName"].(string)
|
hostName := information.Configuration["hostName"].(string)
|
||||||
|
|
||||||
// Initiate a connection to the database
|
// Initiate a connection to the database
|
||||||
// Call service ID 1 to get the database connection information
|
conn, err := information.GetDatabase()
|
||||||
information.Outbox <- library.InterServiceMessage{
|
|
||||||
ServiceID: ServiceInformation.ServiceID,
|
|
||||||
ForServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000001"), // Service initialization service
|
|
||||||
MessageType: 1, // Request connection information
|
|
||||||
SentAt: time.Now(),
|
|
||||||
Message: nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for the response
|
|
||||||
response := <-information.Inbox
|
|
||||||
if response.MessageType == 2 {
|
|
||||||
// This is the connection information
|
|
||||||
// Set up the database connection
|
|
||||||
conn = response.Message.(library.Database)
|
|
||||||
if conn.DBType == library.Sqlite {
|
|
||||||
// Create the RFCs table
|
|
||||||
_, err := conn.DB.Exec("CREATE TABLE IF NOT EXISTS rfc (id INTEGER NOT NULL, year INTEGER NOT NULL, name TEXT NOT NULL, content TEXT NOT NULL, version TEXT NOT NULL, creator BLOB NOT NULL, UNIQUE(id, year))")
|
|
||||||
if err != nil {
|
|
||||||
logFunc(err.Error(), 3, information)
|
|
||||||
}
|
|
||||||
// Create the users table
|
|
||||||
_, err = conn.DB.Exec("CREATE TABLE IF NOT EXISTS users (id BLOB NOT NULL)")
|
|
||||||
if err != nil {
|
|
||||||
logFunc(err.Error(), 3, information)
|
|
||||||
}
|
|
||||||
// Create the comments table
|
|
||||||
_, err = conn.DB.Exec("CREATE TABLE IF NOT EXISTS comments (id BLOB NOT NULL, rfcId INTEGER NOT NULL, rfcYear INTEGER NOT NULL, content TEXT NOT NULL, creator BLOB NOT NULL, creatorName TEXT NOT NULL, created INTEGER NOT NULL)")
|
|
||||||
if err != nil {
|
|
||||||
logFunc(err.Error(), 3, information)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Create the RFCs table
|
|
||||||
_, err := conn.DB.Exec("CREATE TABLE IF NOT EXISTS rfc (id SERIAL PRIMARY KEY, year INTEGER NOT NULL, name TEXT NOT NULL, content TEXT NOT NULL, version TEXT NOT NULL, creator BYTEA NOT NULL, UNIQUE(id, year))")
|
|
||||||
if err != nil {
|
|
||||||
logFunc(err.Error(), 3, information)
|
|
||||||
}
|
|
||||||
// Create the users table
|
|
||||||
_, err = conn.DB.Exec("CREATE TABLE IF NOT EXISTS users (id BYTEA NOT NULL)")
|
|
||||||
if err != nil {
|
|
||||||
logFunc(err.Error(), 3, information)
|
|
||||||
}
|
|
||||||
// Create the comments table
|
|
||||||
_, err = conn.DB.Exec("CREATE TABLE IF NOT EXISTS comments (id BYTEA NOT NULL, rfcId INTEGER NOT NULL, rfcYear INTEGER NOT NULL, content TEXT NOT NULL, creator BYTEA NOT NULL, creatorName TEXT NOT NULL, created INTEGER NOT NULL)")
|
|
||||||
if err != nil {
|
|
||||||
logFunc(err.Error(), 3, information)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// This is an error message
|
|
||||||
// Log the error message to the logger service
|
|
||||||
logFunc(response.Message.(error).Error(), 3, information)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask the authentication service for the public key
|
|
||||||
information.Outbox <- library.InterServiceMessage{
|
|
||||||
ServiceID: ServiceInformation.ServiceID,
|
|
||||||
ForServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000004"), // Authentication service
|
|
||||||
MessageType: 2, // Request public key
|
|
||||||
SentAt: time.Now(),
|
|
||||||
Message: nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
var publicKey ed25519.PublicKey = nil
|
|
||||||
|
|
||||||
// 3 second timeout
|
|
||||||
go func() {
|
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
if publicKey == nil {
|
|
||||||
logFunc("Timeout while waiting for the public key from the authentication service", 3, information)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Wait for the response
|
|
||||||
response = <-information.Inbox
|
|
||||||
if response.MessageType == 2 {
|
|
||||||
// This is the public key
|
|
||||||
publicKey = response.Message.(ed25519.PublicKey)
|
|
||||||
} else {
|
|
||||||
// This is an error message
|
|
||||||
// Log the error message to the logger service
|
|
||||||
logFunc(response.Message.(error).Error(), 3, information)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask the authentication service for the OAuth host name
|
|
||||||
information.Outbox <- library.InterServiceMessage{
|
|
||||||
ServiceID: ServiceInformation.ServiceID,
|
|
||||||
ForServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000004"), // Authentication service
|
|
||||||
MessageType: 0, // Request OAuth host name
|
|
||||||
SentAt: time.Now(),
|
|
||||||
Message: nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
var oauthHostName string
|
|
||||||
|
|
||||||
// 3 second timeout
|
|
||||||
go func() {
|
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
if oauthHostName == "" {
|
|
||||||
logFunc("Timeout while waiting for the OAuth host name from the authentication service", 3, information)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Wait for the response
|
|
||||||
response = <-information.Inbox
|
|
||||||
if response.MessageType == 0 {
|
|
||||||
// This is the OAuth host name
|
|
||||||
oauthHostName = response.Message.(string)
|
|
||||||
} else {
|
|
||||||
// This is an error message
|
|
||||||
// Log the error message to the logger service
|
|
||||||
logFunc(response.Message.(error).Error(), 3, information)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask the authentication service to create a new OAuth2 client
|
|
||||||
urlPath, err := url.JoinPath(hostName, "/oauth")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logFunc(err.Error(), 3, information)
|
logFunc(err.Error(), 3, information)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
information.Outbox <- library.InterServiceMessage{
|
if conn.DBType == library.Sqlite {
|
||||||
ServiceID: ServiceInformation.ServiceID,
|
// Create the RFCs table
|
||||||
ForServiceID: uuid.MustParse("00000000-0000-0000-0000-000000000004"), // Authentication service
|
_, err := conn.DB.Exec("CREATE TABLE IF NOT EXISTS rfc (id INTEGER NOT NULL, year INTEGER NOT NULL, name TEXT NOT NULL, content TEXT NOT NULL, version TEXT NOT NULL, creator BLOB NOT NULL, UNIQUE(id, year))")
|
||||||
MessageType: 1, // Create OAuth2 client
|
if err != nil {
|
||||||
SentAt: time.Now(),
|
logFunc(err.Error(), 3, information)
|
||||||
Message: authLibrary.OAuthInformation{
|
|
||||||
Name: "Data Tracker",
|
|
||||||
RedirectUri: urlPath,
|
|
||||||
KeyShareUri: "",
|
|
||||||
Scopes: []string{"openid"},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
oauthResponse := authLibrary.OAuthResponse{}
|
|
||||||
|
|
||||||
// 3 second timeout
|
|
||||||
go func() {
|
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
if oauthResponse == (authLibrary.OAuthResponse{}) {
|
|
||||||
logFunc("Timeout while waiting for the OAuth response from the authentication service", 3, information)
|
|
||||||
}
|
}
|
||||||
}()
|
// Create the users table
|
||||||
|
_, err = conn.DB.Exec("CREATE TABLE IF NOT EXISTS users (id BLOB NOT NULL)")
|
||||||
|
if err != nil {
|
||||||
|
logFunc(err.Error(), 3, information)
|
||||||
|
}
|
||||||
|
// Create the comments table
|
||||||
|
_, err = conn.DB.Exec("CREATE TABLE IF NOT EXISTS comments (id BLOB NOT NULL, rfcId INTEGER NOT NULL, rfcYear INTEGER NOT NULL, content TEXT NOT NULL, creator BLOB NOT NULL, creatorName TEXT NOT NULL, created INTEGER NOT NULL)")
|
||||||
|
if err != nil {
|
||||||
|
logFunc(err.Error(), 3, information)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Create the RFCs table
|
||||||
|
_, err := conn.DB.Exec("CREATE TABLE IF NOT EXISTS rfc (id SERIAL PRIMARY KEY, year INTEGER NOT NULL, name TEXT NOT NULL, content TEXT NOT NULL, version TEXT NOT NULL, creator BYTEA NOT NULL, UNIQUE(id, year))")
|
||||||
|
if err != nil {
|
||||||
|
logFunc(err.Error(), 3, information)
|
||||||
|
}
|
||||||
|
// Create the users table
|
||||||
|
_, err = conn.DB.Exec("CREATE TABLE IF NOT EXISTS users (id BYTEA NOT NULL)")
|
||||||
|
if err != nil {
|
||||||
|
logFunc(err.Error(), 3, information)
|
||||||
|
}
|
||||||
|
// Create the comments table
|
||||||
|
_, err = conn.DB.Exec("CREATE TABLE IF NOT EXISTS comments (id BYTEA NOT NULL, rfcId INTEGER NOT NULL, rfcYear INTEGER NOT NULL, content TEXT NOT NULL, creator BYTEA NOT NULL, creatorName TEXT NOT NULL, created INTEGER NOT NULL)")
|
||||||
|
if err != nil {
|
||||||
|
logFunc(err.Error(), 3, information)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the response
|
// Initialize the OAuth
|
||||||
response = <-information.Inbox
|
oauthResponse, publicKey, oauthHostName, err := authLibrary.InitializeOAuth(authLibrary.OAuthInformation{
|
||||||
switch response.MessageType {
|
Name: "datatracker",
|
||||||
case 0:
|
RedirectUri: hostName + "/oauth",
|
||||||
// Success, set the OAuth response
|
Scopes: []string{"openid"},
|
||||||
oauthResponse = response.Message.(authLibrary.OAuthResponse)
|
}, information)
|
||||||
logFunc("Initialized with App ID: "+oauthResponse.AppID, 0, information)
|
if err != nil {
|
||||||
case 1:
|
logFunc(err.Error(), 3, information)
|
||||||
// An error which is their fault
|
return
|
||||||
logFunc(response.Message.(error).Error(), 3, information)
|
|
||||||
case 2:
|
|
||||||
// An error which is our fault
|
|
||||||
logFunc(response.Message.(error).Error(), 3, information)
|
|
||||||
default:
|
|
||||||
// An unknown error
|
|
||||||
logFunc("Unknown error", 3, information)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the router
|
// Set up the router
|
||||||
|
|
Loading…
Reference in New Issue