REBOL [ Title: "OAuth Scheme" Date: 27-Sep-2012 Author: "Christopher Ross-Gill" ] do http://reb4.me/r/altwebform unless in system/schemes 'oauth [ system/schemes: make system/schemes [oauth: none] ] system/schemes/oauth: make system/standard/port [ scheme: 'oauth port-id: 0 handler: none key: context [ consumer-key: consumer-secret: "ABCD" ] user: context [ token: secret: "ABCD" ] passive: none cache-size: 5 proxy: make object! [host: port-id: user: pass: type: bypass: #[none]] access: context [ oauth_callback: none oauth_consumer_key: none oauth_token: oauth_nonce: none oauth_signature_method: "HMAC-SHA1" oauth_timestamp: none oauth_version: 1.0 oauth_verifier: oauth_signature: none ] ] system/schemes/oauth/handler: context [ port-flags: system/standard/port-flags/pass-thru init: func [port url /local spec][ unless all [ block? url url? port/url parse/all port/url ["http" opt "s" "://" some skip] ][ make error! "Not a valid OAuth Specification" ] unless find [get post put delete] port/target [ make error! "No HTTP Method Specified" ] port/timeout: enbase/base checksum/secure join now/precise port/key/consumer-key 64 any [date? port/date port/date: now] port/date: form any [ attempt [to integer! difference port/date 1-Jan-1970/0:0:0] port/date - 1-Jan-1970/0:0:0 * 86400.0 ] clear find/last port/date "." port/sub-port: make port! port/url ] sign: func [port [port!]][ port/pass: system/words/copy "" port/access: make port/access [ oauth_consumer_key: port/key/consumer-key oauth_token: port/user/token oauth_nonce: port/timeout oauth_timestamp: port/date ] port/user-data: make port/access any [port/user-data []] port/user-data: sort/skip third port/user-data 2 port/access/oauth_signature: enbase/base checksum/secure/key rejoin [ uppercase form port/target "&" url-encode form port/url "&" url-encode replace/all to-webform port/user-data "+" "%20" ] rejoin [ port/key/consumer-secret "&" any [port/user/secret ""] ] 64 foreach [header value] third port/access [ if value [ repend port/pass [", " form header {="} url-encode form value {"}] ] ] join "OAuth" next port/pass ] open: func [port][ if object? port/user-data [port/user-data: third port/user-data] switch port/target [ put delete [ port/access: compose [port/target: (uppercase form port/target) (any [port/user-data []])] port/access: 'post ] ] switch port/target [ get [ port/target: compose/deep [ header [Authorization: (sign port)] ] if port/user-data [ port/user-data: context sort/skip port/user-data 2 port/sub-port/target: append any [port/sub-port/target ""] to-webform/prefix port/user-data ] ] post put delete [ port/target: compose/deep [ (port/target) (either port/user-data [to-webform port/user-data][""]) [ Authorization: (sign port) Content-Type: "application/x-www-form-urlencoded" ] ] ] ] system/words/open/custom port/sub-port port/target port/state/index: 0 port/state/flags: port/state/flags or port-flags ] copy: func [port [port!]][ port/awake system/words/copy port/sub-port ] close: func [port][ system/words/close port/sub-port ] ]