1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-24 13:48:49 +08:00

NOISSUE - Enable OwnerID Filtering For Admin (#1857)

* Enable OwnerID Filtering For Admin

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Update things/clients/service.go

Co-authored-by: Sammy Kerata Oina <44265300+SammyOina@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Update things/clients/service.go

Co-authored-by: Sammy Kerata Oina <44265300+SammyOina@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Update things/clients/service.go

Co-authored-by: Sammy Kerata Oina <44265300+SammyOina@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Update things/clients/service.go

Co-authored-by: Sammy Kerata Oina <44265300+SammyOina@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Combine the Switch Statement

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

---------

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>
Co-authored-by: Sammy Kerata Oina <44265300+SammyOina@users.noreply.github.com>
This commit is contained in:
b1ackd0t 2023-07-13 17:27:57 +03:00 committed by GitHub
parent 726e358187
commit aee0081864
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 110 additions and 69 deletions

View File

@ -1483,7 +1483,7 @@ components:
example: 'admin@example.com'
Owner:
name: owner
name: owner_id
description: Thing's owner.
in: query
schema:

View File

@ -1477,7 +1477,7 @@ components:
example: 'admin@example.com'
Owner:
name: owner
name: owner_id
description: User's owner.
in: query
schema:

View File

@ -4,16 +4,14 @@ import "github.com/mainflux/mainflux/pkg/clients"
// Page contains page metadata that helps navigation.
type Page struct {
Total uint64 `json:"total"`
Offset uint64 `json:"offset"`
Limit uint64 `json:"limit"`
Name string `json:"name,omitempty"`
OwnerID string `json:"identity,omitempty"`
Tag string `json:"tag,omitempty"`
Metadata clients.Metadata `json:"metadata,omitempty"`
SharedBy string `json:"shared_by,omitempty"`
Status clients.Status `json:"status,omitempty"`
Subject string `json:"subject,omitempty"`
Action string `json:"action,omitempty"`
Disconnected bool `json:"disconnected,omitempty"` // Used for connected or disconnected lists
Total uint64 `json:"total"`
Offset uint64 `json:"offset"`
Limit uint64 `json:"limit"`
Name string `json:"name,omitempty"`
OwnerID string `json:"identity,omitempty"`
Tag string `json:"tag,omitempty"`
Metadata clients.Metadata `json:"metadata,omitempty"`
Status clients.Status `json:"status,omitempty"`
Subject string `json:"subject,omitempty"`
Action string `json:"action,omitempty"`
}

View File

@ -120,7 +120,7 @@ func decodeViewClient(_ context.Context, r *http.Request) (interface{}, error) {
}
func decodeListClients(_ context.Context, r *http.Request) (interface{}, error) {
var sid, oid string
var sharedID, ownerID string
s, err := apiutil.ReadStringQuery(r, api.StatusKey, api.DefClientStatus)
if err != nil {
return nil, err
@ -145,18 +145,25 @@ func decodeListClients(_ context.Context, r *http.Request) (interface{}, error)
if err != nil {
return nil, err
}
visibility, err := apiutil.ReadStringQuery(r, api.VisibilityKey, api.MyVisibility)
oid, err := apiutil.ReadStringQuery(r, api.OwnerKey, "")
if err != nil {
return nil, err
}
visibility, err := apiutil.ReadStringQuery(r, api.VisibilityKey, "")
if err != nil {
return nil, err
}
switch visibility {
case api.MyVisibility:
oid = api.MyVisibility
ownerID = api.MyVisibility
case api.SharedVisibility:
sid = api.MyVisibility
sharedID = api.MyVisibility
case api.AllVisibility:
sid = api.MyVisibility
oid = api.MyVisibility
sharedID = api.MyVisibility
ownerID = api.MyVisibility
}
if oid != "" {
ownerID = oid
}
st, err := mfclients.ToStatus(s)
if err != nil {
@ -170,8 +177,8 @@ func decodeListClients(_ context.Context, r *http.Request) (interface{}, error)
metadata: m,
name: n,
tag: t,
sharedBy: sid,
owner: oid,
sharedBy: sharedID,
owner: ownerID,
}
return req, nil
}

View File

@ -99,23 +99,37 @@ func (svc service) ListClients(ctx context.Context, token string, pm mfclients.P
return mfclients.ClientsPage{}, err
}
switch err = svc.checkAdmin(ctx, userID, thingsObjectKey, listRelationKey); err {
// If the user is admin, fetch all things from database.
if err := svc.checkAdmin(ctx, userID, thingsObjectKey, listRelationKey); err == nil {
pm.Owner = ""
pm.SharedBy = ""
return svc.clients.RetrieveAll(ctx, pm)
}
case nil:
switch {
case pm.SharedBy == MyKey && pm.Owner == MyKey:
pm.SharedBy = ""
pm.Owner = ""
case pm.SharedBy == MyKey && pm.Owner != MyKey:
pm.SharedBy = userID
case pm.Owner == MyKey && pm.SharedBy != MyKey:
pm.Owner = userID
}
// If the user is not admin, check 'sharedby' parameter from page metadata.
// If user provides 'sharedby' key, fetch things from policies. Otherwise,
// fetch things from the database based on thing's 'owner' field.
if pm.SharedBy == MyKey {
pm.SharedBy = userID
default:
// If the user is not admin, check 'sharedby' parameter from page metadata.
// If user provides 'sharedby' key, fetch things from policies. Otherwise,
// fetch things from the database based on thing's 'owner' field.
switch {
case pm.SharedBy == MyKey && pm.Owner == MyKey:
pm.SharedBy = userID
case pm.SharedBy == MyKey && pm.Owner != MyKey:
pm.SharedBy = userID
pm.Owner = ""
case pm.Owner == MyKey && pm.SharedBy != MyKey:
pm.Owner = userID
default:
pm.Owner = userID
}
pm.Action = listRelationKey
}
if pm.Owner == MyKey {
pm.Owner = userID
}
pm.Action = "c_list"
return svc.clients.RetrieveAll(ctx, pm)
}

View File

@ -282,7 +282,12 @@ func buildQuery(gm mfgroups.GroupsPage) (string, error) {
if gm.Status != mfclients.AllStatus {
queries = append(queries, "g.status = :status")
}
if gm.OwnerID != "" {
queries = append(queries, "g.owner_id = :owner_id")
}
if gm.Tag != "" {
queries = append(queries, ":tag = ANY(c.tags)")
}
if gm.Subject != "" {
queries = append(queries, "(g.owner_id = :owner_id OR id IN (SELECT object as id FROM policies WHERE subject = :subject AND :action=ANY(actions)))")
}

View File

@ -213,9 +213,6 @@ func (lce listGroupEvent) Encode() (map[string]interface{}, error) {
val["metadata"] = metadata
}
if lce.SharedBy != "" {
val["sharedBy"] = lce.SharedBy
}
if lce.Status.String() != "" {
val["status"] = lce.Status.String()
}
@ -260,9 +257,6 @@ func (lcge listGroupMembershipEvent) Encode() (map[string]interface{}, error) {
val["metadata"] = metadata
}
if lcge.SharedBy != "" {
val["shared_by"] = lcge.SharedBy
}
if lcge.Status.String() != "" {
val["status"] = lcge.Status.String()
}

View File

@ -93,11 +93,7 @@ func (svc service) ListGroups(ctx context.Context, token string, gm groups.Group
// If the user is admin, fetch all channels from the database.
if err := svc.authorize(ctx, userID, thingsObjectKey, listRelationKey); err == nil {
page, err := svc.groups.RetrieveAll(ctx, gm)
if err != nil {
return groups.GroupsPage{}, err
}
return page, err
return svc.groups.RetrieveAll(ctx, gm)
}
gm.Subject = userID
@ -118,6 +114,7 @@ func (svc service) ListMemberships(ctx context.Context, token, clientID string,
}
gm.OwnerID = userID
gm.Action = listRelationKey
return svc.groups.Memberships(ctx, clientID, gm)
}

View File

@ -162,7 +162,7 @@ func decodeViewProfile(_ context.Context, r *http.Request) (interface{}, error)
}
func decodeListClients(_ context.Context, r *http.Request) (interface{}, error) {
var sid, oid string
var sharedID, ownerID string
s, err := apiutil.ReadStringQuery(r, api.StatusKey, api.DefClientStatus)
if err != nil {
return nil, err
@ -192,18 +192,25 @@ func decodeListClients(_ context.Context, r *http.Request) (interface{}, error)
if err != nil {
return nil, err
}
visibility, err := apiutil.ReadStringQuery(r, api.VisibilityKey, api.MyVisibility)
oid, err := apiutil.ReadStringQuery(r, api.OwnerKey, "")
if err != nil {
return nil, err
}
visibility, err := apiutil.ReadStringQuery(r, api.VisibilityKey, "")
if err != nil {
return nil, err
}
switch visibility {
case api.MyVisibility:
oid = api.MyVisibility
ownerID = api.MyVisibility
case api.SharedVisibility:
sid = api.MyVisibility
sharedID = api.MyVisibility
case api.AllVisibility:
sid = api.MyVisibility
oid = api.MyVisibility
sharedID = api.MyVisibility
ownerID = api.MyVisibility
}
if oid != "" {
ownerID = oid
}
st, err := mfclients.ToStatus(s)
if err != nil {
@ -218,8 +225,8 @@ func decodeListClients(_ context.Context, r *http.Request) (interface{}, error)
name: n,
identity: i,
tag: t,
sharedBy: sid,
owner: oid,
sharedBy: sharedID,
owner: ownerID,
}
return req, nil
}

View File

@ -163,19 +163,33 @@ func (svc service) ListClients(ctx context.Context, token string, pm mfclients.P
return mfclients.ClientsPage{}, err
}
if pm.SharedBy == MyKey {
pm.SharedBy = id
}
if pm.Owner == MyKey {
pm.Owner = id
}
pm.Action = "c_list"
switch err := svc.authorize(ctx, id, clientsObjectKey, listRelationKey); err {
// If the user is admin, fetch all users from database.
case nil:
switch {
case pm.SharedBy == MyKey && pm.Owner == MyKey:
pm.SharedBy = ""
pm.Owner = ""
case pm.SharedBy == MyKey && pm.Owner != MyKey:
pm.SharedBy = id
case pm.Owner == MyKey && pm.SharedBy != MyKey:
pm.Owner = id
}
// If the user is admin, fetch all things from database.
if err := svc.authorize(ctx, id, clientsObjectKey, listRelationKey); err == nil {
pm.SharedBy = ""
pm.Owner = ""
pm.Action = ""
// If the user is not admin, fetch users that they own or are shared with them.
default:
switch {
case pm.SharedBy == MyKey && pm.Owner == MyKey:
pm.SharedBy = id
case pm.SharedBy == MyKey && pm.Owner != MyKey:
pm.SharedBy = id
pm.Owner = ""
case pm.Owner == MyKey && pm.SharedBy != MyKey:
pm.Owner = id
default:
pm.Owner = id
}
pm.Action = listRelationKey
}
clients, err := svc.clients.RetrieveAll(ctx, pm)

View File

@ -295,7 +295,12 @@ func buildQuery(gm mfgroups.GroupsPage) (string, error) {
if gm.Status != mfclients.AllStatus {
queries = append(queries, "g.status = :status")
}
if gm.OwnerID != "" {
queries = append(queries, "g.owner_id = :owner_id")
}
if gm.Tag != "" {
queries = append(queries, ":tag = ANY(c.tags)")
}
if gm.Subject != "" {
queries = append(queries, "(g.owner_id = :owner_id OR id IN (SELECT object as id FROM policies WHERE subject = :subject AND :action=ANY(actions)))")
}