Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-implements LTI-restricted logins #1631

Open
wants to merge 2 commits into
base: dev/10.3.1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion fuel/app/classes/controller/users.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,15 @@ public function get_login()
->set('page_type', 'login');

Css::push_group(['login']);
Js::push_group(['react', 'login']);

if (\Config::get('auth.restrict_logins_to_lti_single_sign_on', false) && ! $direct_login)
{
Js::push_group(['react', 'restricted']);
}
else
{
Js::push_group(['react', 'login']);
}
}

public function post_login()
Expand Down
10 changes: 9 additions & 1 deletion fuel/app/classes/controller/widgets.php
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,15 @@ protected function build_widget_login($login_title = null, $inst_id = null, $is_
->set('page_type', 'login');

Css::push_group(['login']);
Js::push_group(['react', 'login']);

if (\Config::get('auth.restrict_logins_to_lti_single_sign_on', false))
{
Js::push_group(['react', 'restricted']);
}
else
{
Js::push_group(['react', 'login']);
}
}

Js::push_inline('var EMBEDDED = '.($is_embedded ? 'true' : 'false').';');
Expand Down
1 change: 1 addition & 0 deletions fuel/app/config/js.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
'no_permission' => [$webpack.'js/no-permission.js'],
'closed' => [$webpack.'js/closed.js'],
'embedded_only' => [$webpack.'js/embedded-only.js'],
'restricted' => [$webpack.'js/logins-restricted.js'],
'pre_embed' => [$webpack.'js/pre-embed-placeholder.js'],
'help' => [$webpack.'js/help.js'],
'404' => [$webpack.'js/404.js'],
Expand Down
8 changes: 4 additions & 4 deletions fuel/packages/ltiauth/classes/auth/login/ltiauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ class Auth_Login_LtiAuth extends Auth_Login_Materiaauth
{
static public function restrict_logins($bypass=false)
{
// allow admin logins or do nothing if normal logins aren't restricted
if ($bypass || ! \Config::get('auth.restrict_logins_to_lti_single_sign_on', true)) return;

throw new \HttpNotFoundException();
// this method can be extended to limit logins
// the prior restrict_logins_to_lti_single_sign_on configuration check that was present here has been moved:
// the user and widget controllers perform the config check and serve different js based on whether the condition is met.
return;
}
}
48 changes: 48 additions & 0 deletions src/components/logins-restricted-to-lms.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { useState, useEffect } from 'react';
import Header from './header'
import Summary from './widget-summary'
import EmbedFooter from './widget-embed-footer';

const LoginsRestrictedToLMS = () => {

const [state, setState] = useState({
context: ''
})

const waitForWindow = async () => {
while (!window.hasOwnProperty('CONTEXT')) {
await new Promise(resolve => setTimeout(resolve, 500))
}
}

useEffect(() => {
waitForWindow()
.then(() => {
setState({
context: window.CONTEXT,
is_embedded: window.EMBEDDED != undefined ? window.EMBEDDED : false,
})
})
},[])

return (
<>
{ state.is_embedded ? '' : <Header /> }
<div className="container widget">
<section className="page">
<Summary/>

<div className="detail icon-offset">
<h2 className="unavailable-text">Login from your LMS</h2>
<span className="unavailable-subtext">You must access Materia from a course in your LMS.</span>
{ state.context && state.context != 'widget' ? <p>For additional help and support, visit our <a href="/help#students">support page</a>.</p> : '' }
</div>

{ state.context && state.context == 'widget' ? <EmbedFooter/> : '' }
</section>
</div>
</>
)
}

export default LoginsRestrictedToLMS
2 changes: 1 addition & 1 deletion src/components/pre-embed-common-styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ body {
.unavailable-subtext {
margin-bottom: 40px;
font-size: 0.8em;
font-size: 600;
font-weight: 700;
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/logins-restricted.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'
import {createRoot} from 'react-dom/client'
import { QueryClient, QueryClientProvider, QueryCache } from 'react-query'
import LoginsRestrictedToLMS from './components/logins-restricted-to-lms'

const queryCache = new QueryCache()
export const queryClient = new QueryClient({ queryCache })

const root = createRoot(document.getElementById('app'));
root.render(
<QueryClientProvider client={queryClient} contextSharing={true}>
<LoginsRestrictedToLMS />
</QueryClientProvider> )