Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the user to list and see themselves even without rbac_user_show #1230

Merged
merged 1 commit into from
Nov 14, 2023

Conversation

Fryguy
Copy link
Member

@Fryguy Fryguy commented Jun 10, 2023

Depends on

@jrafanie @DavidResende0 Please review.

WIP because I think this should get a lot of testing and verification. I'd like to add specs as well.

I would feel more comfortable adding specs around this and extra testing because technically this fix bypasses API RBAC which is a security vector, however, bypassing API RBAC in this specific case is warranted, because a user should be able to see themselves.

Note that user update was already written to bypass API RBAC for yourself because that's how the group switcher works, but for some reason index and show were not included in the list for API RBAC bypass.

Interestingly when you RBAC.filter the users list it automatically allows you to see yourself - I didn't have to add any special code for index - RBAC.filter just took care of it.

Admin user

Admin user - index

Before & After

curl -s --user admin:smartvm -X GET -H "Accept: application/json" http://localhost:3000/api/users | jq .

{
  "name": "users",
  "count": 2,
  "subcount": 2,
  "pages": 1,
  "resources": [
    {
      "href": "http://localhost:3000/api/users/1"
    },
    {
      "href": "http://localhost:3000/api/users/2"
    }
  ],
  "actions": [
    {
      "name": "query",
      "method": "post",
      "href": "http://localhost:3000/api/users"
    },
    {
      "name": "create",
      "method": "post",
      "href": "http://localhost:3000/api/users"
    },
    {
      "name": "edit",
      "method": "post",
      "href": "http://localhost:3000/api/users"
    },
    {
      "name": "delete",
      "method": "post",
      "href": "http://localhost:3000/api/users"
    },
    {
      "name": "assign_tags",
      "method": "post",
      "href": "http://localhost:3000/api/users"
    },
    {
      "name": "unassign_tags",
      "method": "post",
      "href": "http://localhost:3000/api/users"
    },
    {
      "name": "revoke_sessions",
      "method": "post",
      "href": "http://localhost:3000/api/users"
    }
  ],
  "links": {
    "self": "http://localhost:3000/api/users?offset=0",
    "first": "http://localhost:3000/api/users?offset=0",
    "last": "http://localhost:3000/api/users?offset=0"
  }
}

Admin user - show self

Before & After

curl -s --user admin:smartvm -X GET -H "Accept: application/json" http://localhost:3000/api/users/1 | jq .

{
  "href": "http://localhost:3000/api/users/1",
  "id": "1",
  "name": "Administrator",
  "email": null,
  "icon": null,
  "created_on": "2023-04-18T22:39:31Z",
  "updated_on": "2023-06-10T02:04:14Z",
  "userid": "admin",
  "settings": {},
  "lastlogon": "2023-06-10T02:04:14Z",
  "lastlogoff": "2023-06-10T01:23:55Z",
  "current_group_id": "2",
  "first_name": null,
  "last_name": null,
  "failed_login_attempts": 0,
  "actions": [
    {
      "name": "edit",
      "method": "post",
      "href": "http://localhost:3000/api/users/1"
    },
    {
      "name": "edit",
      "method": "patch",
      "href": "http://localhost:3000/api/users/1"
    },
    {
      "name": "edit",
      "method": "put",
      "href": "http://localhost:3000/api/users/1"
    },
    {
      "name": "delete",
      "method": "post",
      "href": "http://localhost:3000/api/users/1"
    },
    {
      "name": "revoke_sessions",
      "method": "post",
      "href": "http://localhost:3000/api/users/1"
    },
    {
      "name": "set_current_group",
      "method": "post",
      "href": "http://localhost:3000/api/users/1"
    }
  ]
}

Admin user - show other

Before & After

curl -s --user admin:smartvm -X GET -H "Accept: application/json" http://localhost:3000/api/users/2 | jq .

