Skip to content

Commit

Permalink
Merge pull request #828 from qor5/activity-no-perm
Browse files Browse the repository at this point in the history
activity: add SkipResPermCheck
  • Loading branch information
molon authored Jan 8, 2025
2 parents 661bed6 + ecf5d08 commit 28afd47
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 37 deletions.
85 changes: 51 additions & 34 deletions activity/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,28 +100,34 @@ func setupEditing(eb *presets.EditingBuilder) {
func setupListing(b *presets.Builder, lb *presets.ListingBuilder, op *gorm2op.DataOperatorBuilder, ab *Builder) {
lb.RelayPagination(gorm2op.KeysetBasedPagination(true))
lb.SearchFunc(func(ctx *web.EventContext, params *presets.SearchParams) (result *presets.SearchResult, err error) {
var modelLabels []string
// err = ab.db.Model(&ActivityLog{}).Select("DISTINCT model_label AS model_label").Pluck("model_label", &modelLabels).Error
// if err != nil {
// return nil, err
// }
for _, m := range ab.models {
if m.label != nil {
modelLabels = append(modelLabels, m.label())
if !ab.skipResPermCheck {
var modelLabels []string
// err = ab.db.Model(&ActivityLog{}).Select("DISTINCT model_label AS model_label").Pluck("model_label", &modelLabels).Error
// if err != nil {
// return nil, err
// }
for _, m := range ab.models {
if m.label != nil {
modelLabels = append(modelLabels, m.label())
}
}
}
modelLabels = lo.Uniq(modelLabels)
for _, resourceSign := range modelLabels {
if resourceSign == "" || resourceSign == NopModelLabel {
continue
signsNoPerm := []string{}
modelLabels = lo.Uniq(modelLabels)
for _, resourceSign := range modelLabels {
if resourceSign == "" || resourceSign == NopModelLabel {
continue
}
if b.GetVerifier().Spawn().SnakeOn(resourceSign).Do(presets.PermList).WithReq(ctx.R).IsAllowed() == nil {
continue
}
signsNoPerm = append(signsNoPerm, resourceSign)
}
if b.GetVerifier().Spawn().SnakeOn(resourceSign).Do(presets.PermList).WithReq(ctx.R).IsAllowed() == nil {
continue
if len(signsNoPerm) > 0 {
params.SQLConditions = append(params.SQLConditions, &presets.SQLCondition{
Query: "model_label NOT IN ?",
Args: []any{signsNoPerm},
})
}
params.SQLConditions = append(params.SQLConditions, &presets.SQLCondition{
Query: "model_label <> ?",
Args: []any{resourceSign},
})
}

params.SQLConditions = append(params.SQLConditions, &presets.SQLCondition{
Expand Down Expand Up @@ -315,9 +321,11 @@ func setupDetailing(b *presets.Builder, dp *presets.DetailingBuilder, op *gorm2o
}
log := r.(*ActivityLog)

if log.ModelLabel != "" && log.ModelLabel != NopModelLabel {
if b.GetVerifier().Spawn().SnakeOn(log.ModelLabel).Do(presets.PermGet).WithReq(ctx.R).IsAllowed() != nil {
return nil, perm.PermissionDenied
if !ab.skipResPermCheck {
if log.ModelLabel != "" && log.ModelLabel != NopModelLabel {
if b.GetVerifier().Spawn().SnakeOn(log.ModelLabel).Do(presets.PermGet).WithReq(ctx.R).IsAllowed() != nil {
return nil, perm.PermissionDenied
}
}
}

Expand All @@ -335,7 +343,13 @@ func setupDetailing(b *presets.Builder, dp *presets.DetailingBuilder, op *gorm2o
pmsgr = presets.MustGetMessages(ctx.R)
hideDetailTop = cast.ToBool(ctx.R.Form.Get(paramHideDetailTop))
actionLabel = getActionLabel(ctx, log.Action)
hasPermGET = true
)
if log.ModelLabel != "" && log.ModelLabel != NopModelLabel {
if b.GetVerifier().Spawn().SnakeOn(log.ModelLabel).Do(presets.PermGet).WithReq(ctx.R).IsAllowed() != nil {
hasPermGET = false
}
}
var children []h.HTMLComponent
if !hideDetailTop {
children = append(children, VCard().Elevation(0).Children(
Expand All @@ -353,18 +367,21 @@ func setupDetailing(b *presets.Builder, dp *presets.DetailingBuilder, op *gorm2o
)),
h.Tr(h.Td(h.Text(msgr.ModelLabel)), h.Td().Attr("v-pre", true).Text(cmp.Or(log.ModelLabel, NopModelLabel))),
h.Tr(h.Td(h.Text(msgr.ModelKeys)), h.Td().Attr("v-pre", true).Text(log.ModelKeys)),
// h.Iff(log.ModelLink != "", func() h.HTMLComponent {
// return h.Tr(h.Td(h.Text(msgr.ModelLink)), h.Td(
// VBtn(msgr.MoreInfo).Class("text-none text-overline d-flex align-center").
// Variant(VariantTonal).Color(ColorPrimary).Size(SizeXSmall).PrependIcon("mdi-open-in-new").
// Attr("@click", web.POST().
// EventFunc(actions.DetailingDrawer).
// Query(presets.ParamOverlay, actions.Dialog).
// URL(log.ModelLink).
// Go(),
// ),
// ))
// }),
h.Iff(hasPermGET && log.ModelLink != "", func() h.HTMLComponent {
onClick := web.Plaid().PushStateURL(log.ModelLink).Go()
href := log.ModelLink
return h.Tr(h.Td(h.Text(msgr.ModelLink)), h.Td(
h.A(
VBtn(msgr.MoreInfo).Class("text-none text-overline d-flex align-center").
Variant(VariantTonal).Color(ColorPrimary).Size(SizeXSmall).PrependIcon("mdi-open-in-new"),
).Href(href).Attr("@click", fmt.Sprintf(`(e) => {
if (e.metaKey || e.ctrlKey) { return; }
e.stopPropagation();
e.preventDefault();
%s;
}`, onClick)),
))
}),
h.Tr(h.Td(h.Text(msgr.ModelCreatedAt)), h.Td(h.Text(log.CreatedAt.Format(timeFormat)))),
),
),
Expand Down
11 changes: 8 additions & 3 deletions activity/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ type Builder struct {
findUsersFunc func(ctx context.Context, ids []string) (map[string]*User, error)
maxCountShowInTimeline int
findLogsForTimelineFunc func(ctx context.Context, db *gorm.DB, modelName, modelKeys string) (logs []*ActivityLog, hasMore bool, err error)

mu sync.RWMutex
logModelBuilders map[*presets.Builder]*presets.ModelBuilder
skipResPermCheck bool
mu sync.RWMutex
logModelBuilders map[*presets.Builder]*presets.ModelBuilder
}

// @snippet_end
Expand All @@ -59,6 +59,11 @@ func (ab *Builder) PermPolicy(v *perm.PolicyBuilder) *Builder {
return ab
}

func (ab *Builder) SkipResPermCheck(v bool) *Builder {
ab.skipResPermCheck = v
return ab
}

func (ab *Builder) FindUsersFunc(v func(ctx context.Context, ids []string) (map[string]*User, error)) *Builder {
ab.findUsersFunc = v
return ab
Expand Down
53 changes: 53 additions & 0 deletions docs/docsrc/examples/examples_admin/activity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,59 @@ func TestActivityAdmin(t *testing.T) {
"没有可显示的记录",
},
},

{
Name: "Activity logs with skipResPermCheck without PermList",
Debug: true,
HandlerMaker: func() http.Handler {
pb := presets.New()
pb.Permission(
perm.New().Policies(
perm.PolicyFor(perm.Anybody).WhoAre(perm.Allowed).ToDo(perm.Anything).On(perm.Anything),
perm.PolicyFor(perm.Anybody).WhoAre(perm.Denied).ToDo(presets.PermList).On("*:presets:with_activity_products:*"),
),
)
activityExample(pb, TestDB, func(mb *presets.ModelBuilder, ab *activity.Builder) {
ab.SkipResPermCheck(true)
pb.Use(ab)
})
return pb
},
ReqFunc: func() *http.Request {
// activityData.TruncatePut(dbr)
return httptest.NewRequest("GET", "/activity-logs?lang=zh", nil)
},
ExpectPageBodyNotContains: []string{
"没有可显示的记录",
},
},

{
Name: "Activity log detail for edit action with skipResPermCheck without PermGet",
Debug: true,
HandlerMaker: func() http.Handler {
pb := presets.New()
pb.Permission(
perm.New().Policies(
perm.PolicyFor(perm.Anybody).WhoAre(perm.Allowed).ToDo(perm.Anything).On(perm.Anything),
perm.PolicyFor(perm.Anybody).WhoAre(perm.Denied).ToDo(presets.PermGet).On("*:presets:with_activity_products:*"),
),
)
activityExample(pb, TestDB, func(mb *presets.ModelBuilder, ab *activity.Builder) {
ab.SkipResPermCheck(true)
pb.Use(ab)
})
return pb
},
ReqFunc: func() *http.Request {
// activityData.TruncatePut(dbr)
req := multipartestutils.NewMultipartBuilder().
PageURL("/activity-logs?__execute_event__=presets_DetailingDrawer&id=87").
BuildEventFuncRequest()
return req
},
ExpectPortalUpdate0ContainsInOrder: []string{"Activity Log", "87"},
},
}

for _, c := range cases {
Expand Down

0 comments on commit 28afd47

Please sign in to comment.