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 {resolvers} from '@/graphql/resolvers';
|
||||
|
||||
export default function (uri) {
|
||||
export default function (uri, networkErrorCallback) {
|
||||
const httpLink = createHttpLink({
|
||||
// uri: process.env.NODE_ENV !== 'production' ? 'http://localhost:8000/api/graphql/' : '/api/graphql/',
|
||||
uri,
|
||||
|
|
@ -42,6 +42,12 @@ export default function (uri) {
|
|||
});
|
||||
|
||||
const errorLink = onError(({response, operation, networkError, graphQLErrors}) => {
|
||||
|
||||
if (networkError && networkErrorCallback) {
|
||||
networkErrorCallback(networkError.statusCode);
|
||||
return Observable.of();
|
||||
}
|
||||
|
||||
if (graphQLErrors) {
|
||||
graphQLErrors.forEach(({message, locations, path}) =>
|
||||
console.log(
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ if (process.env.GOOGLE_ANALYTICS_ID) {
|
|||
Vue.directive('click-outside', clickOutside);
|
||||
Vue.directive('auto-grow', autoGrow);
|
||||
|
||||
const publicApolloClient = apolloClientFactory('/api/graphql-public/');
|
||||
const privateApolloClient = apolloClientFactory('/api/graphql/');
|
||||
const publicApolloClient = apolloClientFactory('/api/graphql-public/', null);
|
||||
const privateApolloClient = apolloClientFactory('/api/graphql/', networkErrorCallback);
|
||||
|
||||
const apolloProvider = new VueApollo({
|
||||
clients: {
|
||||
|
|
@ -140,7 +140,14 @@ function redirectStudentsWithoutClass() {
|
|||
}).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) => {
|
||||
|
||||
// handle logout
|
||||
if (to.path === '/logout') {
|
||||
privateApolloClient.resetStore();
|
||||
|
|
@ -154,7 +161,7 @@ router.beforeEach(async (to, from, next) => {
|
|||
return
|
||||
}
|
||||
|
||||
if (to.name !== 'noClass' && loginRequired(to) && await redirectStudentsWithoutClass()) {
|
||||
if ((to.name !== 'noClass' || to.name !== 'licenseActivation') && loginRequired(to) && await redirectStudentsWithoutClass()) {
|
||||
next({name: 'noClass'})
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import json
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
|
|
@ -104,6 +105,6 @@ class UserHasLicenseeMiddleWare(MiddlewareMixin):
|
|||
def process_response(self, request, response):
|
||||
if request.path == '/api/graphql/':
|
||||
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
|
||||
|
|
|
|||
|
|
@ -46,3 +46,13 @@ class MiddlewareTestCase(TestCase):
|
|||
body = b'"{mutation { logout {"'
|
||||
|
||||
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')
|
||||
|
||||
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
|
||||
|
||||
license_expiry = user.license_expiry_date
|
||||
|
|
|
|||
Loading…
Reference in New Issue