Github API: determine if user or org - github-api

Given the URL https://github.com/foo/bar, I want to be able to get all the repos for foo. If foo is a user, I need to call api.repos.getForUser({username: 'foo'}) and if an org, I'll need to call api.repos.getForOrg({org: 'foo'}).
My problem is: how can I tell if "foo" is an org or a user?
Right now, I "solve" it in the costly way of trying to get an org called "foo", if I got it, I try to get its repos; if I end up getting an exception (I use promises) and if the code of the exception is "404", I assume "foo" is a user, and try to get user repos.
This is obviously inefficient, and has the side effect of adding calls that may trigger rate limit.
Is there an easier way to know whether "foo" is a user or an org?

As we all know, handling exceptions is costly. So instead of trying to get an org and handling the 404, you could instead look at the type property of the response to https://api.github.com/users/<username> in order to determine if the "user" is a user or organization and then proceed accordingly.
For example a call to my GitHub user API https://api.github.com/users/raghav710 returns
{
"login": "raghav710",
...
"type": "User",
...
}
And a call to an organization like https://api.github.com/users/Microsoft returns
{
"login": "Microsoft",
...
"type": "Organization",
...
}
Update: Doing it in a single call
I understand that you are already trying to access a URL https://github.com/<user or organization>/<repo name> and therein trying to get all the repos of that user or organization.
A suggestion is, instead of trying to do a GET on the above link, you could do a GET on https://api.github.com/repos/<user or organization>/<repo name>
For example doing a GET on https://api.github.com/repos/Microsoft/vscode
Gives
{
"id": 41881900,
"name": "vscode",
"full_name": "Microsoft/vscode",
"owner": {
"login": "Microsoft",
"id": 6154722,
...
"type": "Organization",
},
"private": false,
"html_url": "https://github.com/Microsoft/vscode",
...
}
As you can see the familiar type field is available under the owner key. You can use this to decide your next call

So even if there's an API call to differentiate, you'll still need that call to determine whether it's a user or not.
Considering the fact that most repositories should belong to users, why don't you reverse the checks? Try to retrieve the user repository, if that fails get the organization repository.
In addition, I'd cache as much information as necessary. Don't retrieve everything in real time while users use your tool. Many things won't change that often, if they're even able to be changed.

Related

Logic App error - ActionFailed. An action failed. No dependent actions succeeded

I'm running into this error - ActionFailed. An action failed. No dependent actions succeeded - when trying to run this logic app to add an IP to be blocked.
Error
I'm not sure where to start. The input looks ok. Help? Thanks in advance!
p.s. - sorry, it won't allow me to post the pics due to not having enough points.
Tried changing some parts of the body. Not sure what to change really.
According to Microsoft's documentation on Submit or Update Indicator API the request body should be as follows:
{
"indicatorValue": "220e7d15b011d7fac48f2bd61114db1022197f7f",
"indicatorType": "FileSha1",
"title": "test",
"application": "demo-test",
"expirationTime": "2020-12-12T00:00:00Z",
"action": "AlertAndBlock",
"severity": "Informational",
"description": "test",
"recommendedActions": "nothing",
"rbacGroupNames": ["group1", "group2"]
}
Since the error you get is too generic, it isn't clear enough to know exactly.
You are not passing in recommendedActions and rbacGroupNames, they may not be required but may want to pass the column even if no value is included.
I would also validate calling this API using manual values (even the exact value from their documentation) and if that does work, use process of elimination to figure out which property is giving you the trouble.
i.e. application might not accept a space value or combining the two values for description should be done outside of the HTTP call using compose and then passed as a single value of the output.

NodeJS - Simplify/Resolve GraphQL query

