Przeglądaj źródła

chore: fix gocyclo issues

jamesread 8 miesięcy temu
rodzic
commit
60814b97e2

+ 46 - 36
service/internal/api/api.go

@@ -321,40 +321,50 @@ func (api *oliveTinAPI) GetActionBinding(ctx ctx.Context, req *connect.Request[a
 func (api *oliveTinAPI) GetDashboard(ctx ctx.Context, req *connect.Request[apiv1.GetDashboardRequest]) (*connect.Response[apiv1.GetDashboardResponse], error) {
 	user := acl.UserFromContext(ctx, api.cfg)
 
+	if err := api.checkDashboardAccess(user); err != nil {
+		return nil, err
+	}
+
+	dashboardRenderRequest := api.createDashboardRenderRequest(user)
+
+	if api.isDefaultDashboard(req.Msg.Title) {
+		return api.buildDefaultDashboardResponse(dashboardRenderRequest)
+	}
+
+	return api.buildCustomDashboardResponse(dashboardRenderRequest, req.Msg.Title)
+}
+
+func (api *oliveTinAPI) checkDashboardAccess(user *acl.AuthenticatedUser) error {
 	if user.IsGuest() && api.cfg.AuthRequireGuestsToLogin {
-		return nil, connect.NewError(connect.CodePermissionDenied, fmt.Errorf("guests are not allowed to access the dashboard"))
+		return connect.NewError(connect.CodePermissionDenied, fmt.Errorf("guests are not allowed to access the dashboard"))
 	}
+	return nil
+}
 
-	dashboardRenderRequest := &DashboardRenderRequest{
+func (api *oliveTinAPI) createDashboardRenderRequest(user *acl.AuthenticatedUser) *DashboardRenderRequest {
+	return &DashboardRenderRequest{
 		AuthenticatedUser: user,
 		cfg:               api.cfg,
 		ex:                api.executor,
 	}
+}
 
-	if req.Msg.Title == "default" || req.Msg.Title == "" || req.Msg.Title == "Actions" {
-		db := buildDefaultDashboard(dashboardRenderRequest)
-		res := &apiv1.GetDashboardResponse{
-			Dashboard: db,
-		}
-		return connect.NewResponse(res), nil
-	}
+func (api *oliveTinAPI) isDefaultDashboard(title string) bool {
+	return title == "default" || title == "" || title == "Actions"
+}
 
+func (api *oliveTinAPI) buildDefaultDashboardResponse(rr *DashboardRenderRequest) (*connect.Response[apiv1.GetDashboardResponse], error) {
+	db := buildDefaultDashboard(rr)
 	res := &apiv1.GetDashboardResponse{
-		Dashboard: renderDashboard(dashboardRenderRequest, req.Msg.Title),
-	}
-
-	/*
-		if len(res.Actions) == 0 {
-			log.WithFields(log.Fields{
-				"username":         user.Username,
-				"usergroupLine":    user.UsergroupLine,
-				"provider":         user.Provider,
-				"acls":             user.Acls,
-				"availableActions": len(api.cfg.Actions),
-			}).Warn("Zero actions found for user")
-		}
-	*/
+		Dashboard: db,
+	}
+	return connect.NewResponse(res), nil
+}
 
+func (api *oliveTinAPI) buildCustomDashboardResponse(rr *DashboardRenderRequest, title string) (*connect.Response[apiv1.GetDashboardResponse], error) {
+	res := &apiv1.GetDashboardResponse{
+		Dashboard: renderDashboard(rr, title),
+	}
 	return connect.NewResponse(res), nil
 }
 
@@ -595,31 +605,31 @@ func (api *oliveTinAPI) Init(ctx ctx.Context, req *connect.Request[apiv1.InitReq
 
 func (api *oliveTinAPI) buildRootDashboards(user *acl.AuthenticatedUser, dashboards []*config.DashboardComponent) []string {
 	var rootDashboards []string
+	dashboardRenderRequest := api.createDashboardRenderRequest(user)
 
-	dashboardRenderRequest := &DashboardRenderRequest{
-		AuthenticatedUser: user,
-		cfg:               api.cfg,
-		ex:                api.executor,
-	}
+	api.addDefaultDashboardIfNeeded(&rootDashboards, dashboardRenderRequest)
+	api.addCustomDashboards(&rootDashboards, dashboards, dashboardRenderRequest)
 
-	defaultDashboard := buildDefaultDashboard(dashboardRenderRequest)
+	return rootDashboards
+}
 
+func (api *oliveTinAPI) addDefaultDashboardIfNeeded(rootDashboards *[]string, rr *DashboardRenderRequest) {
+	defaultDashboard := buildDefaultDashboard(rr)
 	if defaultDashboard != nil && len(defaultDashboard.Contents) > 0 {
 		log.Infof("defaultDashboard: %+v", defaultDashboard.Contents)
-		rootDashboards = append(rootDashboards, "Actions")
+		*rootDashboards = append(*rootDashboards, "Actions")
 	}
+}
 
+func (api *oliveTinAPI) addCustomDashboards(rootDashboards *[]string, dashboards []*config.DashboardComponent, rr *DashboardRenderRequest) {
 	for _, dashboard := range dashboards {
 		// We have to build the dashboard response instead of just looping over config.dashboards,
 		// because we need to check if the user has access to the dashboard
-		db := renderDashboard(dashboardRenderRequest, dashboard.Title)
-
+		db := renderDashboard(rr, dashboard.Title)
 		if db != nil {
-			rootDashboards = append(rootDashboards, dashboard.Title)
+			*rootDashboards = append(*rootDashboards, dashboard.Title)
 		}
 	}
-
-	return rootDashboards
 }
 
 func buildPublicOAuth2ProvidersList(cfg *config.Config) []*apiv1.OAuth2Provider {
@@ -720,7 +730,7 @@ func (api *oliveTinAPI) GetEntity(ctx ctx.Context, req *connect.Request[apiv1.Ge
 
 	log.Infof("msg: %+v", req.Msg)
 
-	if instances == nil || len(instances) == 0 {
+	if len(instances) == 0 {
 		return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("entity type %s not found", req.Msg.Type))
 	}
 

+ 44 - 20
service/internal/api/dashboards.go

@@ -14,32 +14,44 @@ func renderDashboard(rr *DashboardRenderRequest, dashboardTitle string) *apiv1.D
 		return buildDefaultDashboard(rr)
 	}
 
+	return findAndRenderDashboard(rr, dashboardTitle)
+}
+
+func findAndRenderDashboard(rr *DashboardRenderRequest, dashboardTitle string) *apiv1.Dashboard {
 	for _, dashboard := range rr.cfg.Dashboards {
 		if dashboard.Title != dashboardTitle {
 			continue
 		}
 
 		if len(dashboard.Contents) == 0 {
-			log.WithFields(log.Fields{
-				"dashboard": dashboard.Title,
-				"username":  rr.AuthenticatedUser.Username,
-			}).Debugf("Dashboard has no readable contents, so it will not be visible in the web ui")
+			logEmptyDashboard(dashboard.Title, rr.AuthenticatedUser.Username)
 			return nil
 		}
 
-		return &apiv1.Dashboard{
-			Title:    dashboard.Title,
-			Contents: sortActions(removeNulls(getDashboardComponentContents(dashboard, rr))),
-		}
+		return buildDashboardFromConfig(dashboard, rr)
 	}
 
 	return nil
 }
 
+func logEmptyDashboard(dashboardTitle, username string) {
+	log.WithFields(log.Fields{
+		"dashboard": dashboardTitle,
+		"username":  username,
+	}).Debugf("Dashboard has no readable contents, so it will not be visible in the web ui")
+}
+
+func buildDashboardFromConfig(dashboard *config.DashboardComponent, rr *DashboardRenderRequest) *apiv1.Dashboard {
+	return &apiv1.Dashboard{
+		Title:    dashboard.Title,
+		Contents: sortActions(removeNulls(getDashboardComponentContents(dashboard, rr))),
+	}
+}
+
 //gocyclo:ignore
 func buildDefaultDashboard(rr *DashboardRenderRequest) *apiv1.Dashboard {
 	db := &apiv1.Dashboard{
-		Title:    "Default",
+		Title:    "Actions",
 		Contents: make([]*apiv1.DashboardComponent, 0),
 	}
 
@@ -112,28 +124,40 @@ func removeNulls(components []*apiv1.DashboardComponent) []*apiv1.DashboardCompo
 
 func getDashboardComponentContents(dashboard *config.DashboardComponent, rr *DashboardRenderRequest) []*apiv1.DashboardComponent {
 	ret := make([]*apiv1.DashboardComponent, 0)
+	rootFieldset := createRootFieldset()
+
+	for _, subitem := range dashboard.Contents {
+		processDashboardSubitem(subitem, rr, &ret, rootFieldset)
+	}
+
+	return appendRootFieldsetIfNeeded(ret, rootFieldset)
+}
 
-	rootFieldset := &apiv1.DashboardComponent{
+func createRootFieldset() *apiv1.DashboardComponent {
+	return &apiv1.DashboardComponent{
 		Type:     "fieldset",
 		Title:    "Actions",
 		Contents: make([]*apiv1.DashboardComponent, 0),
 	}
+}
 
-	for _, subitem := range dashboard.Contents {
-		if subitem.Type == "fieldset" && subitem.Entity != "" {
-			ret = append(ret, buildEntityFieldsets(subitem.Entity, subitem, rr)...)
-		} else if subitem.Type == "fieldset" {
-			// Handle regular fieldsets by creating them directly
-			ret = append(ret, buildDashboardComponentSimple(subitem, rr))
-		} else {
-			rootFieldset.Contents = append(rootFieldset.Contents, buildDashboardComponentSimple(subitem, rr))
-		}
+func processDashboardSubitem(subitem *config.DashboardComponent, rr *DashboardRenderRequest, ret *[]*apiv1.DashboardComponent, rootFieldset *apiv1.DashboardComponent) {
+	if subitem.Type != "fieldset" {
+		rootFieldset.Contents = append(rootFieldset.Contents, buildDashboardComponentSimple(subitem, rr))
+		return
 	}
 
+	if subitem.Entity != "" {
+		*ret = append(*ret, buildEntityFieldsets(subitem.Entity, subitem, rr)...)
+	} else {
+		*ret = append(*ret, buildDashboardComponentSimple(subitem, rr))
+	}
+}
+
+func appendRootFieldsetIfNeeded(ret []*apiv1.DashboardComponent, rootFieldset *apiv1.DashboardComponent) []*apiv1.DashboardComponent {
 	if len(rootFieldset.Contents) > 0 {
 		ret = append(ret, rootFieldset)
 	}
-
 	return ret
 }
 

+ 30 - 18
service/internal/executor/arguments_test.go

@@ -7,8 +7,9 @@ import (
 	config "github.com/OliveTin/OliveTin/internal/config"
 	"github.com/OliveTin/OliveTin/internal/entities"
 
-	"github.com/stretchr/testify/assert"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
 )
 
 func TestSanitizeUnsafe(t *testing.T) {
@@ -254,9 +255,9 @@ func TestTypeSafetyCheckRawStringMultiline(t *testing.T) {
 
 func TestTypeSafetyCheckUnicodeIdentifier(t *testing.T) {
 	tests := []struct {
-		name     string
-		field    string
-		value    string
+		name         string
+		field        string
+		value        string
 		expectsError bool
 	}{
 		{"Valid unicode identifier", "name", "hello_world", false},
@@ -273,24 +274,35 @@ func TestTypeSafetyCheckUnicodeIdentifier(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			err := TypeSafetyCheck(tt.field, tt.value, "unicode_identifier")
-
-			if tt.expectsError {
-				if err == nil {
-					t.Errorf("Expected error for value '%s', but got none", tt.value)
-				} else {
-					t.Logf("Received expected error for value '%s': %v", tt.value, err)
-				}
-			} else {
-				if err != nil {
-					t.Errorf("Expected no error for value '%s', but got: %v", tt.value, err)
-				} else {
-					t.Logf("No error for valid value '%s' as expected", tt.value)
-				}
-			}
+			validateTypeSafetyResult(t, tt.value, tt.expectsError, err)
 		})
 	}
 }
 
+func validateTypeSafetyResult(t *testing.T, value string, expectsError bool, err error) {
+	if expectsError {
+		assertErrorExpected(t, value, err)
+	} else {
+		assertNoErrorExpected(t, value, err)
+	}
+}
+
+func assertErrorExpected(t *testing.T, value string, err error) {
+	if err == nil {
+		t.Errorf("Expected error for value '%s', but got none", value)
+	} else {
+		t.Logf("Received expected error for value '%s': %v", value, err)
+	}
+}
+
+func assertNoErrorExpected(t *testing.T, value string, err error) {
+	if err != nil {
+		t.Errorf("Expected no error for value '%s', but got: %v", value, err)
+	} else {
+		t.Logf("No error for valid value '%s' as expected", value)
+	}
+}
+
 func TestTypeSafetyCheckAsciiIdentifier(t *testing.T) {
 	tests := []struct {
 		name     string