Эх сурвалжийг харах

[api] Add all APIs for Sql Scratchpad

Romain Rigaux 4 жил өмнө
parent
commit
be01df65f0

+ 7 - 2
desktop/core/src/desktop/api_public.py

@@ -17,9 +17,16 @@
 
 from rest_framework.decorators import api_view
 
+from desktop import api2 as desktop_api
 from notebook import api as notebook_api
 
 
+@api_view(["POST"])
+def get_config(request):
+  django_request = request._request
+  return desktop_api.get_config(django_request)
+
+
 @api_view(["POST"])
 def create_notebook(request):
   django_request = request._request
@@ -70,14 +77,12 @@ def close_statement(request):
   django_request = request._request
   return notebook_api.close_statement(django_request)
 
-
 @api_view(["POST"])
 def get_logs(request):
   django_request = request._request
   return notebook_api.get_logs(django_request)
 
 
-
 @api_view(["POST"])
 def autocomplete(request, server=None, database=None, table=None, column=None, nested=None):
   django_request = request._request

+ 25 - 28
desktop/core/src/desktop/api_public_urls.py

@@ -25,52 +25,49 @@ else:
   from django.conf.urls import url as re_path
 
 
-# New "query" API
-# https://demo.gethue.com/api/query
-#
-# https://demo.gethue.com/api/query/execute/hive
-# https://demo.gethue.com/api/query/status
-# https://demo.gethue.com/api/query/result
-# https://demo.gethue.com/api/query/logs
+# "New" query API (i.e. connector based, lean arguments).
+# e.g. https://demo.gethue.com/api/query/execute/hive
 urlpatterns = [
   re_path(r'^query/create_notebook/?$', api_public.create_notebook, name='api_create_notebook'),
   re_path(r'^query/autocomplete/?$', api_public.autocomplete, name='api_autocomplete_databases'),
 ]
 
-# Compatibility with private API
-# https://demo.gethue.com/notebook/api/editor/execute/hive
+# Compatibility with "old" private API.
+# e.g. https://demo.gethue.com/notebook/api/execute/hive
 urlpatterns += [
-  re_path(r'^create_notebook/?$', api_public.create_notebook, name='api_create_notebook'),
-  re_path(r'^create_session/?$', api_public.create_session, name='create_session'),
-  re_path(r'^close_session/?$', api_public.close_session, name='close_session'),
-  re_path(r'^execute(?:/(?P<dialect>.+))?/?$', api_public.execute, name='execute'),
-  re_path(r'^check_status/?$', api_public.check_status, name='check_status'),
-  re_path(r'^fetch_result_data/?$', api_public.fetch_result_data, name='fetch_result_data'),
-  re_path(r'^fetch_result_metadata/?$', api_public.fetch_result_metadata, name='fetch_result_metadata'),
-  re_path(r'^fetch_result_size/?$', api_public.fetch_result_size, name='fetch_result_size'),
-  re_path(r'^cancel_statement/?$', api_public.cancel_statement, name='cancel_statement'),
-  re_path(r'^close_statement/?$', api_public.close_statement, name='close_statement'),
-  re_path(r'^get_logs/?$', api_public.get_logs, name='get_logs'),
+  re_path(r'^iam/get_config/?$', api_public.get_config),
+
+  re_path(r'^editor/create_notebook/?$', api_public.create_notebook, name='api_create_notebook'),
+  re_path(r'^editor/create_session/?$', api_public.create_session, name='api_create_session'),
+  re_path(r'^editor/close_session/?$', api_public.close_session, name='api_close_session'),
+  re_path(r'^editor/execute(?:/(?P<dialect>.+))?/?$', api_public.execute, name='api_execute'),
+  re_path(r'^editor/check_status/?$', api_public.check_status, name='api_check_status'),
+  re_path(r'^editor/fetch_result_data/?$', api_public.fetch_result_data, name='api_fetch_result_data'),
+  re_path(r'^editor/fetch_result_metadata/?$', api_public.fetch_result_metadata, name='api_fetch_result_metadata'),
+  re_path(r'^editor/fetch_result_size/?$', api_public.fetch_result_size, name='api_fetch_result_size'),
+  re_path(r'^editor/cancel_statement/?$', api_public.cancel_statement, name='api_cancel_statement'),
+  re_path(r'^editor/close_statement/?$', api_public.close_statement, name='api_close_statement'),
+  re_path(r'^editor/get_logs/?$', api_public.get_logs, name='api_get_logs'),
 
   re_path(r'^editor/autocomplete/?$', api_public.autocomplete, name='api_autocomplete_databases'),
   re_path(
-      r"^autocomplete/(?P<database>[^/?]*)/?$",
+      r"^editor/autocomplete/(?P<database>[^/?]*)/?$",
       api_public.autocomplete,
-      name="autocomplete_tables",
+      name="api_autocomplete_tables",
   ),
   re_path(
-      r"^autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/?$",
+      r"^editor/autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/?$",
       api_public.autocomplete,
-      name="autocomplete_columns",
+      name="api_autocomplete_columns",
   ),
   re_path(
-      r"^autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/(?P<column>\w+)/?$",
+      r"^editor/autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/(?P<column>\w+)/?$",
       api_public.autocomplete,
-      name="autocomplete_column",
+      name="api_autocomplete_column",
   ),
   re_path(
-      r"^autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/(?P<column>\w+)/(?P<nested>.+)/?$",
+      r"^editor/autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/(?P<column>\w+)/(?P<nested>.+)/?$",
       api_public.autocomplete,
-      name="autocomplete_nested",
+      name="api_autocomplete_nested",
   ),
 ]

+ 6 - 27
desktop/core/src/desktop/js/api/auth.ts

@@ -14,35 +14,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import { get, post } from 'api/utils';
+import { post } from 'api/utils';
 
-export enum AuthType {
-  hue = 'hue',
-  jwt = 'jwt'
-}
+const JWT_URL = 'api/iam/token/auth/';
 
-const LOGOUT_URL = '/hue/accounts/logout';
-const LOGIN_URL = '/hue/accounts/login';
-
-const JWT_URL = 'iam/v1/get/auth-token/';
-
-export const login = async (
-  username: string,
-  password: string,
-  auth = AuthType.jwt
-): Promise<void> => {
-  if (auth === AuthType.jwt) {
+export const login = async (username: string, email: string, password: string): Promise<void> => {
+  if (email !== '') {
+    return post(JWT_URL, { email, password });
+  } else {
     return post(JWT_URL, { username, password });
   }
-
-  if (auth === AuthType.hue) {
-    await get(LOGOUT_URL);
-    const response = await get<string>(LOGIN_URL);
-    const csrfMatch = response.match(/name='csrfmiddlewaretoken'\s+value='([^']+)'/);
-    if (csrfMatch) {
-      return post(LOGIN_URL, { username, password, csrfmiddlewaretoken: csrfMatch[1] });
-    }
-    throw new Error('No csrf middleware token found!');
-  }
-  throw new Error('Unknown auth method specified!');
 };

+ 15 - 11
desktop/core/src/desktop/js/apps/editor/components/sqlScratchpad/SqlScratchpad.vue

@@ -66,7 +66,7 @@
   import ResultTable from '../result/ResultTable.vue';
   import Executor from '../../execution/executor';
   import SqlExecutable from '../../execution/sqlExecutable';
-  import { AuthType, login } from 'api/auth';
+  import { login } from 'api/auth';
   import { setBaseUrl } from 'api/utils';
   import contextCatalog from 'catalog/contextCatalog';
   import HueIcons from 'components/icons/HueIcons.vue';
@@ -87,29 +87,29 @@
       AceEditor
     },
     props: {
-      dialect: {
+      apiUrl: {
         type: String as PropType<string | null>,
         default: null
       },
-      auth: {
-        type: String as PropType<AuthType | null>,
-        default: AuthType.jwt
+      dialect: {
+        type: String as PropType<string | null>,
+        default: null
       },
-      user: {
+      username: {
         type: String as PropType<string | null>,
         default: null
       },
-      password: {
+      email: {
         type: String as PropType<string | null>,
         default: null
       },
-      apiUrl: {
+      password: {
         type: String as PropType<string | null>,
         default: null
       }
     },
     setup(props) {
-      const { apiUrl, auth, dialect, pass, user } = toRefs(props);
+      const { apiUrl, dialect, username, email, password } = toRefs(props);
       const activeExecutable = ref<SqlExecutable>(null);
       const executor = ref<Executor>(null);
       const loading = ref<boolean>(true);
@@ -140,9 +140,13 @@
           setBaseUrl(apiUrl.value);
         }
 
-        if (user.value !== null && pass.value !== null) {
+        if (password.value !== null) {
           try {
-            await login(user.value, pass.value, auth.value);
+            await login(
+              username.value ? username.value : '',
+              email.value ? email.value : '',
+              password.value
+            );
           } catch (err) {
             errorMessage.value = 'Login failed!';
             console.error(err);

+ 1 - 0
desktop/core/src/desktop/js/apps/editor/components/sqlScratchpad/SqlScratchpadWebComponent.ts

@@ -22,6 +22,7 @@ import 'utils/json.bigDataParse';
 
 wrap('sql-scratchpad', SqlScratchpad);
 
+// Dup of auth.ts?
 const login = async (username: string, password: string): Promise<void> =>
   post('iam/v1/get/auth-token/', { username, password });
 

+ 1 - 0
desktop/core/src/desktop/settings.py

@@ -385,6 +385,7 @@ if desktop.conf.CORS_ENABLED.get():
   MIDDLEWARE.remove('django.middleware.csrf.CsrfViewMiddleware')
   if sys.version_info[0] > 2:
     CORS_ALLOW_ALL_ORIGINS = True
+    # CORS_URLS_REGEX = r'^/api/.*$'
   else:
     CORS_ORIGIN_ALLOW_ALL = True
   CORS_ALLOW_CREDENTIALS = True  # For when cookie auth

+ 3 - 3
desktop/core/src/desktop/urls.py

@@ -208,9 +208,9 @@ dynamic_patterns += [
 ]
 
 dynamic_patterns += [
-  re_path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
-  re_path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
-  re_path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
+  re_path('api/iam/token/refresh/?$', TokenRefreshView.as_view(), name='token_refresh'),
+  re_path('api/iam/token/verify/?$', TokenVerifyView.as_view(), name='token_verify'),
+  re_path('api/iam/token/auth/?$', TokenObtainPairView.as_view(), name='token_obtain_pair'),
 
   re_path(r'^api/', include('desktop.api_public_urls')),
 ]

+ 1 - 1
docs/docs-site/content/developer/components/scratchpad/_index.md

@@ -21,7 +21,7 @@ We have the `gethue` [dependency](/developer/components/) in `packages.json` or
 
     <body>
       <div style="position: absolute; height: 100%; width: 100%">
-        <sql-scratchpad api-url="http://localhost:8005" dialect="mysql" />
+        <sql-scratchpad api-url="http://localhost:8005" username="demo" password="demo" dialect="mysql" />
       </div>
     </body>