{
  "href": "http://localhost:3000/api/users/2",
  "id": "2",
  "name": "non-admin",
  "email": null,
  "icon": null,
  "created_on": "2023-06-10T01:23:49Z",
  "updated_on": "2023-06-10T01:53:28Z",
  "userid": "non-admin",
  "settings": {
    "view": {
      "compare": "expanded",
      "compare__mode": "details",
      "drift": "expanded",
      "drift__mode": "details",
      "summary__mode": "dashboard"
    },
    "perpage": {
      "list": 20,
      "reports": 20
    },
    "display": {
      "locale": "default"
    }
  },
  "lastlogon": "2023-06-10T01:50:50Z",
  "lastlogoff": "2023-06-10T01:53:28Z",
  "current_group_id": "5",
  "first_name": null,
  "last_name": null,
  "failed_login_attempts": 0,
  "actions": [
    {
      "name": "edit",
      "method": "post",
      "href": "http://localhost:3000/api/users/2"
    },
    {
      "name": "edit",
      "method": "patch",
      "href": "http://localhost:3000/api/users/2"
    },
    {
      "name": "edit",
      "method": "put",
      "href": "http://localhost:3000/api/users/2"
    },
    {
      "name": "delete",
      "method": "post",
      "href": "http://localhost:3000/api/users/2"
    },
    {
      "name": "revoke_sessions",
      "method": "post",
      "href": "http://localhost:3000/api/users/2"
    },
    {
      "name": "set_current_group",
      "method": "post",
      "href": "http://localhost:3000/api/users/2"
    }
  ]
}

Non-Admin user

Non-Admin user - index

Before

curl -s --user non-admin:smartvm -X GET -H "Accept: application/json" http://localhost:3000/api/users | jq .

{
  "error": {
    "kind": "forbidden",
    "message": "Use of the read action is forbidden",
    "klass": "Api::ForbiddenError"
  }
}

After

curl -s --user non-admin:smartvm -X GET -H "Accept: application/json" http://localhost:3000/api/users | jq .

{
  "name": "users",
  "count": 2,
  "subcount": 1,
  "pages": 1,
  "resources": [
    {
      "href": "http://localhost:3000/api/users/2"
    }
  ],
  "actions": [
    {
      "name": "revoke_sessions",
      "method": "post",
      "href": "http://localhost:3000/api/users"
    }
  ],
  "links": {
    "self": "http://localhost:3000/api/users?offset=0",
    "first": "http://localhost:3000/api/users?offset=0",
    "last": "http://localhost:3000/api/users?offset=0"
  }
}

Non-Admin user - show self

Before

curl -s --user non-admin:smartvm -X GET -H "Accept: application/json" http://localhost:3000/api/users/2 | jq .

{
  "error": {
    "kind": "forbidden",
    "message": "Use of the read action is forbidden",
    "klass": "Api::ForbiddenError"
  }
}

After

curl -s --user non-admin:smartvm -X GET -H "Accept: application/json" http://localhost:3000/api/users/2 | jq .

{
  "href": "http://localhost:3000/api/users/2",
  "id": "2",
  "name": "non-admin",
  "email": null,
  "icon": null,
  "created_on": "2023-06-10T01:23:49Z",
  "updated_on": "2023-06-10T02:04:37Z",
  "userid": "non-admin",
  "settings": {
    "view": {
      "compare": "expanded",
      "compare__mode": "details",
      "drift": "expanded",
      "drift__mode": "details",
      "summary__mode": "dashboard"
    },
    "perpage": {
      "list": 20,
      "reports": 20
    },
    "display": {
      "locale": "default"
    }
  },
  "lastlogon": "2023-06-10T02:04:37Z",
  "lastlogoff": "2023-06-10T01:53:28Z",
  "current_group_id": "5",
  "first_name": null,
  "last_name": null,
  "failed_login_attempts": 0,
  "actions": [
    {
      "name": "revoke_sessions",
      "method": "post",
      "href": "http://localhost:3000/api/users/2"
    },
    {
      "name": "set_current_group",
      "method": "post",
      "href": "http://localhost:3000/api/users/2"
    }
  ]
}

Non-Admin user - show other

Before

curl -s --user non-admin:smartvm -X GET -H "Accept: application/json" http://localhost:3000/api/users/1 | jq .

{
  "error": {
    "kind": "forbidden",
    "message": "Use of the read action is forbidden",
    "klass": "Api::ForbiddenError"
  }
}

