-
Notifications
You must be signed in to change notification settings - Fork 110
Release Teacher 2.4.0 (88) #3513
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,7 @@ import com.instructure.canvasapi2.managers.FileFolderManager | |
| import com.instructure.canvasapi2.models.CanvasContext | ||
| import com.instructure.canvasapi2.models.Course | ||
| import com.instructure.canvasapi2.models.FileFolder | ||
| import com.instructure.canvasapi2.models.Group | ||
| import com.instructure.canvasapi2.utils.ApiPrefs | ||
| import com.instructure.canvasapi2.utils.ApiType | ||
| import com.instructure.canvasapi2.utils.LinkHeaders | ||
|
|
@@ -329,6 +330,7 @@ object RouteMatcher : BaseRouteMatcher() { | |
|
|
||
| fun route(activity: FragmentActivity, route: Route?) { | ||
| val uri = route?.uri | ||
| Logger.i("RouteMatcher:route() - uri: $uri, routeContext: ${route?.routeContext}, primaryClass: ${route?.primaryClass}") | ||
| if (route == null || route.routeContext === RouteContext.DO_NOT_ROUTE) { | ||
| if (route?.uri != null) { | ||
| //No route, no problem | ||
|
|
@@ -364,6 +366,8 @@ object RouteMatcher : BaseRouteMatcher() { | |
| ?.contains("media_attachments") == true | ||
| ) { | ||
| handleStudioImmersiveViewRoute(route, activity) | ||
| } else if (route.routeContext === RouteContext.LTI) { | ||
| handleLtiRoute(activity, route) | ||
| } else if (activity.resources.getBoolean(R.bool.isDeviceTablet)) { | ||
| handleTabletRoute(activity, route) | ||
| } else { | ||
|
|
@@ -477,6 +481,36 @@ object RouteMatcher : BaseRouteMatcher() { | |
| } | ||
| } | ||
|
|
||
| private fun handleLtiRoute(activity: FragmentActivity, route: Route) { | ||
| Logger.i("RouteMatcher:handleLtiRoute()") | ||
| val url = route.uri?.toString() | ||
| if (url.isNullOrEmpty()) { | ||
| return | ||
| } | ||
|
|
||
| // Don't intercept sessionless_launch URLs - they're already being handled by an existing LtiLaunchFragment | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment says "Don't intercept sessionless_launch URLs" but this check might be too broad. Consider whether this should be more specific (e.g., checking for the full path pattern rather than just substring matching). Also, this logic appears duplicated in |
||
| if (url.contains("sessionless_launch")) { | ||
| Logger.i("RouteMatcher:handleLtiRoute() - Skipping sessionless_launch URL") | ||
| return | ||
| } | ||
|
|
||
| val contextId = route.paramsHash[RouterParams.COURSE_ID]?.toLongOrNull() | ||
| ?: route.paramsHash[RouterParams.GROUP_ID]?.toLongOrNull() | ||
|
|
||
| val canvasContext: CanvasContext? = when (route.getContextType()) { | ||
| CanvasContext.Type.COURSE -> contextId?.let { Course(id = it) } | ||
| CanvasContext.Type.GROUP -> contextId?.let { Group(id = it) } | ||
| else -> null | ||
| } | ||
|
|
||
| if (canvasContext != null) { | ||
|
Comment on lines
+496
to
+506
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a potential null safety issue here. If |
||
| val ltiRoute = LtiLaunchFragment.makeRoute(canvasContext, url, sessionLessLaunch = true) | ||
| route(activity, ltiRoute) | ||
| } else { | ||
| handleWebViewUrl(activity, url) | ||
| } | ||
| } | ||
|
|
||
| private fun handleWebViewRoute(context: Context, route: Route) { | ||
| context.startActivity(InternalWebViewActivity.createIntent(context, route, "", false)) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -177,7 +177,9 @@ class LtiLaunchFragment : BaseCanvasFragment(), NavigationCallbacks { | |
| } | ||
|
|
||
| private fun canRouteInternally(url: String) = | ||
| webViewRouter.canRouteInternally(url) && ltiUrl?.substringBefore("?") != url.substringBefore("?") | ||
| webViewRouter.canRouteInternally(url) | ||
| && ltiUrl?.substringBefore("?") != url.substringBefore("?") | ||
|
Comment on lines
179
to
+181
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same sessionless_launch check as in
|
||
| && !url.contains("sessionless_launch") | ||
|
|
||
| override fun routeInternallyCallback(url: String) { | ||
| // Handle return button in external tools. Links to course homepage should close the tool. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -122,7 +122,7 @@ class LtiLaunchViewModel @Inject constructor( | |
|
|
||
| private fun launchLti(url: String) { | ||
| viewModelScope.launch { | ||
| val authenticatedUrl = repository.authenticateUrl(url) | ||
| val authenticatedUrl = if (url.contains("session_token")) url else repository.authenticateUrl(url) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This conditional authentication logic could be problematic. The check
|
||
| if (openInternally || Assignment.internalLtiTools.any { url.contains(it) }) { | ||
| _events.send(LtiLaunchAction.LoadLtiWebView(authenticatedUrl)) | ||
| } else { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider removing this debug logging statement before merging to production. Debug logs with detailed routing information can clutter logs and potentially expose sensitive information in production builds.