How do I programmatically create a video meeting on teams.microsoft.com? - microsoft-graph-api

This might seem rather basic, it seems like it should be the simplest possible API call to make with any video call provider.
I need to:
Get an API key for my web application.
Create a meeting link with the video call provider using the key.
Share that link with an external user via e-mail (or SMS, or whatever, my app does that bit).
Redirect then internal user to the link (possibly in an <iframe>).
Optionally end the meeting afterwards so the link can't be re-used.
Optionally report on who attended and for how long.
It seems like that should be fairly simple (or at least straightforward), and for every other provider I've looked at it is, but for Teams I have struggled to get started.
For instance, in Skype this is (or used to be) simply a POST to https://api.join.skype.com/v1/meetnow/createjoinlinkguest.
I think the API key needs to be generated in Azure, and then the meeting request needs to be made via Microsoft Graph but it also appears like it is not possible to use this API unless a delegated user - i.e. users would have to sign in via their "work or school account".
I think that would mean switching our entire user model over to Microsoft's, a prohibitively large amount of work just to generate video call links.
Is there a way to generate these links without requiring the user to sign in via Microsoft?
Is this only possible via an Azure application instance and Graph API? It seems a very long way round compared to any other provider?

Related

How to use Youtube api v3 on client computer without API-key?

I am planning to make a browser extension which uses Youtube data API v3. Since the code is public to the user, I am unable to use my API-key in the code. What is the correct way to use API in such a scenario? Also, since the API call will be made from user's browser, is there any other way to fetch data without using API-key at all?
TL;DR
On the API screen of Google Cloud Console, create a new key or edit an existing one to have no restriction. This will enable anyone to use this key to make requests the moment you publish it. There is no way to use the YouTube API without a key (or token respectively, when using OAuth). Your clients are allowed to consume up to 50.000.000 quota units per day, after which your app will essentially break for the rest of the day unless you buy more quota.
However, I have to disagree with the statement that you cannot (or "shouldn't") publish your API key; in certain scenarios, this may very well be desired.
Detailed Explanation
Web application keys used to be organized in two groups: Server keys and browser keys, the former of which where to be kept secret on the server of the web application, while the latter was sent to the client for use in JavaScript. Server keys could be configured to only be accepted from certain IP addresses. That way, even if someone got hold of your key, they wouldn't be able to use it. Browser keys could be restricted to a specified referrer, i.e. the domain (as in DNS) of your web application, so it wouldn't work on other sites beside your own either.
Nowadays, there is no distinction between server and browser keys anymore, they are simply called "API keys". This union makes perfect sense to me, since the only difference between the two types was how they were restricted. With the new API keys, one can still choose how to restrict its usage - or choose to not restrict the key at all.
This is where we get back to your case: It is, of course, possible to publish a key and at the same time not restrict it. Depending on how many users are using your app (and will be using it in the future) and how many are using your key for their own app (which you have no control over), the 50 million quota limit will work out for you or it will not.
An then there's responsibility as well. You are responsible for the queries that are made with your API key. This is probably one of the reasons why YouTube doesn't allow for requests without a valid key: They need to stay in control of their service and, naturally, want to protect it from DOS attacks. If someone does mischief with your key, you are the one who gets punished for it, usually by deactivation of the key.

How can I download a OneDrive file with Office365 REST API into a Ruby variable?

I'm building a Ruby on Rails app, and I'd like to integrate some Office365 features.
For instance : I would like to download a file from OneDrive and then attach it to an Email in order to send it via Outlook rest API.
I found this get Item content OneDrive REST API but I dont understand how to use it.
I understand that I have to send a GET request (formated as explained in msdn.microsoft.com) with Rails, which will then provide me a "a pre-authenticated download URL" to download the file.
Then I will have to send a second GET request with this a pre-authenticated download URL to start the download, but I don't understand how to deal with the Response in order to save the file into a variable.
How can I retrieve the file into a variable of my Ruby on Rails App, so that I can attach it to an Email with an Outlook REST API to send it from my own Rail controller ?
Also this workflow is really not optimized in term of Bandwidth and Processing (3 REST API request + 1 download + 1 upload), it will work.
However if it exist a single REST API that direclty attach a OneDrive file to an email to send it, that would ease a lot my life, save energy, save money from Microsoft datacenter, and spare the planet ecology.
Any tutorial, examples, or more explanatory doc would be much appreciated.
--- EDIT ---
Adding link to the email is not wished as the email may have to be send to someone outside of Office365 users, and public link are a security issue for confidential documents.
Any help is welcome.
There isn't a single REST API call you can make currently to do what you want, although being able to easily attach a file from OneDrive to a new email message is a great scenario for Microsoft Graph API, it just isn't supported right now.
If you want to attach the file, you need to do as you mentioned, download the contents of the file, and then upload it again as an attachment to the message.
However, I'd recommend sending a link to the file instead, even though you mentioned you don't want to do that. OneDrive for Business now supports "company shareable links" which are scoped to just the user's organization instead of being available totally anonymously.
Something else to consider: The security concerns of sending an anonymous link aren't that different than sending an attached file. In fact, the anonymous link can be more secure, because access to the file can be monitored and revoked in the future (unlike the attachment, which will always be out there).

How do I get revenue reports from a YouTube CMS account using an API (for an MCN)?

I have access to a YouTube CMS account (for an MCN). On YouTube I can do lots and lots of things with it and this also includes downloading CSV reports which contain detailed information about earnings.
However I want to do some automatic processing of that data and thus access the data using an API instead of a manual CSV download. It looks like the YouTube Analytics Content Owner Reports should contain these data as well, thus I tried to get some data from this API (for now only using the API Explorer) but the only thing I was able to get was a "Forbidden" response.
The API Explorer tells me that for a CMS account I need to specify contentOwner==OWNER_NAME but there is nowhere an explanation what that OWNER_NAME would be. I tried to just insert the displayed name of my CMS account, replacing spaces with underscores, but no success. How do I find out what my owner name is?
Additionally, when I authenticate using OAuth I receive as usual the list of accounts where I can choose which one to use (e.g. all the YouTube channels I am a manager of), but the CMS account is not listed. However if I go to YouTube I can click on the top right corner and then switch to the CMS. No idea if that is important...
Then again, maybe I am totally on the wrong track, because I want to get the reports for all channels connected to my MCN but that does not mean that I own the content. So maybe I am no content owner? In this case: Which is the correct way to request the reports from the API?
First of all, the CMS account is not a separate account you can log in via Oath. It is more like a privilege and it is connected to one of your google/youtube accounts. This is in contrast to youtube's regular channel-management, where each channel has it's own login credentials.
I attached a screenshot of my youtube account-selector-view, where the CMS belongs to the account name#email.com, which is also the account you have to use for oauth authorization to access your CMS reports.
Furthermore you can see the name of the CMS, in this case it "CMSName". So, generally this is the name you would use for contentOwner==CMSName. However, your CMS Name seems to include whitespaces. Unfortunately, i cannot reconstruct this case because of missing admin-rights, but i would suggest you the _ for whitespaces too, because " " and "%20" do not map the regular expression for valid params.
But you said, that you had no success by trying it. But there are too error scenarios:
403 Forbidden: The name of the CMS could either be wrong or the selected OAth account does not have the required privileges. Do you have all required Scopes and selected the correct account?
400 Bad Request: This happens when the request is invalid per se. So if you choose contentOwner==CMSName as ids param, a filter parameter is always required, e.g. channel==[ChannelIdForWhichIHaveCMSRights]. So, a API request, that should generally work, would look like this: https://www.googleapis.com/youtube/analytics/v1/reports?ids=contentOwner%3D%3D[CONTENTOWNER_ID]&start-date=2015-01-01&end-date=2015-01-15&metrics=views&filters=channel%3D%3D[CHANNEL_ID_WITH_CMS_RIGHTS]&access_token=[OATH_TOKEN_FOR_RIGHT_ACCOUNT]
If both cases won't work for you and you're still getting 403 errors, let us do some debugging and try to fetch the content Owner Id. I will now introduce the YouTube Content ID API https://developers.google.com/youtube/partner/.
A few words in advance: You have to activate the API in your developer console, like any other API you want to use for your app. BUT:
Note: The YouTube Content ID API is intended for use by YouTube content partners and is not accessible to all developers or to all YouTube users. If you do not see the YouTube Content ID API as one of the services listed in the Google Developers Console, see www.youtube.com/partner to learn more about the YouTube Partner Program.
You don't see it in the list auf available APIs, unless your account is connected to a CMS and some time has past... It takes 7-14 days unless the Content ID API is available for your account. This is a information i got from the support, but they told me, that it is an automated step.
So, now lets assume, that you already have access to the Content ID API.
You can fetch a list of contentOwnerShips that belong to an account. You can use the API explorer https://developers.google.com/youtube/partner/docs/v1/contentOwners/list#try-it just use as param fetchMine=true and authorize with the https://www.googleapis.com/auth/youtubepartner-content-owner-readonly scope. The response looks like this:
{
"kind": "youtubePartner#contentOwnerList",
"items": [
{
"kind": "youtubePartner#contentOwner",
"id": "[CMS_ID]",
"displayName": "[DisplayName]",
"primaryNotificationEmails": [
"mail#random.xx"
],
"conflictNotificationEmail": "mail#random.xx",
"disputeNotificationEmails": [
"mail#random.xx"
],
"fingerprintReportNotificationEmails": [
"mail#random.xx"
]
}
]
}
This is where you get your CMS_ID from, you can also use it for any API Request as onBehalfOfContentOwner.
To get a list of all channels that belong to the ownership, simply make this request
"https://www.googleapis.com/youtube/v3/channels?part=contentDetails&managedByMe=true&onBehalfOfContentOwner=[CONTENTOWNER]&access_token=[ACCESS_TOKEN]"
But this request requires the granted "https://www.googleapis.com/auth/youtubepartner" scope.
Hoe this could help you, feel free to ask further questions.

Setting up third-party server to interact with Game Center

I'm thinking of adding a feature to my iOS game to allow players to create their own game levels, share them with other players, rate them, etc. There'd be a public repository of user-created levels, sortable by creation date, rating, difficulty, or other criteria.
This kind of functionality would necessitate a third-party server. I was thinking I'd create a RESTful API using Sinatra and run it on Heroku. My question is: what would be the best way to authenticate requests to this API? I would prefer not to require players to create a username and password. I'd like to just use Game Center's ID system.
Any suggestions? I've never done any server-side stuff before so any help is appreciated!
Clarification
Yes, I'm aware that Apple doesn't provide its own system. But it does give developers access to unique Game Center identifiers (developer.apple.com/library/mac/#documentation/…) and I was hoping I could use that somehow to roll my own authentication system without requiring users to sign on via Facebook/Twitter/etc. If that's possible.
Looks like as of iOS 7, this is possible with Game Center using:
[localPlayer generateIdentityVerificationSignatureWithCompletionHandler]
Once you have verified the identity of the player using the generateIdentity call,
Associate the player id with a user on your server's db
Use whatever access token / authentication pattern your REST framework provides for subsequent calls
https://developer.apple.com/library/ios/documentation/GameKit/Reference/GKLocalPlayer_Ref/Reference/Reference.html
Also for reference, here is the dictionary that we end up sending off to our server based on the response from generateIdentityVerificationSignatureWithCompletionHandler
NSDictionary *paramsDict = #{
#"publicKeyUrl":[publicKeyUrl absoluteString],
#"timestamp":[NSString stringWithFormat:#"%llu", timestamp],
#"signature":[signature base64EncodedStringWithOptions:0],
#"salt":[salt base64EncodedStringWithOptions:0],
#"playerID":localPlayer.playerID,
#"bundleID":[[NSBundle mainBundle] bundleIdentifier]
};
edit: as if when I posted this there was no official solution from Apple, but there is now. See the other answers for that, or read on purely for historical / backwards-compatibility interest.
Apple doesn't provide any sort of system for using Apple ID authentication (which includes Game Center) with third-party services. You're on your own for authentication, though you could look into OAuth for allowing single-sign-on via Facebook/Twitter/etc. (Just beware that not everyone has a Facebook/Twitter/etc identity, or one that they want to use for your game.)
In theory, the playerID property on GKPlayer is unique, constant, and not known to anyone else. So, in theory, you could use it for "poor man's authentication": present it to your server, and that's all the server needs to look up and provide player-specific stuff. But this is like authentication by UDID, or by user name only -- the only security it provides is obscurity. And what happens when you have a user who's not signed into Game Center?
Andy's answer is on the right track, but to finish the story: in those docs that he links to, there's an explanation of how to actually authenticate against Apple services that the GameCenter user actually is who he is claiming to be. Link to that part of the docs is below. Basically, the call on the client to generateIdentityVerificationSignatureWithCompletionHandler gives your some data including a URL. You give that data and the URL to your own server, and then from your server you can hit that URL to authenticate the user with the rest of the data that was provided by the call to generateIdentityVerificationSignatureWithCompletionHandler.
https://developer.apple.com/library/ios/documentation/GameKit/Reference/GKLocalPlayer_Ref/index.html#//apple_ref/occ/instm/GKLocalPlayer/generateIdentityVerificationSignatureWithCompletionHandler:
I had a heck of a time figuring this out. I finally used a few hints from this answer, a couple of other SO answers, the php docs and some lucky guessing to come up with this complete answer.
NOTE: This method seems very open to hacking, as anyone could sign whatever they want with their own certificate then pass the server the data, signature and URL to their certificate and get back a "that's a valid GameCenter login" answer so, while this code "works" in the sense that it implements the GC algorithm, the algorithm itself seems flawed. Ideally, we would also check that the certificate came from a trusted source. Extra-paranoia to check that it is Apple's Game Center certificate would be good, too.

