mattermost-community / mattermost-app-gcal

Google Calendar Mattermost App
Apache License 2.0
8 stars 5 forks source link

Building in Docker #10

Open Azario16 opened 1 year ago

Azario16 commented 1 year ago

Good afternoon

I'm trying to build docker plugin binaries but I'm getting errors, I'm not good with Make so I tried to find a ready solution

My docker file

FROM alpine:latest
RUN apk update && apk add make g++ bash go curl git
RUN wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.52.2
ENTRYPOINT ["bash"]

When the container is finished building, I run the command:

docker run
-v ${SYSTEM_DIR}\mattermost-plugin-apps\:/opt/app
-it --name mattermost_app_gcal
--entrypoint /bin/bash mattermost-app-gcal

Go to plugin directory

cd opt/app

And I execute the command

make all

I am getting an error in the process

Azario16 commented 1 year ago

go: downloading github.com/pkg/errors v0.9.1
go: downloading github.com/mattermost/mattermost-server/v6 v6.0.0-20210906125346-b41b7eae1026
go: downloading github.com/francoispqt/gojay v1.2.13
go: downloading github.com/dyatlov/go-opengraph v0.0.0-20210112100619-dae8665a5b09
go: downloading github.com/blang/semver v3.5.1+incompatible
go: downloading github.com/gorilla/websocket v1.4.2
go: downloading github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d
go: downloading github.com/pborman/uuid v1.2.1
go: downloading github.com/tinylib/msgp v1.1.6
go: downloading gopkg.in/yaml.v2 v2.4.0
go: downloading golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e
go: downloading golang.org/x/text v0.3.6
go: downloading github.com/mattermost/go-i18n v1.11.0
go: downloading github.com/minio/minio-go/v7 v7.0.11
go: downloading github.com/mattermost/logr/v2 v2.0.10
go: downloading github.com/google/uuid v1.2.0
go: downloading golang.org/x/net v0.0.0-20210614182718-04defd469f4e
go: downloading github.com/go-asn1-ber/asn1-ber v1.5.3
go: downloading github.com/pelletier/go-toml v1.9.3
go: downloading github.com/philhofer/fwd v1.1.1
go: downloading github.com/json-iterator/go v1.1.11
go: downloading github.com/minio/md5-simd v1.1.2
go: downloading github.com/minio/sha256-simd v1.0.0
go: downloading github.com/mitchellh/go-homedir v1.1.0
go: downloading gopkg.in/ini.v1 v1.62.0
go: downloading github.com/rs/xid v1.3.0
go: downloading golang.org/x/sys v0.0.0-20210616094352-59db8d763f22
go: downloading github.com/klauspost/cpuid/v2 v2.0.6
go: downloading github.com/modern-go/reflect2 v1.0.1
go: downloading github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
go: downloading github.com/mattermost/logr v1.0.13
go: downloading github.com/klauspost/cpuid v1.3.1
go: downloading github.com/wiggin77/merror v1.0.3
go: downloading gopkg.in/natefinch/lumberjack.v2 v2.0.0
go: downloading github.com/wiggin77/srslog v1.0.1
Checking for style guide compliance
Running golangci-lint
golangci-lint run ./...
plugin.go:1: File is not `gofmt`-ed with `-s` (gofmt)
package root

import (
        "embed" // Need to embed manifest file
        "encoding/json"
        "net/http"

        "github.com/mattermost/mattermost-plugin-apps/apps"
        "github.com/mattermost/mattermost-plugin-apps/utils/httputils"
        "github.com/mattermost/mattermost-server/v6/model"
)

//go:embed plugin.json
var pluginManifestData []byte

//go:embed manifest.json
var appManifestData []byte

//go:embed static
var staticFS embed.FS

var Manifest model.Manifest
var AppManifest apps.Manifest

func init() {
        _ = json.Unmarshal(pluginManifestData, &Manifest)
        _ = json.Unmarshal(appManifestData, &AppManifest)
}

func InitHTTP(prefix string) {
        http.HandleFunc(prefix+"/manifest.json",
                httputils.DoHandleJSONData(appManifestData))

        http.Handle(prefix+"/static/",
                http.StripPrefix(prefix+"/", http.FileServer(http.FS(staticFS))))
}
function/app.go:1: File is not `gofmt`-ed with `-s` (gofmt)
package function

import (
        "fmt"
        "net/http"

        "go.uber.org/zap/zapcore"

        appspath "github.com/mattermost/mattermost-plugin-apps/apps/path"
        "github.com/mattermost/mattermost-plugin-apps/utils"
        "github.com/mattermost/mattermost-plugin-apps/utils/httputils"
)

const IconPath = "icon.png"

var AppPathPrefix = ""
var Log = utils.MustMakeCommandLogger(zapcore.DebugLevel)

var BuildHash string
var BuildHashShort string
var BuildDate string

// KV store: subscriptions
const (
        // Individual subscriptions are stored in the "s" namespace, as "[s]{id}",
        // where id is the generated ID of the subscription, also known as channel
        // ID in Google terms.
        KVSubPrefix = "s"

        // Indices of subscriptions are stored in the "si" namespace, as
        // "[si]{userID}". The global (channel) subscriptions are stored under the
        // "bot_subs".
        KVSubIndexPrefix = "si"

        // Individual events are stored in the "e" namespace, as
        // "[e]base64({googleEmail}/{calID}/{eventID})".
        KVEventPrefix = "e"

        // The name of the key that stores the list of global subscriptions.
        KVBotSubscriptionsKey = "bot_subs"
)

// Field names
const (
        fAccountJSON       = "account_json"
        fAPIKey            = "api_key"
        fCalendarID        = "calendar_id"
        fClientID          = "client_id"
        fClientSecret      = "client_secret"
        fEventID           = "event_id"
        fID                = "id"
        fImpersonateEmail  = "impersonate_email"
        fJSON              = "json"
        fMode              = "mode"
        fResourceID        = "resource_id"
        fState             = "state"
        fSubscriptionID    = "sub_id"
        fUseServiceAccount = "use_service_account"
)

func Init() {
        // Ping.
        http.HandleFunc(AppPathPrefix+"/ping",
                httputils.DoHandleJSONData([]byte("{}")))

        // Bindings.
        HandleCall("/bindings", bindings)

        // OAuth2 (Google Calendar) connect commands and callbacks.
        HandleCall("/oauth2/connect", oauth2Connect)
        HandleCall("/oauth2/complete", oauth2Complete)

        // Google Calendar webhook handler.
        HandleCall(appspath.Webhook, webhookReceived)

        // Command submit handlers.
        HandleCommand(configure)
        HandleCommand(connect)
        HandleCommand(debugGetEvent)
        HandleCommand(debugListCalendars)
        HandleCommand(debugListEvents)
        HandleCommand(debugStopWatch)
        HandleCommand(debugUserInfo)
        HandleCommand(disconnect)
        HandleCommand(info)
        HandleCommand(watchList)
        HandleCommand(watchStart)
        HandleCommand(watchStop)

        // Configure modal (submit+source).
        HandleCall("/configure-modal", RequireAdmin(
                configureModal))
        HandleCall("/f/configure-modal", RequireAdmin(
                FormHandler(configureModalForm)))

        // Lookups TODO rework when the paths are decoupled from forms.
        HandleCall("/q/cal", RequireGoogleAuth(
                LookupHandler(calendarIDLookup)))
        HandleCall("/q/event", RequireGoogleAuth(
                LookupHandler(eventLookup)))
        HandleCall("/q/sub", RequireGoogleAuth(
                LookupHandler(subscriptionIDLookup)))

        // Log NOT FOUND.
        http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
                Log.Warnw("not found", "path", req.URL.Path, "method", req.Method)
                http.Error(w, fmt.Sprintf("Not found: %s %q", req.Method, req.URL.Path), http.StatusNotFound)
        })
}
function/auth.go:1: File is not `gofmt`-ed with `-s` (gofmt)
package function

import (
        "context"
        "fmt"

        "github.com/pkg/errors"
        "golang.org/x/oauth2"
        "golang.org/x/oauth2/google"
        "google.golang.org/api/calendar/v3"
        oauth2api "google.golang.org/api/oauth2/v2"
        "google.golang.org/api/option"

        "github.com/mattermost/mattermost-plugin-apps/apps"
        "github.com/mattermost/mattermost-plugin-apps/apps/appclient"
        "github.com/mattermost/mattermost-plugin-apps/utils"
)

var OAuth2Scopes = []string{
        calendar.CalendarScope,
        "https://www.googleapis.com/auth/userinfo.profile",
        "https://www.googleapis.com/auth/userinfo.email",
}

func oauth2Config(creq CallRequest) *oauth2.Config {
        return &oauth2.Config{
                ClientID:     creq.Context.OAuth2.ClientID,
                ClientSecret: creq.Context.OAuth2.ClientSecret,
                Endpoint:     google.Endpoint,
                RedirectURL:  creq.Context.OAuth2.CompleteURL,
                Scopes:       OAuth2Scopes,
        }
}

func oauth2Connect(creq CallRequest) apps.CallResponse {
        state := creq.GetValue(fState, "")
        url := oauth2Config(creq).AuthCodeURL(state, oauth2.AccessTypeOffline)
        return apps.NewDataResponse(url)
}

func oauth2Complete(creq CallRequest) apps.CallResponse {
        code := creq.GetValue("code", "")
        oauth2Config := oauth2Config(creq)

        token, err := oauth2Config.Exchange(creq.ctx, code)
        if err != nil {
                return apps.NewErrorResponse(errors.Wrap(err, "failed token exchange"))
        }

        oauth2Service, err := oauth2api.NewService(creq.ctx,
                option.WithTokenSource(oauth2Config.TokenSource(creq.ctx, token)))
        if err != nil {
                return apps.NewErrorResponse(errors.Wrap(err, "failed to get OAuth2 service"))
        }
        uiService := oauth2api.NewUserinfoService(oauth2Service)
        ui, err := uiService.V2.Me.Get().Do()
        if err != nil {
                return apps.NewErrorResponse(errors.Wrap(err, "failed to get user info"))
        }

        asActingUser := appclient.AsActingUser(creq.Context)
        err = asActingUser.StoreOAuth2User(User{
                Token: token,
                Email: ui.Email,
                ID:    ui.Id,
        })
        if err != nil {
                return apps.NewErrorResponse(errors.Wrap(err, "failed to store OAuth user info to Mattermost"))
        }
        return apps.NewTextResponse("completed connecting to Google Calendar with OAuth2.")
}

type ServiceAccount struct {
        // Mode is either "api_key", "account_json", or "" implying no service
        // account is to be used, and the corresponding functionality disabled.
        Mode        string `json:"mode,omitempty"`         // fMode
        APIKey      string `json:"api_key,omitempty"`      // fAPIKey
        AccountJSON string `json:"account_json,omitempty"` // fAccountJSON
}

func NewServiceAccount(mode, apiKey, serviceAccout string) ServiceAccount {
        sa := ServiceAccount{
                Mode: mode,
        }
        switch mode {
        case fAPIKey:
                sa.APIKey = apiKey
        case fAccountJSON:
                sa.AccountJSON = serviceAccout
        }
        return sa
}

func (sa ServiceAccount) String() string {
        switch sa.Mode {
        case fAPIKey:
                return fmt.Sprintf("API Key, ending in %q", utils.LastN(sa.APIKey, 8))
        case fAccountJSON:
                return fmt.Sprintf("Account JSON, ending in %q", utils.LastN(sa.AccountJSON, 32))
        default:
                return "No service account"
        }
}

func (sa ServiceAccount) AuthOption(ctx context.Context, userEmail string) (option.ClientOption, error) {
        switch sa.Mode {
        case fAccountJSON:
                config, err := google.JWTConfigFromJSON(
                        []byte(sa.AccountJSON),
                        calendar.CalendarScope)
                if err != nil {
                        return nil, fmt.Errorf("JWTConfigFromJSON: %v", err)
                }
                config.Subject = userEmail

                return option.WithTokenSource(config.TokenSource(ctx)), nil

        case fAPIKey:
                return option.WithAPIKey(sa.APIKey), nil

        default:
                return nil, errors.New("service account authentication is not configured")
        }
}
function/command.go:23:25: unused-parameter: parameter 'creq' seems to be unused, consider removing or renaming it as _ (revive)
func (c Command) Submit(creq CallRequest) *apps.Call {
                        ^
server/plugin.go:29:28: unused-parameter: parameter 'c' seems to be unused, consider removing or renaming it as _ (revive)
func (p *Plugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
                           ^
make: *** [Makefile:44: check-style] Error 1