After

curl -s --user non-admin:smartvm -X GET -H "Accept: application/json" http://localhost:3000/api/users/1 | jq .

{
  "error": {
    "kind": "forbidden",
    "message": "Use of the read action is forbidden",
    "klass": "Api::ForbiddenError"
  }
}

@Fryguy Fryguy requested a review from bdunne as a code owner June 10, 2023 01:57
@Fryguy Fryguy changed the title Allow the user to list and see themselves even without rbac_user_show [WIP] Allow the user to list and see themselves even without rbac_user_show Jun 10, 2023
@Fryguy Fryguy force-pushed the let_user_see_themselves branch 4 times, most recently from 837c7ec to d4411de Compare June 10, 2023 02:23
@DavidResende0
Copy link
Member

@Fryguy I'm getting this error now in the ui
image

@Fryguy
Copy link
Member Author

Fryguy commented Jun 10, 2023

Did you switch groups? Curious how you got into that state.

@DavidResende0
Copy link
Member

Did you switch groups? Curious how you got into that state.

yes I was using a user with multiple groups and swapped to admin before hitting the error

@miq-bot miq-bot added the stale label Sep 11, 2023
@miq-bot
Copy link
Member

miq-bot commented Sep 11, 2023

This pull request has been automatically marked as stale because it has not been updated for at least 3 months.

If these changes are still valid, please remove the stale label, make any changes requested by reviewers (if any), and ensure that this issue is being looked at by the assigned/reviewer(s)

Thank you for all your contributions! More information about the ManageIQ triage process can be found in the triage process documentation.

@Fryguy Fryguy removed the stale label Oct 25, 2023
@Fryguy
Copy link
Member Author

Fryguy commented Oct 25, 2023

Interestingly when you RBAC.filter the users list it automatically allows you to see yourself - I didn't have to add any special code for index - RBAC.filter just took care of it.

Ok, this is the weird part. I'm finding this only works for some roles but not others, and I can't narrow it down. This causes the current code to only partially work. Looking into this deeper.

@kbrock
Copy link
Member

kbrock commented Oct 26, 2023

I was expecting to see index/show to manually return objects based upon target_is_api_user?
Looking at this I almost wish super had this logic instead.

Not for now: Wondering what would happen if we used rbac for index/show and only had privs on post/update

@Fryguy Fryguy force-pushed the let_user_see_themselves branch from d4411de to 3a5695e Compare November 7, 2023 19:24
@Fryguy Fryguy changed the title [WIP] Allow the user to list and see themselves even without rbac_user_show Allow the user to list and see themselves even without rbac_user_show Nov 14, 2023
@miq-bot miq-bot removed the wip label Nov 14, 2023
@Fryguy Fryguy force-pushed the let_user_see_themselves branch from 3a5695e to b695962 Compare November 14, 2023 22:12
@miq-bot
Copy link
Member

miq-bot commented Nov 14, 2023

Checked commit Fryguy@b695962 with ruby 2.6.10, rubocop 1.28.2, haml-lint 0.35.0, and yamllint
1 file checked, 0 offenses detected
Everything looks fine. 🏆

@Fryguy Fryguy closed this Nov 14, 2023
@Fryguy Fryguy reopened this Nov 14, 2023
@kbrock kbrock merged commit cc89506 into ManageIQ:master Nov 14, 2023
2 of 3 checks passed
@Fryguy
Copy link
Member Author

Fryguy commented Nov 14, 2023

Backported to quinteros in commit 3b41604.

commit 3b4160427ce390d1b5e9882470bcc06d122cc679
Author: Keenan Brock <[email protected]>
Date:   Tue Nov 14 18:15:13 2023 -0500

    Merge pull request #1230 from Fryguy/let_user_see_themselves
    
    Allow the user to list and see themselves even without rbac_user_show
    
    (cherry picked from commit cc895066de9fecdf5687d7cd2b7307ec046718b2)

Fryguy pushed a commit that referenced this pull request Nov 14, 2023
Allow the user to list and see themselves even without rbac_user_show

(cherry picked from commit cc89506)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants