From: aBainbridge11 <113794078+aBainbridge11@users.noreply.github.com> Date: Mon, 29 Jul 2024 19:28:46 +0000 (-0400) Subject: Create Twitter X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fcb4cb4dce4f679f171f10b906ebac99e8394d88;p=thirdparty%2Ffreeradius-server.git Create Twitter --- diff --git a/doc/antora/modules/howto/pages/twitter.adoc b/doc/antora/modules/howto/pages/twitter.adoc new file mode 100644 index 00000000000..2807ee35dd6 --- /dev/null +++ b/doc/antora/modules/howto/pages/twitter.adoc @@ -0,0 +1,134 @@ +Note: The required functionality to do basic twitter operations is only available in FreeRADIUS >= v3.0.4 + +# Overview + +The difficult part in twitter integration is signing the requests. If a single character +is incorrect, the signature won't match, and the Twitter API will return an authentication +error. + +The config snippet below shows how this can be done for a simple status update. At the time +of writing there is no xlat method to sort values lexicographically. So in order to use +the more complex API calls, you will need to modify Stage 1.1 and add your other post data +pairs, maintaining lexicographic attribute order manually. + +This is all very much a work in progress, and whether additional example operations get added here will +depend on the actual demand for twitter integration. + +## Getting the tokens + +Follow the link here(https://dev.twitter.com/docs/auth/tokens-devtwittercom) signing up +for an account and creating a new application if necessary. + +## Understanding how signing works + +Twitter has some excellent documents on authorizing(https://dev.twitter.com/docs/auth/authorizing-request) and signing(https://dev.twitter.com/docs/auth/creating-signature) requests. + +The policies below implement signing for simple status updates. It's not currently possible to write a generic signing policy. + +## Dictionary attributes + +Add the following to your custom dictionary +```text +ATTRIBUTE Twitter-API-Method integer +ATTRIBUTE Twitter-API-URL string +ATTRIBUTE Twitter-API-Data string + +VALUE Twitter-API-Method GET 1 +VALUE Twitter-API-Method POST 2 +VALUE Twitter-API-Method PUT 3 +VALUE Twitter-API-Method DELETE 4 +``` + +## The policy +And add this to policy.d/twitter +```text +# +# Basic integration with the twitter API +# +# This gets the difficult part working (oAuth) and allows integration with other +# parts of the API. +# +# Note: This does *NOT* support user based oAuth, the policy cannot be used to +# authenticate users against twitter. It is purely for integration with +# the API. +# +# Note: Unless you're using twitter as part of an authorisation scheme, you should +# use a detail reader/writer pair to provide a buffer in case the twitter +# API becomes unavailable/unreachable. You don't want authentication to be +# delayed whilst waiting for a twitter API request to time out. +# +twitter { + oauth_consumer_key = '' + oauth_consumer_secret = '' + oauth_access_token = '' + oauth_access_token_secret = '' +} + +twitter_sign { + # Stage 1.0 - Generate the nonce (base64 encoding of 32 bytes of random data) and record the timestamp + update request { + Tmp-Octets-0 := "0x%{randstr:hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh}" + Tmp-String-0 := "%{base64:&Tmp-Octets-0}" + Tmp-Integer-0 := "%l" + } + + # Stage 1.1 - Build the parameter string + # Note: The parameters here may have to be re-ordered alphabetically + # Twitter-API-Data should represent a single = + # pair. We should probably add an xlat to sort attributes + # by value lexicographically. + update request { + Tmp-String-1 := "\ + oauth_consumer_key=%{urlquote:${policy.twitter.oauth_consumer_key}}&\ + oauth_nonce=%{urlquote:%{Tmp-String-0}}&\ + oauth_signature_method=HMAC-SHA1&\ + oauth_timestamp=%{Tmp-Integer-0}&\ + oauth_token=%{urlquote:${policy.twitter.oauth_access_token}}&\ + oauth_version=1.0&\ + status=%{Twitter-API-Data}" + } + + # Stage 1.2 - Create the signature base string + update request { + Tmp-String-2 := "%{Twitter-API-Method}&%{urlquote:%{Twitter-API-URL}}&%{urlquote:%{Tmp-String-1}}" + } + + # Stage 1.3 - Create the signing key + update request { + Tmp-String-3 := "%{urlquote:${policy.twitter.oauth_consumer_secret}}&%{urlquote:${policy.twitter.oauth_access_token_secret}}" + } + + # Stage 1.4 - Create the oAuth signature + update request { + Tmp-Octets-1 := "0x%{hmacsha1:&Tmp-String-2 &Tmp-String-3}" + Tmp-String-4 := "%{base64:&Tmp-Octets-1}" + } + + # Stage 2.0 - Adding the authorization header + update control { + REST-HTTP-Header := "Connection: close" + REST-HTTP-Header += "\ + Authorization: OAuth \ + oauth_consumer_key=\"%{urlquote:${policy.twitter.oauth_consumer_key}}\", \ + oauth_nonce=\"%{urlquote:%{Tmp-String-0}}\", \ + oauth_signature=\"%{urlquote:%{Tmp-String-4}}\", \ + oauth_signature_method=\"HMAC-SHA1\", \ + oauth_timestamp=\"%{Tmp-Integer-0}\", \ + oauth_token=\"%{urlquote:${policy.twitter.oauth_access_token}}\", \ + oauth_version=\"1.0\"" + } +} + +twitter_tweet { + update request { + Twitter-API-Method := POST + Twitter-API-URL := "https://api.twitter.com/1.1/statuses/update.json" + Twitter-API-Data := "%{urlquote:User %{User-Name} connected to %{NAS-Identifier} #WatchingYou #NoPrivacy #FreeRADIUS #Winning}" + } + + # Stage 3.0 - Sending the request + update request { + Tmp-String-5 := "%{rest:%{Twitter-API-Method} %{Twitter-API-URL} status=%{Twitter-API-Data}}" + } +} +```