Embedding Flash Media Services (Red5) and Authorization

An architectural question.
My site needs to allow the user to record video and upload it to the "site". I've been poking around a fair bit and it seems I have to use some kind of media server to achieve this aim. As I'm introducing this secondary server into the system (I seek to embed the flash app residing on this server into the HTML delivered by the site) it occurs to me that this broadens the scope of security a lot. What scares me is attackers trying to embed the flash app themselves or attempting to impersonate clients (or anything else I haven't thought of yet!).
I was therefore wondering how people secure their applications with such an architecture. Sure I can do what is suggested here, a decent band-aid for now but afaik the domain information can technically be falsified by the client.
I could separate out the auth of the site giving me a WebServer, an AuthServer and a MediaServer enabling the MediaServer to separately auth. Getting the user to log into both sites is obviously onerous and passing around the user's login creds and securing all connections sounds ugly and averse to best practice.
As far as I can see my best bet is some kind of temporary token that the auth server creates. So the website kicks the auth server after logging in to generate the token which the site can then pass to the media server (as part of the flash vars) and the MediaServer itself can use to double check against the auth server.
I'm relatively new to Red5, Flash and web security so I was wondering if the following sounds sane, secure and/or necessary. Also if anyone knows of decent tools to use for such an auth system and whether there is something already kicking about in ASP.NET auth for such a purpose.
the solution provided in your link ... you should read my second comment.
The first about virtual hosts is wrong! My comment does actually tell you (at least one) solution to secure your app.
You could for example pass a SESSION_ID in the connect method to Red5. The user would get the SESSION_ID from another webservice call before he invokes the record or playback method.
The SESSION_ID might be even some kind of temporary token, that is only valid for 15 minutes and only usable a single time for exactly that video. How far you implement that is a matter of how secure your mechanism needs to be.
Sebastian

Resources