Detect 402 in frontend, allow me query
This commit is contained in:
parent
c9c42e2296
commit
36c43bf4e1
|
|
@ -7,7 +7,7 @@ import fetch from 'unfetch'
|
||||||
import {typeDefs} from '@/graphql/typedefs';
|
import {typeDefs} from '@/graphql/typedefs';
|
||||||
import {resolvers} from '@/graphql/resolvers';
|
import {resolvers} from '@/graphql/resolvers';
|
||||||
|
|
||||||
export default function (uri) {
|
export default function (uri, networkErrorCallback) {
|
||||||
const httpLink = createHttpLink({
|
const httpLink = createHttpLink({
|
||||||
// uri: process.env.NODE_ENV !== 'production' ? 'http://localhost:8000/api/graphql/' : '/api/graphql/',
|
// uri: process.env.NODE_ENV !== 'production' ? 'http://localhost:8000/api/graphql/' : '/api/graphql/',
|
||||||
uri,
|
uri,
|
||||||
|
|
@ -42,6 +42,12 @@ export default function (uri) {
|
||||||
});
|
});
|
||||||
|
|
||||||
const errorLink = onError(({response, operation, networkError, graphQLErrors}) => {
|
const errorLink = onError(({response, operation, networkError, graphQLErrors}) => {
|
||||||
|
|
||||||
|
if (networkError && networkErrorCallback) {
|
||||||
|
networkErrorCallback(networkError.statusCode);
|
||||||
|
return Observable.of();
|
||||||
|
}
|
||||||
|
|
||||||
if (graphQLErrors) {
|
if (graphQLErrors) {
|
||||||
graphQLErrors.forEach(({message, locations, path}) =>
|
graphQLErrors.forEach(({message, locations, path}) =>
|
||||||
console.log(
|
console.log(
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,8 @@ if (process.env.GOOGLE_ANALYTICS_ID) {
|
||||||
Vue.directive('click-outside', clickOutside);
|
Vue.directive('click-outside', clickOutside);
|
||||||
Vue.directive('auto-grow', autoGrow);
|
Vue.directive('auto-grow', autoGrow);
|
||||||
|
|
||||||
const publicApolloClient = apolloClientFactory('/api/graphql-public/');
|
const publicApolloClient = apolloClientFactory('/api/graphql-public/', null);
|
||||||
const privateApolloClient = apolloClientFactory('/api/graphql/');
|
const privateApolloClient = apolloClientFactory('/api/graphql/', networkErrorCallback);
|
||||||
|
|
||||||
const apolloProvider = new VueApollo({
|
const apolloProvider = new VueApollo({
|
||||||
clients: {
|
clients: {
|
||||||
|
|
@ -140,7 +140,14 @@ function redirectStudentsWithoutClass() {
|
||||||
}).then(({data}) => data.me.schoolClasses.edges.length === 0 && data.me.permissions.length === 0);
|
}).then(({data}) => data.me.schoolClasses.edges.length === 0 && data.me.permissions.length === 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function networkErrorCallback(statusCode) {
|
||||||
|
if (statusCode === 402) {
|
||||||
|
router.push({name: 'licenseActivation'}, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
|
||||||
// handle logout
|
// handle logout
|
||||||
if (to.path === '/logout') {
|
if (to.path === '/logout') {
|
||||||
privateApolloClient.resetStore();
|
privateApolloClient.resetStore();
|
||||||
|
|
@ -154,7 +161,7 @@ router.beforeEach(async (to, from, next) => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to.name !== 'noClass' && loginRequired(to) && await redirectStudentsWithoutClass()) {
|
if ((to.name !== 'noClass' || to.name !== 'licenseActivation') && loginRequired(to) && await redirectStudentsWithoutClass()) {
|
||||||
next({name: 'noClass'})
|
next({name: 'noClass'})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
@ -104,6 +105,6 @@ class UserHasLicenseeMiddleWare(MiddlewareMixin):
|
||||||
def process_response(self, request, response):
|
def process_response(self, request, response):
|
||||||
if request.path == '/api/graphql/':
|
if request.path == '/api/graphql/':
|
||||||
if not is_private_api_call_allowed(request.user, request.body):
|
if not is_private_api_call_allowed(request.user, request.body):
|
||||||
return HttpResponse('License required', status=402)
|
return HttpResponse(json.dumps({'errors': ['no active license']}), status=402)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
|
||||||
|
|
@ -46,3 +46,13 @@ class MiddlewareTestCase(TestCase):
|
||||||
body = b'"{mutation { logout {"'
|
body = b'"{mutation { logout {"'
|
||||||
|
|
||||||
self.assertTrue(is_private_api_call_allowed(user, body))
|
self.assertTrue(is_private_api_call_allowed(user, body))
|
||||||
|
|
||||||
|
def test_me_query_is_allowed_without_valid_license(self):
|
||||||
|
|
||||||
|
yesterday = timezone.now() - timedelta(1)
|
||||||
|
user = UserFactory(username='aschiman@ch.ch')
|
||||||
|
user.license_expiry_date = yesterday
|
||||||
|
|
||||||
|
body = b'"{query { me {"'
|
||||||
|
|
||||||
|
self.assertTrue(is_private_api_call_allowed(user, body))
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ def is_private_api_call_allowed(user, body):
|
||||||
|
|
||||||
body_unicode = body.decode('utf-8')
|
body_unicode = body.decode('utf-8')
|
||||||
|
|
||||||
if re.search(r"mutation\s*.*\s*logout\s*{", body_unicode):
|
if re.search(r"mutation\s*.*\s*logout\s*{", body_unicode) or re.search(r"query\s*.*\s*me\s*{", body_unicode):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
license_expiry = user.license_expiry_date
|
license_expiry = user.license_expiry_date
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue