How do I access data for all of my students? - khan-academy

I'm making an app that authenticates a coach with KA's API, in order to present statistics and reports on the progress of each student.
How do I see "For whom am I a coach" (inverse of /api/v1/user.coaches)?
or otherwise request user and progress data for all my students?

You can request /api/v1/user/students to get a list of the currently authenticated users' students. Note that this is an undocumented endpoint, not sure if that's on purpose or not, but I suspect just an oversight because IIRC I've seen them reference it on github issues in the past.
I added that endpoint to the khan npm module in this PR: https://github.com/weo-edu/khan/pull/4
An important caveat to note is that as of this writing, you won't be able to request students on behalf of a user who has authenticated your application, only the user who created the app you're currently using.
Put another way: If I create an application called "hello" while logged in as "Jeffrey", I can get all of Jeffrey's students by authenticating with the "hello" app. However, If I log in as Lisa via the "hello" app (via oauth, e.g. passport-khan), I'll have an access token but the Khan API will refuse my request because Lisa did not create the "hello" app.
This behavior is documented (albeit a bit confusingly) in this wiki page, here's the relevant paragraph:
It is recommended that schools have one teacher/coach account that registers for an API key. This enables a situation where the logged-in user is the same as the third-party developer, who then can access their own students' data pursuant to Khan Academy's "coach" relationship. For example, suppose the principal of Riverdale High wished to export data for multiple students via the API. The principal would create a teacher/coach account, perhaps called "RiverdaleHighAPI," and register for an API key. The principal would then ask all students of Riverdale High to add "RiverdaleHighAPI" as a coach, either directly or via several class codes. When accessing the API with "RiverdaleHighAPI" as the logged in user, the principal would be able to access the data for all students that have added "RiverdaleHighAPI" as a coach. The app would not have access to any other coaches' student data, even if another coach logged in through the app. To protect student privacy, we do not allow indirect consent through the coach, and we require each student to explicitly grant permission to access their data. Please note that we are working to improve this functionality; for the time being, this "RiverdaleHighAPI" account should only be used by the school's API client, not by any actual teacher or coach.
Lastly, khan actually encourages public use of their internal API. They recommend opening up your developer console while logged in to khan and looking for the endpoints that return the data you want. (see this note on their authentication document).
This is obviously a fairly non-standard practice and I assume the endpoints would be subject to breaking changes without warning. Also you'll be flying documentation free. That said, this approach may be the most robust option for your purposes. Here's the quote from their wiki for posterity:
The API explorer documents our public API, which has URLs starting with /api/v1, but unfortunately it's not very well-maintained and lacking in a few areas.
If you're feeling adventurous, though, you're welcome to use any internal undocumented API endpoints. For example, if you load a Khan Academy video page and use your browser's developer tools to look at the ajax requests being sent, you'll see that it gets a URL like /api/internal/videos/aubZU0iWtgI/transcript, which contains a JSON response with the video subtitles. That "internal" in the name means that we don't provide documentation, and we may remove the endpoint or change the format in the future, but you're welcome to use any internal endpoints if you keep those caveats in mind.

Related

Migrating Users From Facebook's "Raw" Authentication to Firebase Based Facebook Authentication

I am working on a project which needs User Authentication. The "Clients" are iOS (Swift) or Android (Kotlin) native applications. The original form of the API (NodeJS) used Facebook and Account Kit for OAuth and Phone authentication respectively. Since Account Kit shutdown, we moved to Firebase Phone Authentication for Phone but left Facebook in its original form. Now, we're wanting to consolidate our Authentication providers (to Firebase) but I can't seem to find a way to "convert" or "import" Facebook users to Firebase-based Facebook users.
So far, I've read through the Documentation, including the category about importing users, but it doesn't seem to indicate an ability to maintain backwards compatibility, while also moving forward to Firebase. What I mean is, it has an ability to set information, but it doesn't indicate that the same information will be used to authenticate that user as the same unique visitor.
What I am looking for is either transitory logic, which will handle this during login, or preferably, a "bulk-insert" type migration. Essentially, I want to have it setup so that the API only needs to keep a single authentication UID, and use only a single third party (even if they then use another subsequent third party) while maintaining user uniqueness (so that it doesn't create a new user for the same Facebook account).
Part of my problem in creating a temporary patch (not necessary if the main question is answered) is that I don't know of a way to differentiate between a Facebook UID and a Firebase UID to fork the logic. Again, this is only relevant if there isn't a solution for migration.
Feel free to request any more details that would be useful.
Update #1
I realized my question was open ended in what I was asking. I've been digging further and can better define my question:
I need a way to bulk insert users into Firebase's Authentication with a provider of Facebook. I know I can import them, via admin.auth().importUsers([...]) and that I can create accounts via admin.auth().createUser({...}) but when I do the former I can't seem to get back the user's UID, and the latter doesn't seem to allow specifying a provider. Am I missing something?

How to use DocuSign on behalf of a single user, but with dynamic redirection post signing ceremony?

My use case is thus:
I will have access to a single DocuSign account which would belong to Acme Inc. (I am currently using a sandbox account).
Acme Inc. has many branches, each with it's own employees with different documents that they must sign depending on which branch they work in.
From my internal application, the Admins of the branches will upload documents and set the emails addresses that the documents must be sent to.
The employees will complete the signing ceremony after following the link in the mail that they will receive.
MAIN ISSUE - Once the signing ceremony is complete, I require the employee to be redirected to a certain page of the internal application where they must complete some additional steps.
What I have so far:
I ran the example provided here. The issue with this is the permission request. I do not want an access prompt, rather, I want this done in the Admin Panel itself so that requests to the DocuSign API from my Server Application contain a valid token or receive a new one in case the existing one has expired. I saw from here that the JWT Grant system fit my use case, and I ran that using consent from a single user, however, I am stuck trying to figure out how to redirect the signer (employee) to the page I want with some parameters in the redirection URI. This can be as simple as the one provided (state=123) in the (eg-01) Embedded Signing example provided with the Auth Grant sample.
I apologize for not having any code snippet to show as I have not integrated anything into my internal application as of yet, I am merely running the code from the GitHub examples. Please let me know if I need to provide any additional information in order to facilitate your understanding of my requirements.
Any help provided would be much appreciated!
I think your main issue is the authentication type you are using.
You used the example showing Auth Code Grant, which does require users to log in.
You could instead use JWT (JSON Web Token) which does not require that (only once, and that can be done by you).
The code for making APIs and redirecting after signing ceremony etc. is the same. All you have to do is change the code that was used to obtain the access token (and also you need some configuration changes).
You can find nodeJS example of JWT here - https://github.com/docusign/eg-01-node-jwt
If you want to read more about JWT - https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-jsonwebtoken

docusign custom connector pricing plans and API base path doubts

I have some doubts regarding the custom connector we are trying to build for docusign : -
Regarding the license plan that need to be bought by the customers who will be granting access for our connector to collect data from their docusign organization account. I am looking at the link https://www.docusign.com/products-and-pricing. API access support is mentioned in only the advanced solution. So I was wondering whether only we need to have "Advanced solutions plan with APIs support" plan or all our customers need to API access support in order to fetch their data.
As per the documentation, to make the REST API calls we need two fields 'base_uri' and 'account_id' (https://developers.docusign.com/esign-rest-api/guides/authentication/user-info-endpoints). Now, the response of userInfo API call gives an array of accounts and its respective fields. My doubt is, if multiple authenticated users (more than one accounts) are returned in this array but all are part of same organization, will they all have different account_ids. Main concern here is, will there be several Base Paths (https://developers.docusign.com/esign-rest-api/guides/authentication/user-info-endpoints#form-your-base-path) to make API calls?
2a. Further question is, what is the significance of 'is_default' field?
Is this related to main account (if is_default is true) using which we will create our Base Path?
Since this is a tech/engineering forum I'm going to answer only question #2 as question #1 is more of a business/sales question.
The reason you may get multiple accounts is that an authenticated user in DocuSign can be a member of multiple accounts. That said, it's the same user. Meaning, say foobar#blah.com has an account 123 with company X and account 456 with his school, then it's possible that when foobar#blah.com authenticates (With the same password!) to DocuSign we have a list of accounts associated with that user. We give you all of them when you make the API call. The default one is the main one that you would see when you log into our web app. You can decide yourself as the user which one is the default. Users who log into our web-app then see an option at the top-right to change accounts.
and yes, every API call is associated with a specific account. So when you construct the urls for your API - you do need to know which account for this user you are making the API call for. Your application can decide how to handle this.
Hope this helps.

Obtaining Instagram Access Token

We have a client who has a simple Instagram feature on the site to pull photos by a certain tag. They just noticed it isn't working. Getting an error - invalid access token. I guess since the 1st because of the updates. We didn't used to need an access token since we're not doing anything with users - just tags.
Now it looks like we need one and the documentation makes zero sense on how to obtain one. And it seems like they're not accepting most apps. The app is in sandbox mode too. So I'm assuming it's because it got switched to that? Got no notification of this happening.
The first step in documentation to get an access token is "Direct the user to our authorization url." What does that even mean? There's not a link provided or anything. It also says "Company Name, Contact Email and Privacy Policy URL are required to start a submission." Our app doesn't have a privacy policy... it's just a simple tag feed. I don't understand why everything is so complex to have a simple tag feed.
Is there a wait time to get the app approved..if it gets approved... Do I have to have it approved before getting an access token? This isn't outlined anywhere.
You got it right. As of June 2016 any Instagram API calls require an access token.
Getting an access token is described in the documentation. App approval is not required.
There are two ways to get one: server-side or client-side. The second option (called implicit authentication) can only be used when implicit OAuth is enabled in the client settings (Manage Clients > Edit Client > Security > Disable implicit OAuth). It is disabled by default.
In either case you need to redirect the user to the authorization URL to obtain an access token.
The URL for explicit mode (server side) is:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code
The URL for implicit mode (client side) is:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token
After this you will be redirected to the REDIRECT-URI, which will be passed an argument. For explicit mode this will be a query string with a code, while for implicit mode you will get the access token directly as a hash:
http://your-redirect-uri?code=CODE
http://your-redirect-uri#access_token=ACCESS-TOKEN
For implicit mode you can then get the access token from the window.location.hash in Javascript.
For explicit mode, however, you need to further process the code to obtain the access token. You can read how this can be done in the API Documentation. I'm not going to take this any further here.
The problem is that every user who wants to see your feed needs to login to Instagram (and have an account) in order to view it. In your case this might not be desired. However, there are a few options to get around this (rather annoying) problem:
You can reuse your own (already obtained) access token(s) to display the Instagram feed for every user. You will need to be aware of rate limits for each token. For sandboxed apps this is 500 API calls / hour, while live mode allows 5000 API calls / hour. [source] You could store tokens in a table and use them in a round-robin manner, to allow more API calls. This involves manually obtaining a bunch of tokens which your application can use (the more the better). This might not be the ideal solution considering Instagram doesn't warrant access tokens to have an unlimited lifetime.
You can retreive JSON data without authentication by appending /media/ to a user page URL, as described in this post. No tokens or client IDs are required for this to work. However, this only works for users, not for tags. Besides, Instagram doesn't document this feature so it is not garanteed to work in the future.
You can use an aggregator like Juicer or Dialogfeed instead which will handle access tokens for you. This is usually not free of charge.
I'm also in the process of making an Instagram feed for my website, and this is what I concluded from my research. Please bare with any errors I made.
Edit: Here are some more limitations for sandbox apps.
In sandbox mode you can only access data from sandbox users (thus users who received a sandbox invite). This means that:
Media retreived by user, e.g. /users/{user-id}/media/recent, will return an empty response if the user is not any of the sandbox users.
Media retreived by tag, e.g. /tags/{tag-name}/media/recent, will only contain tagged media belonging to sandbox users.
Thus, for a tag feed to work, it needs to be live (reviewed and approved). If you don't want to do this, the only alternative is to use an aggregator as I mentioned above.

Foursquare API Access without registered application

I have just an idea for now to develop an application based on foursquare API.
I checked in the website that a creation of an application inside the foursquare is needed to access the api functions.
There some form fields in the application creation that cannot be filled by me as I don't have an application yet, like web address home page, privacy police page, etc.
I want to perform some tests for a certain time and then choose if I'll proceed with the application development or not.
For now I just need access for the venue stats function. Do you know if it's possible to have access to this function without have an official application?
Regards,
Rodrigo Lima
You need to create an application in order to get an OAuth token, which you need to call venues/stats. In practice, during testing, the only real field that needs to be accurate is the redirect URI, which you'll need for OAuth. The others can take dummy values for now, so long as you go and change them before you publish.

Resources