| rev | 
   line source | 
| 
bsw/jbe@1309
 | 
     1 Token = mondelefant.new_class()
 | 
| 
bsw/jbe@1309
 | 
     2 Token.table = 'token'
 | 
| 
bsw/jbe@1309
 | 
     3 
 | 
| 
bsw/jbe@1309
 | 
     4 Token:add_reference{
 | 
| 
bsw/jbe@1309
 | 
     5   mode          = '1m',
 | 
| 
bsw/jbe@1309
 | 
     6   to            = "TokenScope",
 | 
| 
bsw/jbe@1309
 | 
     7   this_key      = 'id',
 | 
| 
bsw/jbe@1309
 | 
     8   that_key      = 'token_id',
 | 
| 
bsw/jbe@1309
 | 
     9   ref           = 'token_scopes',
 | 
| 
bsw/jbe@1309
 | 
    10   back_ref      = 'token',
 | 
| 
bsw/jbe@1309
 | 
    11   default_order = 'token_scope.index'
 | 
| 
bsw/jbe@1309
 | 
    12 }
 | 
| 
bsw/jbe@1309
 | 
    13 
 | 
| 
bsw/jbe@1309
 | 
    14 Token:add_reference{
 | 
| 
bsw/jbe@1309
 | 
    15   mode          = 'm1',
 | 
| 
bsw/jbe@1309
 | 
    16   to            = "Member",
 | 
| 
bsw/jbe@1309
 | 
    17   this_key      = 'member_id',
 | 
| 
bsw/jbe@1309
 | 
    18   that_key      = 'id',
 | 
| 
bsw/jbe@1309
 | 
    19   ref           = 'member',
 | 
| 
bsw/jbe@1309
 | 
    20 }
 | 
| 
bsw/jbe@1309
 | 
    21 
 | 
| 
bsw/jbe@1309
 | 
    22 Token:add_reference{
 | 
| 
bsw/jbe@1309
 | 
    23   mode          = 'm1',
 | 
| 
bsw/jbe@1309
 | 
    24   to            = "Session",
 | 
| 
bsw/jbe@1309
 | 
    25   this_key      = 'session_id',
 | 
| 
bsw/jbe@1309
 | 
    26   that_key      = 'id',
 | 
| 
bsw/jbe@1309
 | 
    27   ref           = 'session',
 | 
| 
bsw/jbe@1309
 | 
    28 }
 | 
| 
bsw/jbe@1309
 | 
    29 
 | 
| 
bsw/jbe@1309
 | 
    30 Token:add_reference{
 | 
| 
bsw/jbe@1309
 | 
    31   mode          = 'm1',
 | 
| 
bsw/jbe@1309
 | 
    32   to            = "SystemApplication",
 | 
| 
bsw/jbe@1309
 | 
    33   this_key      = 'system_application_id',
 | 
| 
bsw/jbe@1309
 | 
    34   that_key      = 'id',
 | 
| 
bsw/jbe@1309
 | 
    35   ref           = 'system_application',
 | 
| 
bsw/jbe@1309
 | 
    36 }
 | 
| 
bsw/jbe@1309
 | 
    37 
 | 
| 
bsw/jbe@1309
 | 
    38 function Token:new()
 | 
| 
bsw/jbe@1309
 | 
    39   local token = self.prototype.new(self)
 | 
| 
bsw/jbe@1309
 | 
    40   token.token = multirand.string(16, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
 | 
| 
bsw/jbe@1309
 | 
    41   return token
 | 
| 
bsw/jbe@1309
 | 
    42 end
 | 
| 
bsw/jbe@1309
 | 
    43 
 | 
| 
bsw/jbe@1309
 | 
    44 function Token:create_authorization(member_id, system_application_id, domain, session_id, redirect_uri, redirect_uri_explicit, scopes, state)
 | 
| 
bsw/jbe@1309
 | 
    45 
 | 
| 
bsw/jbe@1309
 | 
    46   local detached = false
 | 
| 
bsw/jbe@1309
 | 
    47   for i = 0, #scopes do
 | 
| 
bsw/jbe@1309
 | 
    48     if scopes[i] then
 | 
| 
bsw/jbe@1309
 | 
    49       for s in string.gmatch(scopes[i], "[^ ]+") do
 | 
| 
bsw/jbe@1309
 | 
    50         if s == "detached" then
 | 
| 
bsw/jbe@1309
 | 
    51           detached = true
 | 
| 
bsw/jbe@1309
 | 
    52         end
 | 
| 
bsw/jbe@1309
 | 
    53       end
 | 
| 
bsw/jbe@1309
 | 
    54     end
 | 
| 
bsw/jbe@1309
 | 
    55   end
 | 
| 
bsw/jbe@1309
 | 
    56   
 | 
| 
bsw/jbe@1309
 | 
    57   local requested_scopes = {}
 | 
| 
bsw/jbe@1309
 | 
    58 
 | 
| 
bsw/jbe@1309
 | 
    59   for i = 0, #scopes do
 | 
| 
bsw/jbe@1309
 | 
    60     if scopes[i] then
 | 
| 
bsw/jbe@1309
 | 
    61       for scope in string.gmatch(scopes[i], "[^ ]+") do
 | 
| 
bsw/jbe@1309
 | 
    62         requested_scopes[scope] = true
 | 
| 
bsw/jbe@1309
 | 
    63       end
 | 
| 
bsw/jbe@1309
 | 
    64     end
 | 
| 
bsw/jbe@1309
 | 
    65   end
 | 
| 
bsw/jbe@1309
 | 
    66 
 | 
| 
bsw/jbe@1309
 | 
    67   local requested_scopes_list = {}
 | 
| 
bsw/jbe@1309
 | 
    68 
 | 
| 
bsw/jbe@1309
 | 
    69   for k, v in pairs(requested_scopes) do
 | 
| 
bsw/jbe@1309
 | 
    70     requested_scopes_list[#requested_scopes_list+1] = k
 | 
| 
bsw/jbe@1309
 | 
    71   end
 | 
| 
bsw/jbe@1309
 | 
    72 
 | 
| 
bsw/jbe@1309
 | 
    73   local requested_scopes_string = table.concat(requested_scopes_list, " ")
 | 
| 
bsw/jbe@1309
 | 
    74 
 | 
| 
bsw/jbe@1309
 | 
    75   local expiry = db:query({"SELECT now() + (? || 'sec')::interval AS expiry", config.oauth2.authorization_code_lifetime }, "object").expiry
 | 
| 
bsw/jbe@1309
 | 
    76 
 | 
| 
bsw/jbe@1309
 | 
    77   local token = Token:new()
 | 
| 
bsw/jbe@1309
 | 
    78   token.token_type = "authorization"
 | 
| 
bsw/jbe@1309
 | 
    79   token.member_id = member_id
 | 
| 
bsw/jbe@1309
 | 
    80   token.system_application_id = system_application_id
 | 
| 
bsw/jbe@1309
 | 
    81   token.domain = domain
 | 
| 
bsw/jbe@1309
 | 
    82   if not detached then
 | 
| 
bsw/jbe@1309
 | 
    83     token.session_id = session_id
 | 
| 
bsw/jbe@1309
 | 
    84   end
 | 
| 
bsw/jbe@1309
 | 
    85   token.redirect_uri = redirect_uri
 | 
| 
bsw/jbe@1309
 | 
    86   token.redirect_uri_explicit = redirect_uri_explicit
 | 
| 
bsw/jbe@1309
 | 
    87   token.expiry = expiry
 | 
| 
bsw/jbe@1309
 | 
    88   token.scope = requested_scopes_string
 | 
| 
bsw/jbe@1309
 | 
    89 
 | 
| 
bsw/jbe@1309
 | 
    90   token:save()
 | 
| 
bsw/jbe@1309
 | 
    91   
 | 
| 
bsw/jbe@1309
 | 
    92   for i = 0, #scopes do
 | 
| 
bsw/jbe@1309
 | 
    93     if scopes[i] then
 | 
| 
bsw/jbe@1309
 | 
    94       local token_scope = TokenScope:new()
 | 
| 
bsw/jbe@1309
 | 
    95       token_scope.token_id = token.id
 | 
| 
bsw/jbe@1309
 | 
    96       token_scope.index = i
 | 
| 
bsw/jbe@1309
 | 
    97       token_scope.scope = scopes[i]
 | 
| 
bsw/jbe@1309
 | 
    98       token_scope:save()
 | 
| 
bsw/jbe@1309
 | 
    99     end
 | 
| 
bsw/jbe@1309
 | 
   100   end
 | 
| 
bsw/jbe@1309
 | 
   101   
 | 
| 
bsw/jbe@1309
 | 
   102 
 | 
| 
bsw/jbe@1309
 | 
   103   return token, target_uri
 | 
| 
bsw/jbe@1309
 | 
   104 end
 | 
| 
bsw/jbe@1309
 | 
   105 
 | 
| 
bsw/jbe@1309
 | 
   106 function Token:by_token_type_and_token(token_type, token)
 | 
| 
bsw/jbe@1309
 | 
   107   local selector = Token:new_selector()
 | 
| 
bsw/jbe@1309
 | 
   108   selector:add_where{ "token_type = ?", token_type }
 | 
| 
bsw/jbe@1309
 | 
   109   selector:add_where{ "token = ?", token }
 | 
| 
bsw/jbe@1309
 | 
   110   selector:add_where{ "expiry > now()" }
 | 
| 
bsw/jbe@1309
 | 
   111   selector:optional_object_mode()
 | 
| 
bsw/jbe@1309
 | 
   112   if token_type == "authorization_code" then
 | 
| 
bsw/jbe@1309
 | 
   113     selector:for_update()
 | 
| 
bsw/jbe@1309
 | 
   114   end
 | 
| 
bsw/jbe@1309
 | 
   115   if token_type == "access_token" then
 | 
| 
bsw/jbe@1309
 | 
   116     selector:add_field("FLOOR(EXTRACT(EPOCH FROM expiry - now()))", "expiry_in")
 | 
| 
bsw/jbe@1309
 | 
   117   end
 | 
| 
bsw/jbe@1309
 | 
   118   return selector:exec()
 | 
| 
bsw/jbe@1309
 | 
   119 end
 | 
| 
bsw/jbe@1309
 | 
   120 
 | 
| 
bsw/jbe@1309
 | 
   121 function Token:refresh_token_by_token_selector(token)
 | 
| 
bsw/jbe@1309
 | 
   122   local selector = Token:new_selector()
 | 
| 
bsw/jbe@1309
 | 
   123   selector:add_where{ "token_type = ?", "refresh" }
 | 
| 
bsw/jbe@1309
 | 
   124   selector:add_where{ "member_id = ?", token.member_id }
 | 
| 
bsw/jbe@1309
 | 
   125   if token.system_application_id then
 | 
| 
bsw/jbe@1309
 | 
   126     selector:add_where{ "system_application_id = ?", token.system_application_id }
 | 
| 
bsw/jbe@1309
 | 
   127   else
 | 
| 
bsw/jbe@1309
 | 
   128     selector:add_where{ "domain = ?", token.domain }
 | 
| 
bsw/jbe@1309
 | 
   129   end
 | 
| 
bsw/jbe@1309
 | 
   130   return selector
 | 
| 
bsw/jbe@1309
 | 
   131 end
 | 
| 
bsw/jbe@1309
 | 
   132 
 | 
| 
bsw/jbe@1309
 | 
   133 function Token:fresh_refresh_token_by_token(token)
 | 
| 
bsw/jbe@1309
 | 
   134   local selector = Token:refresh_token_by_token_selector(token)
 | 
| 
bsw/jbe@1309
 | 
   135   selector:add_where{ "created + ('?' || ' sec')::interval > now()", config.oauth2.refresh_pause }
 | 
| 
bsw/jbe@1309
 | 
   136   selector:add_where{ "regexp_split_to_array(scope, E'\\\\s+') <@ regexp_split_to_array(?, E'\\\\s+')", token.scope }
 | 
| 
bsw/jbe@1309
 | 
   137   selector:add_where{ "regexp_split_to_array(scope, E'\\\\s+') @> regexp_split_to_array(?, E'\\\\s+')", token.scope }
 | 
| 
bsw/jbe@1309
 | 
   138   return selector:exec()
 | 
| 
bsw/jbe@1309
 | 
   139 end
 | 
| 
bsw/jbe@1309
 | 
   140 
 | 
| 
bsw/jbe@1309
 | 
   141 function Token:old_refresh_token_by_token(token, scopes)
 | 
| 
bsw/jbe@1309
 | 
   142   local selector = Token:refresh_token_by_token_selector(token)
 | 
| 
bsw/jbe@1309
 | 
   143   selector:add_where{ "id < ?", token.id }
 | 
| 
bsw/jbe@1309
 | 
   144   selector:add_where{ "created + ('?' || ' sec')::interval <= now()", config.oauth2.refresh_grace_period }
 | 
| 
bsw/jbe@1309
 | 
   145   selector:add_where{ "regexp_split_to_array(scope, E'\\\\s+') && regexp_split_to_array(?, E'\\\\s+')", scopes }
 | 
| 
bsw/jbe@1309
 | 
   146   return selector:exec()
 | 
| 
bsw/jbe@1309
 | 
   147 end
 |