I am currently writing a Lambda authorizer for an AWS AppSync API, however the authorization depends on the target resource being accessed.
Every resource has their own ACL listing the users and conditions for allowing access to it.
Currently the best I could find would be to get the identity of the caller, look at all the ACLs, and authorize the call while denying access to all the other resources, what's not only highly inefficient, but also extremely impractical, if not impossible.
The solution I had originally came up with was to get the target resource, retrieve the ACL and check if the user fits the specified criteria. The problem is that I am unable to reliably define what's the target resource. What I get from AWS is a request like this:
{
"authorizationToken": "ExampleAUTHtoken123123123",
"requestContext": {
"apiId": "aaaaaa123123123example123",
"accountId": "111122223333",
"requestId": "f4081827-1111-4444-5555-5cf4695f339f",
"queryString": "mutation CreateEvent {...}\n\nquery MyQuery {...}\n",
"operationName": "MyQuery",
"variables": {}
}
}
So, I only have the query string and variables, leaving the actual parsing of this to me. I got to convert it to an AST using graphql-js, but it's still extremely verbose and most importantly, it's structure varies greatly.
My first code to retrieve the target worked for the AppSync console queries, but not the Amplify Front-End, for example. I also can't rely on something as simple as the variable name, as an attacker could quite easily craft a query with an arbitrary name, or even not use variables at all.
I thought about implementing this authorization logic within Lambda Resolvers, what should be simpler in a way, but would require me to use resolvers as authorizers, what doesn't seem ideal, and implement the entire resolver logic when I just want the most trivial possible resolvers.
Ideally I'd like something like this:
/* Schema:
type Query {
operationName(key: KEY!): responseType
}*/
/* Query:
query abitraryQueryName($var1: KEY!) {
operationName(key: $var1) {
field1
field2
}
}*/
/* Variables:
{ "var1": "value1" } */
parsedQuery = {
operation: "operationName",
params: { "key": "value1" },
fields: [ "field1", "field2" ]
};
Is there any way to resolve/simplify the queries from GraphQL to JSON/similar in a way that this information can be easily extracted?
Well, couldn't find anything on it, so I made something myself.
On the off chance someone needs something similar, here's the gist with the code I used: https://gist.github.com/Iorpim/6544dad46060522dd0b17477871bc434
I didn't make it a proper full lib, as it's a very specific use case and it's likely a one-off, and I am also not sure how reliable it is, but it solves my problem!

Multiple output text value setting in watson conversation

I have following node in the conversation. I want to raise the action and based on that need to call the API. In success scenario, will show the output.text[0] and error scenario getting from output.text[1]
{
"output": {
"text": {
"values": [
"I want to get this with success scenario",
"I want to get this with error scenario"
],
"selection_policy": "sequential"
},
"action": "MyAction"
}
}
But when I am accessing this conversation node in node.js, it will always give 1st value, i.e. 'I want to get this with success scenario' It will never give output like 'I want to get this with error scenario' .
How to resolve this issue ?
This is really complicated to answer because depends your Business role inside your Chatbot.
But, if you wanna answer one message according to the Condition...
You can see in your output the selection_policy is sequential, in the other words, first will show the 1st phrase, and just if the condition access again by the user, will show the second message.
"The order in which values in the array are returned depends on the attribute selection_policy."
The better form to solve this is to create two conditions inside the Node flow for each phrase.
For example first condition flow:
if bot recognizes successScenario response "I want to get this with success scenario"
In another second condition flow:
if bot recognizes errorScenario response "I want to get this with error scenario"
And your app with Nodejs will get the value according the condition.
See the official documentation about this here, search about selection_policy.
I have resolved that issue with the following way.
{
"output": {
"text": {
"values": [
{
"successMsg": "success Message",
"errorMsg": "error message"
}
]
},
"action": "MyAction"
}
}
Reason for not going for new node, because with this action, I need to create the API and based on the API call success and fail display this message to the user. Then it will help to save one roundtrip because no need to send results status again to conversation service, it will identify the what to present to user based on the this node itself.

RESTful API design - naming an "activity" resource

When designing the endpoints for an activity resource that provides information on the activity of other resources such as users and organisations we are struggling with naming conventions.
What would be more semantic:
/organisations/activity
/organisations/activity/${activityId}
/users/activity
/users/activity/${activityId}
OR
/activity/users/${activityId}
/activity/users
/activity/organisations/${activityId}
/activity/organisations
There's not a generic answer for this, especially since the mechanisms doing the lookup/retrieval at the other end, and associated back-ends vary so drastically, not to mention the use case purpose and intended application.
That said, assuming for all intents and purposes the "schema" (or ... endpoint convention from the point of view of the end user) was just going to be flat, I have seen many more of the latter activity convention, as that is the actual resource, which is what many applications and APIs are developed around.
I've come to expect the following style of representation from APIs today (how they achieve the referencings and mappings is a different story, but from the point of view of API reference)
-
{
"Activity": [
{
"date": "1970-01-01 08:00:00",
"some_other_resource_reference_uuid": "f1c4a41e-1639-4e35-ba98-e7b169d1c92d",
"user": "b3ababc4-461b-404a-a1a2-83b4ca8c097f",
"uuid": "0ccf1b41-aecf-45f9-a963-178128096c97"
}
],
"Users": [
{
"email": "johnanderson#mycompany.net",
"first": "John",
"last": "Anderson",
"user_preference_1": "somevalue",
"user_property_1": "somevalue",
"uuid": "b3ababc4-461b-404a-a1a2-83b4ca8c097f"
}
]
}
The StackExchange API allows retrieving objects through multiple methods also:
For example, the User type look like this:
-
{
"view_count": 1000,
"user_type": "registered",
"user_id": 9999,
"link": "http://example.stackexchange.com/users/1/example-user",
"profile_image": "https://www.gravatar.com/avatar/a007be5a61f6aa8f3e85ae2fc18dd66e?d=identicon&r=PG",
"display_name": "Example User"
}
And on the Question type, the same user is shown underneath the owner object :
-
{
"owner": {
"user_id": 9999,
"user_type": "registered",
"profile_image": "https://www.gravatar.com/avatar/a007be5a61f6aa8f3e85ae2fc18dd66e?d=identicon&r=PG",
"display_name": "Example User",
"link": "https://example.stackexchange.com/users/1/example-user"
},
"is_answered": false,
"view_count": 31415,
"favorite_count": 1,
"down_vote_count": 2,
"up_vote_count": 3,
"answer_count": 0,
"score": 1,
"last_activity_date": 1494871135,
"creation_date": 1494827935,
"last_edit_date": 1494896335,
"question_id": 1234,
"link": "https://example.stackexchange.com/questions/1234/an-example-post-title",
"title": "An example post title",
"body": "An example post body"
}
On the Posts Type reference (Using this as a separate example because there is only a handful of methods to reach this type), you'll see an example down the bottom :
Methods That Return This Type
  posts
  posts/{ids}
  users/{ids}/posts 2.2
  me/posts 2.2
So whilst you can access resources (or "types" as it is on StackExchange), through a number of ways including filters and complex queries, there still exists the ability to see the desired resource through a number of more direct transparent URI conventions.
Different applications will clearly have different requirements. For example, the Gmail API is user based all the way - this makes sense from a users point of view given that in the context of the authenticated credential, you're separating one users objects from another.
This doesn't mean google uses the same convention for all of their APIs, their Activities API resource is all about the activity
Even looking at the Twitter API, there is a Direct Messages endpoint resource that has sender and receiver objects within.
I've not seen many API's at all that are limited to accessing resources purely via a user endpoint, unless the situation obviously calls for it, i.e. the Gmail example above.
Regardless of how flexible a REST API can be, the minimum I have come to expect is that some kind of Activity, location, physical object, or other entity is usually it's own resource, and the user association is plugged in and referenced at various degrees of flexibility (at a minimum, the example given at the top of this post).
It should be pointed out that in a true REST api the uri holds no meaning. It's the link relationships from your organizations and users resources that matter.
Clients should just discover those urls, and should also adapt to the new situation if you decide that you want a different url structure after all.
That being said, it's nice to have a logical structure for this type of thing. However, either is fine. You're asking for an opinion, there is not really a standard or best practice. That said, I would choose option #1.

Is there any way to retrieve the name for a gist that github displays

When I browse to a gist on gist.github.com it displays a friendly name. E.g. for
https://gist.github.com/stuartleeks/1f4e07546db69b15ade2 it shows stuartleeks/baz
This seems to be determined by the first file that it shows in the list of files for the gist, but I was wondering whether there is any way to retrieve this via the API?
Not directly, but you can get with the Gist API the JSON information associated to a gist, reusing the id of your url:
GET /gists/:id
In your case: https://api.github.com/gists/1f4e07546db69b15ade2
It includes:
"files": {
"baz": {
"filename": "baz",
and:
"owner": {
"login": "stuartleeks",
That should be enough to infer the name stuartleeks/baz.

Resources