From a552073d18590d144cfe39effb45b670359d9e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferdinand=20M=C3=BCtsch?= Date: Thu, 21 Jan 2021 23:26:50 +0100 Subject: [PATCH] feat: ui for configuring wakatime integration --- main.go | 1 + middlewares/authenticate_test.go | 25 --------- mocks/user_service.go | 5 ++ routes/settings.go | 15 ++++++ services/services.go | 1 + services/user.go | 5 ++ views/settings.tpl.html | 93 +++++++++++++++++++++++++++----- 7 files changed, 107 insertions(+), 38 deletions(-) diff --git a/main.go b/main.go index 7604e6b..ccb8995 100644 --- a/main.go +++ b/main.go @@ -168,6 +168,7 @@ func main() { settingsRouter.Path("/language_mappings/delete").Methods(http.MethodPost).HandlerFunc(settingsHandler.DeleteLanguageMapping) settingsRouter.Path("/reset").Methods(http.MethodPost).HandlerFunc(settingsHandler.PostResetApiKey) settingsRouter.Path("/badges").Methods(http.MethodPost).HandlerFunc(settingsHandler.PostToggleBadges) + settingsRouter.Path("/wakatime_integration").Methods(http.MethodPost).HandlerFunc(settingsHandler.PostSetWakatimeApiKey) settingsRouter.Path("/regenerate").Methods(http.MethodPost).HandlerFunc(settingsHandler.PostRegenerateSummaries) // API Routes diff --git a/middlewares/authenticate_test.go b/middlewares/authenticate_test.go index cc42b2e..960d269 100644 --- a/middlewares/authenticate_test.go +++ b/middlewares/authenticate_test.go @@ -6,7 +6,6 @@ import ( "github.com/muety/wakapi/mocks" "github.com/muety/wakapi/models" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "net/http" "testing" ) @@ -33,30 +32,6 @@ func TestAuthenticateMiddleware_tryGetUserByApiKey_Success(t *testing.T) { assert.Equal(t, testUser, result) } -func TestAuthenticateMiddleware_tryGetUserByApiKey_GetFromCache(t *testing.T) { - testApiKey := "z5uig69cn9ut93n" - testToken := base64.StdEncoding.EncodeToString([]byte(testApiKey)) - testUser := &models.User{ApiKey: testApiKey} - - mockRequest := &http.Request{ - Header: http.Header{ - "Authorization": []string{fmt.Sprintf("Basic %s", testToken)}, - }, - } - - userServiceMock := new(mocks.UserServiceMock) - userServiceMock.On("GetUserByKey", testApiKey).Return(testUser, nil) - - sut := NewAuthenticateMiddleware(userServiceMock, []string{}) - sut.cache.SetDefault(testApiKey, testUser) - - result, err := sut.tryGetUserByApiKey(mockRequest) - - assert.Nil(t, err) - assert.Equal(t, testUser, result) - userServiceMock.AssertNotCalled(t, "GetUserByKey", mock.Anything) -} - func TestAuthenticateMiddleware_tryGetUserByApiKey_InvalidHeader(t *testing.T) { testApiKey := "z5uig69cn9ut93n" testToken := base64.StdEncoding.EncodeToString([]byte(testApiKey)) diff --git a/mocks/user_service.go b/mocks/user_service.go index a91d2f9..bb3847d 100644 --- a/mocks/user_service.go +++ b/mocks/user_service.go @@ -44,6 +44,11 @@ func (m *UserServiceMock) ToggleBadges(user *models.User) (*models.User, error) return args.Get(0).(*models.User), args.Error(1) } +func (m *UserServiceMock) SetWakatimeApiKey(user *models.User, s string) (*models.User, error) { + args := m.Called(user, s) + return args.Get(0).(*models.User), args.Error(1) +} + func (m *UserServiceMock) MigrateMd5Password(user *models.User, login *models.Login) (*models.User, error) { args := m.Called(user, login) return args.Get(0).(*models.User), args.Error(1) diff --git a/routes/settings.go b/routes/settings.go index 4e4d115..61eba3f 100644 --- a/routes/settings.go +++ b/routes/settings.go @@ -233,6 +233,21 @@ func (h *SettingsHandler) PostResetApiKey(w http.ResponseWriter, r *http.Request templates[conf.SettingsTemplate].Execute(w, h.buildViewModel(r).WithSuccess(msg)) } +func (h *SettingsHandler) PostSetWakatimeApiKey(w http.ResponseWriter, r *http.Request) { + if h.config.IsDev() { + loadTemplates() + } + + user := r.Context().Value(models.UserKey).(*models.User) + if _, err := h.userSrvc.SetWakatimeApiKey(user, r.PostFormValue("api_key")); err != nil { + w.WriteHeader(http.StatusInternalServerError) + templates[conf.SettingsTemplate].Execute(w, h.buildViewModel(r).WithError("internal server error")) + return + } + + templates[conf.SettingsTemplate].Execute(w, h.buildViewModel(r).WithSuccess("Wakatime API Key updated successfully")) +} + func (h *SettingsHandler) PostToggleBadges(w http.ResponseWriter, r *http.Request) { if h.config.IsDev() { loadTemplates() diff --git a/services/services.go b/services/services.go index 7ae92f5..c0f1f3b 100644 --- a/services/services.go +++ b/services/services.go @@ -63,5 +63,6 @@ type IUserService interface { Update(*models.User) (*models.User, error) ResetApiKey(*models.User) (*models.User, error) ToggleBadges(*models.User) (*models.User, error) + SetWakatimeApiKey(*models.User, string) (*models.User, error) MigrateMd5Password(*models.User, *models.Login) (*models.User, error) } diff --git a/services/user.go b/services/user.go index 27d298c..a908965 100644 --- a/services/user.go +++ b/services/user.go @@ -88,6 +88,11 @@ func (srv *UserService) ToggleBadges(user *models.User) (*models.User, error) { return srv.repository.UpdateField(user, "badges_enabled", !user.BadgesEnabled) } +func (srv *UserService) SetWakatimeApiKey(user *models.User, apiKey string) (*models.User, error) { + srv.cache.Flush() + return srv.repository.UpdateField(user, "wakatime_api_key", apiKey) +} + func (srv *UserService) MigrateMd5Password(user *models.User, login *models.Login) (*models.User, error) { srv.cache.Flush() user.Password = login.Password diff --git a/views/settings.tpl.html b/views/settings.tpl.html index 3c1ab8c..7f074d0 100644 --- a/views/settings.tpl.html +++ b/views/settings.tpl.html @@ -9,9 +9,11 @@ .inline-bullet-list li a { text-decoration: underline; } + .inline-bullet-list li:after { content: "•"; } + .inline-bullet-list li:last-child:after { content: ""; } @@ -32,7 +34,7 @@
-
-
+

Change Password -

+
@@ -87,9 +92,9 @@
-
+

Reset API Key -

+
@@ -107,9 +112,9 @@
-
+

Aliases -

+
You can specify aliases for any type of entity. For instance, you can define a rule, that both {{ if .Aliases }} -

Rules

+

Rules

{{ range $i, $alias := .Aliases }}
- @@ -148,7 +154,7 @@
{{end}} -

Add Rule

+

Add Rule

Map @@ -188,7 +194,7 @@
{{ if .LanguageMappings }} -

Rules

+

Rules

{{ range $i, $mapping := .LanguageMappings }}
@@ -199,7 +205,8 @@
- @@ -208,7 +215,7 @@
{{end}} -

Add Rule

+

Add Rule

When filename ends in @@ -295,6 +302,66 @@
+
+

+ Integrations +

+ +
+

+ Wakatime +

+ +
+ WakaTime Logo +

You can connect Wakapi with the official Wakatime in a way + that all heartbeats sent to Wakapi are relayed to Wakatime. This way, you can use both services + at + the same time. To get started, get your API key and paste it here.

+
+ +
+ + {{ $placeholderText := "Paste your Wakatime API key here ..." }} + {{ if .User.WakatimeApiKey }} + {{ $placeholderText = "********" }} + {{ end }} + +
+ + +
+ {{ if not .User.WakatimeApiKey }} + + {{ else }} + + {{ end }} +
+
+
+ +

+ 👉 Please note: + When enabling this feature, the operators of this server will, in theory (!), have unlimited access to your data stored in Wakatime. If you are concerned about your privacy, please do not enable this integration or wait for OAuth 2 authentication (#94) to be implemented. +

+
+
+ +
⚠️ Danger Zone