get embed dashboard with roles and permissions in superset - apache-superset

I am trying to embed dashboard in superset based on the roles and permissions created in superset application roles.
I had created a role and given certain permission and assigned to specific user. But while embeding in superset, that particular user is having the permission of 'view query' option in chart controls even though I didn't assigned that in permission. But when I log in to superset directly with that user, I can see those roles and permissions are applying over there but not in Embed Dashboard. Can anyone help me on this?
I am using superset version - 2.0.1
superset logs:
2023-02-13 16:31:00,516:ERROR:root:'GuestUser' object has no attribute 'get_user_id'
Traceback (most recent call last):
File "/home/gridlex/Desktop/main_project/binary_superset_file/binary_ss_env/lib/python3.8/site-packages/flask_appbuilder/api/init.py", line 86, in wraps
return f(self, *args, **kwargs)
File "/home/gridlex/Desktop/main_project/binary_superset_file/binary_ss_env/lib/python3.8/site-packages/superset/utils/log.py", line 245, in wrapper
value = f(*args, **kwargs)
File "/home/gridlex/Desktop/main_project/binary_superset_file/binary_ss_env/lib/python3.8/site-packages/superset/dashboards/filter_state/api.py", line 98, in post
return super().post(pk)
File "/home/gridlex/Desktop/main_project/binary_superset_file/binary_ss_env/lib/python3.8/site-packages/superset/views/base_api.py", line 83, in wraps
return f(self, *args, **kwargs)
File "/home/gridlex/Desktop/main_project/binary_superset_file/binary_ss_env/lib/python3.8/site-packages/superset/temporary_cache/api.py", line 76, in post
key = self.get_create_command()(args).run()
File "/home/gridlex/Desktop/main_project/binary_superset_file/binary_ss_env/lib/python3.8/site-packages/superset/temporary_cache/commands/create.py", line 35, in run
return self.create(self._cmd_params)
File "/home/gridlex/Desktop/main_project/binary_superset_file/binary_ss_env/lib/python3.8/site-packages/superset/dashboards/filter_state/commands/create.py", line 41, in create
entry: Entry = {"owner": get_owner(actor), "value": value}
File "/home/gridlex/Desktop/main_project/binary_superset_file/binary_ss_env/lib/python3.8/site-packages/superset/key_value/utils.py", line 70, in get_owner
return user.get_user_id() if not user.is_anonymous else None
AttributeError: 'GuestUser' object has no attribute 'get_user_id'
2023-02-13 16:31:00,533:INFO:werkzeug:127.0.0.1 - - [13/Feb/2023 16:31:00] "POST /api/v1/dashboard/11/filter_state?tab_id=1 HTTP/1.1" 500 -
And I am getting the following error in browser console.
POST http://127.0.0.1:8088/api/v1/dashboard/11/filter_state?tab_id=1 500 (INTERNAL SERVER ERROR)
Response {type: 'basic', url: 'http://127.0.0.1:8088/api/v1/dashboard/11/filter_state?tab_id=1', redirected: false, status: 500, ok: false, …}

Related

Django Rest Framework request header based permission

I'm building a Django app with Django Rest Framework to host it on my organisation's domain. The domain implements a custom authentication protocol. When someone accesses the domain, say to app1.domainname.com, they are redirected to the organisation's login page (login.domainname.com) and they have to log in with their staff account. After the user is authenticated, the user is redirected back to their initial destination (app1.domain.com). The information of the user is then stored in some custom header fields of the HTTP request sent to the app. E.g.
GET / HTTP/2
Content-Type:
User-Agent: ...
...
X-Username: johndoe1
X-Firstname: John
X-Lastname: Doe
X-Email: johndoe#domainname.com
etc.
I'm trying to implement custom permission for my REST API that looks for these fields in the headers, and then authorise the user based on their user information. This is what I'm currently having:
from rest_framework.permissions import BasePermission
allowed = ['johndoe1', 'dicksmith2', 'username3']
class CutomPerm(BasePermission):
message = "You don't have permission to access this object"
def has_object_permission(self, request, view, obj):
print(request.headers)
username = request.headers['X-Username']
return username in allowed
But when I run the server, it seems like the custom headers are passed through to the backend. For some requests they are, but ultimately the user is not authorised because the has_object_permission method raises a KeyError:
[10/Mar/2020 10:03:29] "GET /api/obj/ HTTP/1.1" 200 81
[10/Mar/2020 10:03:29] "GET /favicon.ico/ HTTP/1.1" 200 11
{'Content-Length': '', 'Content-Type': 'text/plain', 'Host': 'localhost:8000', 'Connection': 'keep-alive', etc., 'X-Username': 'johndoe1', 'X-Firstname': 'John', etc.}
Forbidden: /api/obj/1/
[10/Mar/2020 10:04:35] "GET /api/obj/1/ HTTP/1.1" 403 6581
{'Content-Length': '', 'Content-Type': 'text/plain', 'Host': 'localhost:8000', 'Connection': 'keep-alive', etc.} # no custom headers here
[10/Mar/2020 10:04:35] "GET /favicon.ico/ HTTP/1.1" 200 11
Internal Server Error: /api/obj/1/
Traceback (most recent call last):
File "/path/to/project/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/path/to/project/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/path/to/project/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/path/to/project/venv/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/path/to/project/venv/lib/python3.8/site-packages/rest_framework/viewsets.py", line 114, in view
return self.dispatch(request, *args, **kwargs)
File "/path/to/project/venv/lib/python3.8/site-packages/rest_framework/views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "/path/to/project/venv/lib/python3.8/site-packages/rest_framework/views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "/path/to/project/venv/lib/python3.8/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
raise exc
File "/path/to/project/venv/lib/python3.8/site-packages/rest_framework/views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "/path/to/project/venv/lib/python3.8/site-packages/rest_framework/mixins.py", line 54, in retrieve
instance = self.get_object()
File "/path/to/project/venv/lib/python3.8/site-packages/rest_framework/generics.py", line 99, in get_object
self.check_object_permissions(self.request, obj)
File "/path/to/project/venv/lib/python3.8/site-packages/rest_framework/views.py", line 343, in check_object_permissions
if not permission.has_object_permission(request, self, obj):
File "/path/to/project/project/app/permissions.py", line 11, in has_object_permission
username = request.headers['X-Username']
File "/path/to/project/venv/lib/python3.8/site-packages/django/http/request.py", line 388, in __getitem__
return super().__getitem__(key.replace('_', '-'))
File "/path/to/project/venv/lib/python3.8/site-packages/django/utils/datastructures.py", line 320, in __getitem__
return self._store[key.lower()][1]
KeyError: 'X-Username'
Note that in the 2 header dictionaries printed out, the first one has all the custom headers but the second one doesn't.
I think this is because there are some redirecting happening behind the scene and the final request that gets to the rest framework permission check has lost all of its custom headers. Is there anyway to check for permissions based on the custom headers?
Thanks
Django modifies the http header keys.
You have to access the header as:
username = request.META.get('HTTP_X_USERNAME', None)
if username:
# your logic
pass
checkout Django header docs:
https://docs.djangoproject.com/en/3.0/ref/request-response/#django.http.HttpRequest.META

Authenticating Swagger API docs (drf-yasg)

I've setup DRF-YASG but am unable to figure out how to configure it to show Views that require Authentication.
Below is the configuration.
schema_view = get_schema_view(
openapi.Info(
title="Swagger Doc",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="contact#snippets.local"),
license=openapi.License(name="BSD License"),
),
validators=['flex', 'ssv'],
permission_classes=(permissions.AllowAny,), # If I change the permission it throws an exception. See below
public=False,
patterns=public_apis,
)
the public_apis are the APIs that I want a person to see after they have authenticated themselves.
With the above configuration, it does not show a single API. It only shows the Authorize Button and text that says No operations defined in spec!. But if I change public=False to public=True then it shows all the APIs.
PS: Earlier I was using Django Rest Swagger and I had been able to configure it to show the APIs only after the JWT token had been provided.
Am is using JWT for authentication.
Exception on Permission Change:
Another issue is that if I change the permission above to a DRF Permission class the rendering fails with the error below:
Internal Server Error: /swagger/
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 217, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 215, in _get_response
response = response.render()
File "/usr/local/lib/python3.6/site-packages/django/template/response.py", line 107, in render
self.content = self.rendered_content
File "/usr/local/lib/python3.6/site-packages/rest_framework/response.py", line 72, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/usr/local/lib/python3.6/site-packages/drf_yasg/renderers.py", line 54, in render
self.set_context(renderer_context, swagger)
File "/usr/local/lib/python3.6/site-packages/drf_yasg/renderers.py", line 62, in set_context
renderer_context['title'] = swagger.info.title
AttributeError: 'dict' object has no attribute 'info'
Internal Server Error: /swagger/
I've tried changing it to permmissions.IsAuthenticated and my own custom permission classes but they all fail with the same error.
Turned out the issue was that I was missing rest_framework.authentication.SessionAuthentication in DRF's DEFAULT_AUTHENTICATION_CLASSES.
So the request object sent after logging in via the Django Admin login view did not have a user so all permission classes kept failing and it would then lead to the above error.
So after adding it drf-yasg shows all its glory.
Bug:
The error it throws when this occurs was raised as bug though. See #issue58.

Trying to login to a ATWS with SUDS error

Im trying to login to a ATWS service with suds but I keep getting the following error:
Traceback (most recent call last):
File "/Users/AAAA/Documents/Aptana/AutotaskUpdateTicketEstimatedHours/Main.py", line 38, in <module>
handler = ConnectATWS()
File "/Users/AAAA/Documents/Aptana/AutotaskUpdateTicketEstimatedHours/Main.py", line 31, in __init__
client = Client(self.url)
File "/Library/Python/2.7/site-packages/suds/client.py", line 112, in __init__
self.wsdl = reader.open(url)
File "/Library/Python/2.7/site-packages/suds/reader.py", line 152, in open
d = self.fn(url, self.options)
File "/Library/Python/2.7/site-packages/suds/wsdl.py", line 136, in __init__
d = reader.open(url)
File "/Library/Python/2.7/site-packages/suds/reader.py", line 79, in open
d = self.download(url)
File "/Library/Python/2.7/site-packages/suds/reader.py", line 95, in download
fp = self.options.transport.open(Request(url))
File "/Library/Python/2.7/site-packages/suds/transport/https.py", line 60, in open
return HttpTransport.open(self, request)
File "/Library/Python/2.7/site-packages/suds/transport/http.py", line 64, in open
raise TransportError(str(e), e.code, e.fp)
suds.transport.TransportError: HTTP Error 401: Unauthorized
I'm inputting the correct login info, yet I keep getting the Unauthorized error.
This is my code:
class ConnectATWS():
def __init__(self):
app_config = Init()
self.username = app_config.data["Username"]
self.password = app_config.data["Password"]
self.login_id = app_config.data["LoginID"]
self.url = app_config.data["AutotaskUpdateTicketEstimatedHours_net_autotask_webservices5_ATWS"]
client = Client(self.url)
login_res = client.service.Login(self.login_id, self.password)
Am I not using SUDS correctly?
Authentication like this
client = Client(self.url)
login_res = client.service.Login(self.login_id, self.password)
will only work if the webservice offers a Login(user, password) method which needs to be called to authenticate.
In you case you get a 401 response already when you try to access the service wsdl (when constructing the Client), which is an indication that a different authentication method is used, based on the http response probably http basic auth. So the authentication is not done by the service, but on the transport layer.
To use http basic auth with suds is simple, just pass the username and password keyword arguments to the Client:
client = Client(self.url, username=self.login_id, password=self.password)

"working outside of application context" in Google App Engine with Python remote API

