diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 381df275579468051eb8b56a7337b0cfc91c67ea..0000000000000000000000000000000000000000 --- a/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -** -!piratar -!piratar.conf -!default.jpg diff --git a/.env b/.env new file mode 100644 index 0000000000000000000000000000000000000000..c012b30ae95c36a3691cdc678e10fad18d2eedb1 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +export OCTOPUS=https://chobotnice.pirati.cz/graphql/ +export OCTPUS_DEBUG=1 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5ac96414271d44a899abca06475a421a2b6c51dd..10d37664c6fd300019c224909b52a404bd75f6a8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,11 +1,10 @@ -image: docker:20.10.9 +image: docker:latest variables: DOCKER_TLS_CERTDIR: "/certs" - IMAGE_VER: 2.1.0 services: - - docker:20.10.9-dind + - docker:dind before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY @@ -13,7 +12,8 @@ before_script: build: stage: build script: + - VERSION=`cat VERSION` - docker pull $CI_REGISTRY_IMAGE:latest || true - - docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$IMAGE_VER --tag $CI_REGISTRY_IMAGE:latest . - - docker push $CI_REGISTRY_IMAGE:$IMAGE_VER + - docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$VERSION --tag $CI_REGISTRY_IMAGE:latest . + - docker push $CI_REGISTRY_IMAGE:$VERSION - docker push $CI_REGISTRY_IMAGE:latest diff --git a/Dockerfile b/Dockerfile index 3f4c2f30fc059346737f4bd547fce0f37091fd34..0de64e5c506848d1ec05d290d9fa1507647b8e40 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ -FROM alpine:latest -RUN apk update && apk add perl-mojolicious perl-io-socket-ssl perl-app-cpanminus make -RUN cpanm GraphQL::Client +FROM golang:alpine AS build-stage +ADD . ./ +RUN CGO_ENABLED=0 GOOS=linux go build -o /piratar -ADD . /opt/piratar -WORKDIR /opt/piratar - -USER nobody +FROM alpine +WORKDIR /app +COPY --from=build-stage /piratar /app +COPY default.jpg /app EXPOSE 3000 -CMD /opt/piratar/piratar daemon -c 3000 +ENTRYPOINT ["/app/piratar"] diff --git a/VERSION b/VERSION new file mode 100644 index 0000000000000000000000000000000000000000..4a36342fcab700951adb18ae7adc930997f6c3f4 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +3.0.0 diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6e0f8b7ea5d93d941043d5d0676c2c88489d0569 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,7 @@ +services: + app: + image: piratar + environment: + OCTOPUS: https://chobotnice.pirati.cz/graphql/ + ports: + - "3000:3000" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..68b7c45ecfb1546695c2a0c1bb26685bfb501d81 --- /dev/null +++ b/go.mod @@ -0,0 +1,14 @@ +module pirates/piratar + +go 1.22.2 + +require pirates/piratar/octopus v0.0.0-00010101000000-000000000000 + +require ( + github.com/google/uuid v1.6.0 // indirect + github.com/machinebox/graphql v0.2.2 // indirect + github.com/matryer/is v1.4.1 // indirect + github.com/pkg/errors v0.9.1 // indirect +) + +replace pirates/piratar/octopus => ./octopus diff --git a/go.sum b/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..2fe3d62bf9a67c7de92a54c8dfd3a9ce30f6e1ed --- /dev/null +++ b/go.sum @@ -0,0 +1,8 @@ +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo= +github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA= +github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= +github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/main.go b/main.go new file mode 100644 index 0000000000000000000000000000000000000000..8635994e0016fc991dd316899a101efbbd4f29cf --- /dev/null +++ b/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "log" + "path" + "strings" + "net/http" + "pirates/piratar/octopus" +) + +func main() { + http.HandleFunc("/", handler) + + port := 3000 // TODO: ENV + fmt.Printf("Piratar service listening on port %d...\n", port) + + if err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil); err != nil { + log.Fatalf("Server failed: %v", err) + } +} + +func handler(w http.ResponseWriter, r *http.Request) { + + // Extrakce username nebo UUID + id := strings.ToLower(path.Base(r.URL.Path)) + if dotIndex := strings.LastIndex(id, "."); dotIndex != -1 { + id = id[:dotIndex] + } + + // Profilova fotka nebo default + if photo, err := octopus.ProfilePhoto(id); err == nil { + fmt.Printf("Piratar for %s: %s\n", id, photo) + http.Redirect(w, r, photo, http.StatusFound) + } else { + fmt.Printf("Piratar for %s not found\n", id) + w.Header().Set("Content-Type", "image/jpeg") + http.ServeFile(w, r, "default.jpg") + } +} diff --git a/octopus/go.mod b/octopus/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..17405e123116173147946b8cfb9cf050fffc1016 --- /dev/null +++ b/octopus/go.mod @@ -0,0 +1,3 @@ +module pirates/piratar/octopus + +go 1.22.2 diff --git a/octopus/octopus.go b/octopus/octopus.go new file mode 100644 index 0000000000000000000000000000000000000000..f7ef86055f0c26c7c4e7b5eb8821c196be643561 --- /dev/null +++ b/octopus/octopus.go @@ -0,0 +1,60 @@ +package octopus + +import ( + "os" + "fmt" + "log" + "errors" + "context" + "github.com/google/uuid" + "github.com/machinebox/graphql" +) + +func ProfilePhoto (id string) (string, error) { + var keyname string + var response struct { + AllPeople struct { + Edges []struct { + Node struct { + ProfilePhoto string `json:"profilePhoto"` + } `json:"node"` + } `json:"edges"` + } `json:"allPeople"` + } + + if _, err := uuid.Parse(id); err == nil { + keyname = "keycloakId" + } else { + keyname = "username" + } + + // GraphAPI klient + octopus := graphql.NewClient(os.Getenv("OCTOPUS")) + if os.Getenv("DEBUG") != "" { + octopus.Log = func(s string) { log.Println(s) } + } + + // Request + req := graphql.NewRequest(fmt.Sprintf( + `query profilePhoto($username: String!) { + allPeople(filters: {%s: {iExact: $username}}) { + edges { node { profilePhoto } } + }} + `, keyname )) + + req.Var("username", id) + +// define a Context for the request + ctx := context.Background() + +// run it and capture the response + if err := octopus.Run(ctx, req, &response); err != nil { + log.Fatal(err) + } + + if people := response.AllPeople.Edges; len(people) == 1 { + return people[0].Node.ProfilePhoto, nil + } else { + return "", errors.New("User not found") + } +} diff --git a/piratar b/piratar deleted file mode 100755 index e1d838b5edfcc0ff5e0e8715d81fddec65e31488..0000000000000000000000000000000000000000 --- a/piratar +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env perl -use Mojolicious::Lite -signatures; -use Mojo::UserAgent; -use Mojolicious::Static; -use GraphQL::Client; -use Mojo::Util qw(dumper); - -get '/*url' => sub ($c) { - - my $username = lc($c->param('url')); - $username =~ s/^.*\///; - $username =~ s/\.(png|jpg|gif)$//; - $c->app->log->debug("Username: $username"); - - my $gq = GraphQL::Client->new(url => $ENV{OCTOPUS}); - my $rc = $gq->execute(qq[ query MyQuery { - allPeople(filters: {username: {iExact: "$username"}}) { - edges { node { profilePhoto } } - }}], - ); - - if ($rc->{errors}) { - $c->app->log->warn("Octopus error: " . dumper $rc->{errors}); - } - elsif ( $rc->{data} ) { - $c->app->log->debug("Octopus response: " . dumper $rc->{data}); - - my $user = $rc->{data}{allPeople}{edges}[0]{node}; - - if ( my $photo = $user->{profilePhoto}) { - $c->app->log->info("Avatar for user $username: $photo"); - $c->redirect_to($photo); - return; - } - } - - $c->app->log->info("Avatar for user $username: FALLBACK"); - $c->reply->file('default.jpg'); -}; - -app->start;