wisski-cloud-distillery/internal/dis/component/triplestore/provision.go
2024-04-04 13:52:15 +02:00

101 lines
2.8 KiB
Go

package triplestore
import (
"bytes"
"context"
"errors"
"net/http"
"text/template"
_ "embed"
"github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/tkw1536/goprogram/exit"
)
var errTripleStoreFailedRepository = exit.Error{
Message: "failed to create repository: %s",
ExitCode: exit.ExitGeneric,
}
//go:embed create-repo.tpl
var createRepoTpl string
// Template for creating repositories.
//
// NOTE(twiesing): The template is not aware of SparQL syntax, thus this template is very unsafe.
// And should only be used with KNOWN GOOD input.
var creteRepoTemplate = template.Must(template.New("create-repo.tpl").Parse(createRepoTpl))
type createRepoContext struct {
RepositoryID string
Label string
BaseURL string
}
func (ts *Triplestore) Provision(ctx context.Context, instance models.Instance, domain string) error {
return ts.CreateRepository(ctx, instance.GraphDBRepository, domain, instance.GraphDBUsername, instance.GraphDBPassword)
}
func (ts *Triplestore) Purge(ctx context.Context, instance models.Instance, domain string) error {
return errors.Join(
ts.PurgeRepo(ctx, instance.GraphDBRepository),
ts.PurgeUser(ctx, instance.GraphDBUsername),
)
}
func (ts *Triplestore) CreateRepository(ctx context.Context, name, domain, user, password string) error {
if err := ts.Wait(ctx); err != nil {
return err
}
// prepare the create repo request
var createRepo bytes.Buffer
if err := creteRepoTemplate.Execute(&createRepo, createRepoContext{
RepositoryID: name,
Label: domain,
BaseURL: "http://" + domain + "/",
}); err != nil {
return err
}
// do the create!
{
res, err := ts.DoRestWithForm(ctx, tsTrivialTimeout, http.MethodPost, "/rest/repositories", nil, "config", &createRepo)
if err != nil {
return errTripleStoreFailedRepository.WithMessageF(err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
return errTripleStoreFailedRepository.WithMessageF("repo create did not return status code 201")
}
}
// create the user and grant them access
{
res, err := ts.DoRestWithMarshal(ctx, tsTrivialTimeout, http.MethodPost, "/rest/security/users/"+user, nil, TriplestoreUserPayload{
Password: password,
AppSettings: TriplestoreUserAppSettings{
DefaultInference: true,
DefaultVisGraphSchema: true,
DefaultSameas: true,
IgnoreSharedQueries: false,
ExecuteCount: true,
},
GrantedAuthorities: []string{
"ROLE_USER",
"READ_REPO_" + name,
"WRITE_REPO_" + name,
},
})
if err != nil {
return errTripleStoreFailedRepository.WithMessageF(err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
return errTripleStoreFailedRepository.WithMessageF("user create did not return status code 201")
}
}
return nil
}