Garage key page info

This commit is contained in:
Quentin 2023-04-19 11:36:13 +02:00
parent 24600c8787
commit bdb9af5a26
Signed by untrusted user: quentin
GPG key ID: E9602264D639FF68
3 changed files with 81 additions and 14 deletions

View file

@ -1,9 +1,12 @@
package main package main
import ( import (
"errors"
"log"
"net/http" "net/http"
"context" "context"
"fmt" "fmt"
"github.com/go-ldap/ldap/v3"
garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang" garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang"
) )
@ -21,26 +24,82 @@ func gadmin() (*garage.APIClient, context.Context) {
} }
func createKey(name string) error { func grgCreateKey(name string) (*garage.KeyInfo, error) {
client, ctx := gadmin() client, ctx := gadmin()
kr := garage.AddKeyRequest{Name: &name} kr := garage.AddKeyRequest{Name: &name}
resp, _, err := client.KeyApi.AddKey(ctx).AddKeyRequest(kr).Execute() resp, _, err := client.KeyApi.AddKey(ctx).AddKeyRequest(kr).Execute()
if err != nil { if err != nil {
fmt.Printf("%+v\n", err) fmt.Printf("%+v\n", err)
return err return nil, err
} }
fmt.Printf("%+v\n", resp) return resp, nil
return nil }
func grgGetKey(accessKey string) (*garage.KeyInfo, error) {
client, ctx := gadmin()
resp, _, err := client.KeyApi.GetKey(ctx, accessKey).Execute()
if err != nil {
fmt.Printf("%+v\n", err)
return nil, err
}
return resp, nil
}
func checkLoginAndS3(w http.ResponseWriter, r *http.Request) (*LoginStatus, *garage.KeyInfo, error) {
login := checkLogin(w, r)
if login == nil {
return nil, nil, errors.New("LDAP login failed")
}
keyID := login.UserEntry.GetAttributeValue("garage_s3_access_key")
if keyID == "" {
keyPair, err := grgCreateKey(login.Info.Username)
if err != nil {
return login, nil, err
}
modify_request := ldap.NewModifyRequest(login.Info.DN, nil)
modify_request.Replace("garage_s3_access_key", []string{*keyPair.AccessKeyId})
// @FIXME compatibility feature for bagage (SFTP+webdav)
// you can remove it once bagage will be updated to fetch the key from garage directly
// or when bottin will be able to dynamically fetch it.
modify_request.Replace("garage_s3_secret_key", []string{*keyPair.SecretAccessKey})
err = login.conn.Modify(modify_request)
return login, keyPair, err
}
// Note: we could simply return the login info, but LX asked we do not
// store the secrets in LDAP in the future.
keyPair, err := grgGetKey(keyID)
return login, keyPair, err
}
type keyView struct {
Status *LoginStatus
Key *garage.KeyInfo
} }
func handleGarageKey(w http.ResponseWriter, r *http.Request) { func handleGarageKey(w http.ResponseWriter, r *http.Request) {
createKey("toto") login, s3key, err := checkLoginAndS3(w, r)
if err != nil {
log.Println(err)
return
}
view := keyView{Status: login, Key: s3key}
tKey := getTemplate("garage_key.html") tKey := getTemplate("garage_key.html")
tKey.Execute(w, nil) tKey.Execute(w, &view)
} }
func handleGarageWebsiteList(w http.ResponseWriter, r *http.Request) { func handleGarageWebsiteList(w http.ResponseWriter, r *http.Request) {
login, s3key, err := checkLoginAndS3(w, r)
if err != nil {
log.Println(err)
return
}
log.Println(login, s3key)
tWebsiteList := getTemplate("garage_website_list.html") tWebsiteList := getTemplate("garage_website_list.html")
tWebsiteList.Execute(w, nil) tWebsiteList.Execute(w, nil)
} }
@ -51,6 +110,13 @@ func handleGarageWebsiteNew(w http.ResponseWriter, r *http.Request) {
} }
func handleGarageWebsiteInspect(w http.ResponseWriter, r *http.Request) { func handleGarageWebsiteInspect(w http.ResponseWriter, r *http.Request) {
login, s3key, err := checkLoginAndS3(w, r)
if err != nil {
log.Println(err)
return
}
log.Println(login, s3key)
tWebsiteInspect := getTemplate("garage_website_inspect.html") tWebsiteInspect := getTemplate("garage_website_inspect.html")
tWebsiteInspect.Execute(w, nil) tWebsiteInspect.Execute(w, nil)
} }

View file

@ -255,6 +255,7 @@ func checkLogin(w http.ResponseWriter, r *http.Request) *LoginStatus {
"mail", "mail",
"memberof", "memberof",
"description", "description",
"garage_s3_access_key",
FIELD_NAME_DIRECTORY_VISIBILITY, FIELD_NAME_DIRECTORY_VISIBILITY,
FIELD_NAME_PROFILE_PICTURE, FIELD_NAME_PROFILE_PICTURE,
}, },

View file

@ -22,11 +22,11 @@
<tbody> <tbody>
<tr> <tr>
<th scope="row">Identifiant de clé</th> <th scope="row">Identifiant de clé</th>
<td>GKxxx</td> <td>{{ .Key.AccessKeyId }}</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Clé secrète</th> <th scope="row">Clé secrète</th>
<td>...</td> <td>{{ .Key.SecretAccessKey }}</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Région</th> <th scope="row">Région</th>
@ -62,8 +62,8 @@
<div class="card-body"> <div class="card-body">
<p>Créez un fichier nommé <code>~/.awsrc</code> :</p> <p>Créez un fichier nommé <code>~/.awsrc</code> :</p>
<pre> <pre>
export AWS_ACCESS_KEY_ID=GK... export AWS_ACCESS_KEY_ID={{ .Key.AccessKeyId }}
export AWS_SECRET_ACCESS_KEY=... export AWS_SECRET_ACCESS_KEY={{ .Key.SecretAccessKey }}
export AWS_DEFAULT_REGION='garage' export AWS_DEFAULT_REGION='garage'
function aws { command aws --endpoint-url https://garage.deuxfleurs.fr $@ ; } function aws { command aws --endpoint-url https://garage.deuxfleurs.fr $@ ; }
@ -97,8 +97,8 @@ aws s3 cp /tmp/a.txt s3://my-bucket
mc alias set \ mc alias set \
garage \ garage \
https://garage.deuxfleurs.fr \ https://garage.deuxfleurs.fr \
GK... \ {{ .Key.AccessKeyId }} \
... \ {{ .Key.SecretAccessKey }} \
--api S3v4 --api S3v4
</pre> </pre>
<p>Et ensuite pour utiliser Minio CLI avec :</p> <p>Et ensuite pour utiliser Minio CLI avec :</p>
@ -176,7 +176,7 @@ hugo deploy
<tbody> <tbody>
<tr> <tr>
<th scope="row">Nom d'utilisateur-ice</th> <th scope="row">Nom d'utilisateur-ice</th>
<td>(votre username guichet)</td> <td>{{ .Status.Info.Username }}</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Mot de passe</th> <th scope="row">Mot de passe</th>
@ -207,7 +207,7 @@ hugo deploy
<div class="card-body"> <div class="card-body">
<p>Un exemple avec SCP :</p> <p>Un exemple avec SCP :</p>
<pre> <pre>
scp -oHostKeyAlgorithms=+ssh-rsa -P2222 -r ./public bagage.deuxfleurs.fr:mon_bucket/ scp -oHostKeyAlgorithms=+ssh-rsa -P2222 -r ./public {{ .Status.Info.Username }}@bagage.deuxfleurs.fr:mon_bucket/
</pre> </pre>
</div> </div>
</div> </div>