dosubot[bot] commented on issue #35594:
URL: https://github.com/apache/superset/issues/35594#issuecomment-3395663654

   <!-- Answer -->
   To implement logging for user CRUD operations in Superset 3.1.1, subclass 
`UserDBModelView` and override the Flask AppBuilder hooks: 
`after_model_create`, `after_model_change`, and `after_model_delete`. These 
hooks are called after the transaction is committed, so you can safely log 
actions without running into transaction errors. You can access the actor via 
`g.user` and the request context for the IP address.
   
   Here's a concrete example:
   
   ```python
   from flask import g, request
   from superset.utils.log import DBEventLogger
   from flask_appbuilder.security.views import UserDBModelView
   
   class CustomUserDBModelView(UserDBModelView):
       def after_model_create(self, model):
           actor = getattr(g, "user", None)
           ip_address = request.headers.get("X-Forwarded-For", 
request.remote_addr)
           DBEventLogger().log(
               user_id=actor.id if actor else None,
               action="user_create",
               dashboard_id=None,
               duration_ms=None,
               slice_id=None,
               referrer=ip_address,
               records=[{
                   "actor_username": getattr(actor, "username", None),
                   "target_username": getattr(model, "username", None),
                   "ip_address": ip_address,
                   "details": "User created",
               }],
           )
   
       def after_model_change(self, model):
           actor = getattr(g, "user", None)
           ip_address = request.headers.get("X-Forwarded-For", 
request.remote_addr)
           DBEventLogger().log(
               user_id=actor.id if actor else None,
               action="user_update",
               dashboard_id=None,
               duration_ms=None,
               slice_id=None,
               referrer=ip_address,
               records=[{
                   "actor_username": getattr(actor, "username", None),
                   "target_username": getattr(model, "username", None),
                   "ip_address": ip_address,
                   "details": "User updated",
               }],
           )
   
       def after_model_delete(self, model):
           actor = getattr(g, "user", None)
           ip_address = request.headers.get("X-Forwarded-For", 
request.remote_addr)
           DBEventLogger().log(
               user_id=actor.id if actor else None,
               action="user_delete",
               dashboard_id=None,
               duration_ms=None,
               slice_id=None,
               referrer=ip_address,
               records=[{
                   "actor_username": getattr(actor, "username", None),
                   "target_username": getattr(model, "username", None),
                   "ip_address": ip_address,
                   "details": "User deleted",
               }],
           )
   ```
   
   To use your custom view, register it in your security manager or appbuilder 
setup, replacing the default `UserDBModelView`. This approach is upgrade-safe 
and ensures all frontend user management actions are logged via the backend 
view hooks 
[reference](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/views/base.py).
   
   Let me know if you need details on registration or want to customize the log 
format further!
   
   
   <!-- Dosu Comment Footer -->
   *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).*
   
   ---
   <sup>How did I do? 
[Good](https://app.dosu.dev/response-feedback/dc457ede-8e20-4087-8716-e3e9c36a08fa?feedback_type=great_response)
 | 
[Irrelevant](https://app.dosu.dev/response-feedback/dc457ede-8e20-4087-8716-e3e9c36a08fa?feedback_type=irrelevant_answer)
 | 
[Incorrect](https://app.dosu.dev/response-feedback/dc457ede-8e20-4087-8716-e3e9c36a08fa?feedback_type=incorrect_sources)
 | 
[Verbose](https://app.dosu.dev/response-feedback/dc457ede-8e20-4087-8716-e3e9c36a08fa?feedback_type=too_verbose)
 | 
[Hallucination](https://app.dosu.dev/response-feedback/dc457ede-8e20-4087-8716-e3e9c36a08fa?feedback_type=hallucination)
 | [Report 
🐛](https://app.dosu.dev/response-feedback/dc457ede-8e20-4087-8716-e3e9c36a08fa?feedback_type=bug_report)
 | 
[Other](https://app.dosu.dev/response-feedback/dc457ede-8e20-4087-8716-e3e9c36a08fa?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat
 with 
Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/a28d3c7e-a9d3-459e-9fb6-3a6f9ff4f357/ask?utm_source=githu
 b)&nbsp;[![Join 
Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share
 on 
X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/apache/superset/issues/35594)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to