· 5 years ago · Dec 09, 2019, 08:54 AM
1local tokenStore = ngx.shared.tokenStore
2
3local cjson = require "cjson"
4local http = require "resty.http"
5local httpc = http.new()
6
7local b64 = require "ngx.base64"
8local aes = require "resty.aes"
9
10local oauthUrl = os.getenv("OAUTH_SERVICE_URL")
11local s3Url = os.getenv("S3_SERVICE_URL")
12local userName = os.getenv("USER_NAME")
13local userSecret = os.getenv("USER_PASSWORD")
14local clientName = os.getenv("CLIENT_NAME")
15local clientSecret = os.getenv("CLIENT_PASSWORD")
16local expiryTime = os.getenv("EXPIRY_TIME")
17local aes_secret = os.getenv("AES_SECRET_KEY")
18local aes_iv = os.getenv("AES_IV")
19local aes_128_cbc_with_iv = assert(aes:new(aes_secret, nil, aes.cipher(128, "cbc"), { iv = aes_iv }))
20
21local query_string = ngx.req.get_uri_args()
22
23local encodedEncryptedKey = query_string["key"]
24local decodedEncryptedKey = b64.decode_base64url(encodedEncryptedKey)
25local key = aes_128_cbc_with_iv:decrypt(decodedEncryptedKey)
26
27--ngx.log(ngx.ERR,"key is " .. key)
28
29local encodedEncryptedMediaContext = query_string["mediaContext"]
30local decodedEncryptedMediaContext = b64.decode_base64url(encodedEncryptedMediaContext)
31local mediaContext = aes_128_cbc_with_iv:decrypt(decodedEncryptedMediaContext)
32
33local combinedParams = key .. "&" .. mediaContext
34
35local encodedEncryptedTimeStamp = query_string["timestamp"]
36
37if encodedEncryptedTimeStamp ~= nil then
38 local decodedEncryptedTimeStamp = b64.decode_base64url(encodedEncryptedTimeStamp)
39 local timeStamp = aes_128_cbc_with_iv:decrypt(decodedEncryptedTimeStamp)
40 --ngx.log(ngx.ERR,"timestamp is " .. timeStamp)
41 combinedParams = combinedParams .. "&" .. timeStamp
42end
43
44local signature = query_string["signature"]
45--ngx.log(ngx.ERR,"signature is " .. signature)
46local calculatedSignature = aes_128_cbc_with_iv:encrypt(combinedParams)
47local encodedCalculatedSignature = b64.encode_base64url(calculatedSignature)
48
49--ngx.log(ngx.ERR,"received signature:" .. signature);
50--ngx.log(ngx.ERR,"expected signature:" .. encodedCalculatedSignature);
51
52if signature ~= encodedCalculatedSignature then
53 return ngx.redirect("/error.html");
54else
55 --ngx.log(ngx.ERR,"signature match");
56end
57
58function isempty(s)
59 return s == nil or s == ''
60end
61
62function starts_with(str, start)
63 return str:sub(1, #start) == start
64end
65
66function getNewToken()
67 --ngx.log(ngx.INFO,"generating new token");
68 local oauthRes, oauthErr = httpc:request_uri(oauthUrl .. "/oauth/token",
69 {
70 method = "POST",
71 body = "username=" .. userName .. "&password=" .. userSecret .. "&grant_type=password&client_id=" .. clientName .. "&client_secret=" .. clientSecret,
72 headers = {
73 ["Content-Type"] = "application/x-www-form-urlencoded",
74 },
75 keepalive_timeout = 60,
76 keepalive_pool = 10
77 })
78
79 if not oauthRes then
80 ngx.log(ngx.ERR, "failed to oauth request: " .. oauthErr);
81 return ngx.redirect("/error.html")
82 end
83
84 --ngx.log(ngx.ERR,oauthRes.body)
85 local oauthJson = oauthRes.body
86 local oauthTable = cjson.decode(oauthJson)
87 local token = oauthTable.access_token
88 tokenStore:set("token", token)
89 return token;
90end
91
92function getUrl(count)
93
94 if (count > 1) then
95 ngx.log(ngx.ERR, "Max attempt exhausted in generating url" .. count);
96 return ngx.redirect("/error.html");
97 end
98
99 count = count + 1;
100
101 local token = tokenStore:get("token")
102
103 if (isempty(token)) then
104 token = getNewToken();
105 end
106 local url = s3Url .. "/v1/object/viewPresignedUrl?key=" .. key .. "&expirationTime=" .. expiryTime .. "&mediaContext=" .. mediaContext
107 ngx.log(ngx.ERR, "s3 url is " .. url);
108 local s3Res, s3Err = httpc:request_uri(url,
109 {
110 method = "GET",
111 headers = {
112 ["Content-Type"] = "application/x-www-form-urlencoded",
113 ["authorization"] = "Bearer " .. token,
114 },
115 keepalive_timeout = 60,
116 keepalive_pool = 10
117 })
118
119 if not s3Res then
120 ngx.log(ngx.ERR, "failed to s3 request: " .. s3Err)
121 return ngx.redirect("/error.html");
122 end
123
124 local s3Json = s3Res.body
125 local s3ResponseTable = cjson.decode(s3Json)
126 local s3Status = s3ResponseTable.status
127
128 if s3Status == "SUCCESS" then
129 --ngx.log(ngx.ERR,s3ResponseTable.presignedUrl)
130 return s3ResponseTable.presignedUrl
131 elseif s3Status == "ERROR" then
132 ngx.log(ngx.ERR, s3ResponseTable.error.message);
133 return ngx.redirect("/error.html")
134 elseif starts_with(s3ResponseTable.error_description, "Access token expired") then
135 --ngx.log(ngx.ERR,"Access token expired");
136 token = getNewToken();
137 return getUrl(count)
138 else
139 ngx.log(ngx.ERR, s3Json);
140 return ngx.redirect("/error.html")
141 end
142
143end
144
145local count = 0;
146local targetUrl = getUrl(count)
147ngx.var.target = targetUrl;