I deployed one simple project on Google App Engine and there the project is working. Before I was able to get list of users from datastore through the remote API console , but now this no longer works. To start the remote API console I'm connecting this way (running from the project directory):
../../+/google_appengine_PYTHON_SDK/remote_api_shell.py -s project.appspot.com
I found that the easiest way to load all modules is to run:
s~project> help()
help>modules
help>quit
After that I try to get the list of users:
s~project> from app.models import User
s~project> User.query().fetch()
The last row results in this:
WARNING:root:suspended generator _run_to_list(query.py:964) raised RuntimeError(working outside of application context)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/ext/ndb/utils.py", line 142, in positional_wrapper
return wrapped(*args, **kwds)
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/ext/ndb/query.py", line 1187, in fetch
return self.fetch_async(limit, **q_options).get_result()
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/ext/ndb/tasklets.py", line 325, in get_result
self.check_success()
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
value = gen.throw(exc.__class__, exc, tb)
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/ext/ndb/query.py", line 964, in _run_to_list
batch = yield rpc
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/ext/ndb/tasklets.py", line 454, in _on_rpc_completion
result = rpc.get_result()
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result
return self.__get_result_hook(self)
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/datastore/datastore_query.py", line 3014, in __query_result_hook
self.__results = self._process_results(query_result.result_list())
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/datastore/datastore_query.py", line 3047, in _process_results
for result in results]
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/datastore/datastore_rpc.py", line 185, in pb_to_query_result
return self.pb_to_entity(pb)
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/ext/ndb/model.py", line 662, in pb_to_entity
entity = modelclass._from_pb(pb, key=key, set_key=False)
File "/home/krasen/Programs/+/google_appengine_PYTHON_SDK/google/appengine/ext/ndb/model.py", line 3119, in _from_pb
ent = cls()
File "app/models.py", line 68, in __init__
if self.email == current_app.config['MAIL_ADMIN']:
File "/home/krasen/Programs/workspacePycharm/0010_1user_profile/venv/local/lib/python2.7/site-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/home/krasen/Programs/workspacePycharm/0010_1user_profile/venv/local/lib/python2.7/site-packages/werkzeug/local.py", line 297, in _get_current_object
return self.__local()
File "/home/krasen/Programs/workspacePycharm/0010_1user_profile/venv/local/lib/python2.7/site-packages/flask/globals.py", line 34, in _find_app
raise RuntimeError('working outside of application context')
RuntimeError: working outside of application context
I'm very new to python. I found http://kronosapiens.github.io/blog/2014/08/14/understanding-contexts-in-flask.html but couldn't understand from this how to start working inside the app context.
I have tried on linux with python versions:
2.7.6(on clean installed linux)
2.7.9
I have tried with google app engine SDK versions:
1.9.17
1.9.23
1.9.24
The problem was in the User class itself. There I have:
def __init__(self, **kwargs):
super(User, self).__init__(**kwargs)
# FLASKY_ADMIN configuration variable, so as soon as that email address appears in a registration request it can be given the correct role
if self.role is None:
print ("there is no role for this user")
if self.email == current_app.config['MAIL_ADMIN']:
self.role = ndb.Key('Role', 'administrator')
the problematic line is this line:
if self.email == current_app.config['MAIL_ADMIN']:
I don't know how to manage to make it work with this line so I've removed it and now the user is retrieved.

Internal Server Error when trying to log in with Facebook to Django server

I have a Django REST server which I updated recently from using Python 2.7 to 3.4. The server uses Django REST framework on top of Django, with django-allauth and django-rest-auth for Facebook login support.
Now, after the update, I cannot login to the server with Facebook anymore. When I send a POST to the server, I get the following error:
Internal Server Error: /rest-auth/facebook/
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 132, in get_response response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python34\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view return view_func(*args, **kwargs)
File "C:\Python34\lib\site-packages\django\views\generic\base.py", line 71, in view return self.dispatch(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\rest_framework\views.py", line 452, in dispatch response = self.handle_exception(exc)
File "C:\Python34\lib\site-packages\rest_framework\views.py", line 449, in dispatch response = handler(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\rest_auth\views.py", line 51, in post if not self.serializer.is_valid():
File "C:\Python34\lib\site-packages\rest_framework\serializers.py", line 187, in is_valid self._validated_data = self.run_validation(self.initial_data)
File "C:\Python34\lib\site-packages\rest_framework\serializers.py", line 370, in run_validation value = self.validate(value)
File "C:\Python34\lib\site-packages\rest_auth\registration\serializers.py", line 31, in validate token.account = login.account
File "C:\Python34\lib\site-packages\django\db\models\fields\related.py", line 668, in __set__ (value, self.field.rel.to._meta.object_name)
File "C:\Python34\lib\site-packages\django\db\models\base.py", line 496, in __repr__ u = six.text_type(self)
File "C:\Python34\lib\site-packages\allauth\socialaccount\models.py", line 104, in __str__ return force_text(self.user)
File "C:\Python34\lib\site-packages\django\db\models\fields\related.py", line 608, in __get__ "%s has no %s." % (self.field.model.__name__, self.field.name)
django.db.models.fields.related.RelatedObjectDoesNotExist: SocialAccount has no user.
[13/Apr/2015 08:53:30]"POST /rest-auth/facebook/ HTTP/1.1" 500 115908
What could be causing this? I have done no changes to the code after updating Python and the libraries, and it worked before the update. I deleted the old database and created a new one via syncdb but it didn't help.
Thanks in advance.
RelatedObject has been removed in Django 1.8 in favour of ForeignObjectRel. Source
The allauth version you are using does not support Django 1.8.