-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from Extrawurst/master
add linkedin example and allow token_type to be empty
- Loading branch information
Showing
9 changed files
with
224 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
linkedin.json | ||
linkedin-login-example |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# LinkedIn Connect Example | ||
|
||
If you want to try running this example, please register as a [LinkedIn developer](https://developer.linkedin.com/) and create an App. Then, create a file named `linkedin.json` with contents like this: | ||
|
||
```json | ||
{ | ||
"clientId": "YOUR_APP_ID_HERE", | ||
"clientSecret": "YOUR_APP_SECRET_HERE", | ||
"redirectUri": "http://localhost:8080/login/linkedin" | ||
} | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"name": "linkedin-login-example", | ||
"dependencies": { | ||
"oauth": { | ||
"path": "..\/..\/" | ||
}, | ||
"vibe-d:http": "*", | ||
"vibe-d:core": "*", | ||
"vibe-d:data": "*", | ||
"vibe-d:web": "*" | ||
}, | ||
"versions": [ | ||
"VibeDefaultMain" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import vibe.http.server; | ||
import vibe.web.auth; | ||
import vibe.web.web; | ||
|
||
import oauth.webapp; | ||
|
||
/// | ||
struct AuthInfo | ||
{ | ||
} | ||
|
||
/// | ||
@requiresAuth class LinkedInLoginExample : OAuthWebapp | ||
{ | ||
private | ||
{ | ||
import oauth.settings : OAuthSettings; | ||
|
||
static immutable OAuthSettings _oauthSettings; | ||
static immutable _scopes = ["r_basicprofile"]; | ||
} | ||
|
||
shared static this() | ||
{ | ||
import vibe.core.file : readFileUTF8; | ||
import vibe.data.json : parseJsonString; | ||
import oauth.provider.linkedin : LinkedInAuthSettings; | ||
|
||
_oauthSettings = new immutable(LinkedInAuthSettings)( | ||
"linkedin.json".readFileUTF8.parseJsonString()); | ||
} | ||
|
||
@noRoute @safe AuthInfo authenticate(scope HTTPServerRequest req, scope HTTPServerResponse res) | ||
{ | ||
if (!isLoggedIn(req, _oauthSettings)) | ||
login(req, res, _oauthSettings, _scopes); | ||
|
||
return AuthInfo(); | ||
} | ||
|
||
@path("/") | ||
@anyAuth void getIndex(scope HTTPServerRequest req) | ||
{ | ||
import vibe.http.client : requestHTTP; | ||
import vibe.data.json : Json; | ||
|
||
auto session = this.oauthSession(req); | ||
assert(session, "No session: authenticate() not called??"); | ||
|
||
Json userInfo; | ||
|
||
requestHTTP("https://api.linkedin.com/v1/people/~?format=json", delegate(scope graphReq) { | ||
session.authorizeRequest(graphReq); | ||
}, delegate(scope graphRes) { | ||
auto obj = graphRes.readJson(); | ||
if ("error" !in obj) | ||
userInfo = obj; | ||
}); | ||
|
||
render!("index.dt", userInfo); | ||
} | ||
|
||
@path("/login/linkedin") | ||
@noAuth void getLoginLinkedIn(scope HTTPServerRequest req, scope HTTPServerResponse res) | ||
{ | ||
login(req, res, _oauthSettings, _scopes); | ||
|
||
if (!res.headerWritten) | ||
res.redirect("/"); | ||
} | ||
|
||
@anyAuth void getLogout() | ||
{ | ||
terminateSession(); | ||
render!("logout.dt"); | ||
} | ||
} | ||
|
||
shared static this() | ||
{ | ||
import vibe.http.router : URLRouter; | ||
import vibe.http.session : MemorySessionStore; | ||
|
||
auto router = new URLRouter; | ||
router.registerWebInterface(new LinkedInLoginExample); | ||
|
||
auto settings = new HTTPServerSettings; | ||
settings.sessionStore = new MemorySessionStore; | ||
settings.port = 8080; | ||
|
||
listenHTTP(settings, router); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
extends layout | ||
|
||
block body | ||
h1 Welcome #{ userInfo["firstName"].get!string } | ||
p You've been logged in successfully! | ||
p LinkedIn told me your name is #{ userInfo["firstName"].get!string } | ||
| #{ userInfo["lastName"].get!string } and your headline is | ||
| #{ userInfo["headline"].get!string }. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
doctype html | ||
html | ||
head | ||
title LinkedIn authentication example | ||
body | ||
block body | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
extends layout | ||
|
||
block body | ||
h1 Logout | ||
p You've been logged out successfully! | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
module oauth.provider.linkedin; | ||
|
||
import oauth.provider : OAuthProvider; | ||
import oauth.settings : OAuthSettings; | ||
|
||
import vibe.data.json; | ||
import vibe.http.client; | ||
import vibe.inet.webform; | ||
|
||
import std.exception; | ||
|
||
/++ | ||
Settings for 'linkedin' provider. | ||
OAuthSettings specialized for Linkedin. Just for convenience. | ||
+/ | ||
class LinkedInAuthSettings : OAuthSettings | ||
{ | ||
private bool _rerequest; | ||
|
||
/++ | ||
See OAuthSettings constructor for common documentation. | ||
The 'provider' field may be omitted. If it is included, it MUST be set | ||
to "linkedin". | ||
+/ | ||
this(in Json config) immutable | ||
{ | ||
enforce("provider" !in config || (config["provider"].type == Json.Type.string | ||
&& config["provider"].get!string == "linkedin"), | ||
"LinkedInAuthSettings can only be used with provider 'linkedin'."); | ||
|
||
super("linkedin", config["clientId"].get!string, | ||
config["clientSecret"].get!string, config["redirectUri"].get!string); | ||
|
||
if (config["authType"].type == Json.Type.string | ||
&& config["authType"].get!string == "rerequest") | ||
_rerequest = true; | ||
} | ||
} | ||
|
||
/++ | ||
LinkedIn specialized derivative of OAuthProvider. | ||
This class should not be used directly. It registers itself as an | ||
OAuthProvider with name `linkedin`. | ||
+/ | ||
class LinkedInAuthProvider : OAuthProvider | ||
{ | ||
shared static this() | ||
{ | ||
OAuthProvider.register("linkedin", new immutable(LinkedInAuthProvider)); | ||
} | ||
|
||
private this() immutable | ||
{ | ||
import std.typecons : BitFlags; | ||
|
||
super("https://www.linkedin.com/oauth/v2/authorization", "https://www.linkedin.com/oauth/v2/accessToken", | ||
BitFlags!Option(Option.explicitRedirectUri, | ||
Option.tokenRequestHttpGet, Option.clientAuthParams)); | ||
} | ||
|
||
override void authUriHandler(immutable OAuthSettings settings, string[string] params) const | ||
{ | ||
if (auto liSettings = cast(immutable LinkedInAuthSettings) settings) | ||
if ("auth_type" !in params && liSettings._rerequest) | ||
params["auth_type"] = "rerequest"; | ||
} | ||
} | ||
|
||
unittest | ||
{ | ||
auto linkedin = OAuthProvider.forName("linkedin"); | ||
assert(linkedin, "Name 'linkedin' not registered!"); | ||
assert(cast(LinkedInAuthProvider) linkedin, | ||
"Some unkown OAuthProvider has been registered as 'linkedin'."); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters