bsw/jbe@1309: DynamicApplicationScope = mondelefant.new_class() bsw/jbe@1309: DynamicApplicationScope.table = 'dynamic_application_scope' bsw/jbe@1309: DynamicApplicationScope.primary_key = { "redirect_uri", "flow", "scope" } bsw/jbe@1309: bsw/jbe@1309: function DynamicApplicationScope:by_redirect_uri_and_flow(redirect_uri, flow) bsw/jbe@1309: local dynamic_application_scopes = self:new_selector() bsw/jbe@1309: :add_where{ "redirect_uri = ?", redirect_uri } bsw/jbe@1309: :add_where{ "flow = ?", flow } bsw/jbe@1309: :add_where("expiry >= now()") bsw/jbe@1309: :exec() bsw/jbe@1309: return dynamic_application_scopes bsw/jbe@1309: end bsw/jbe@1309: bsw/jbe@1309: function DynamicApplicationScope:check_scopes(domain, redirect_uri, requested_flow, requested_scopes) bsw/jbe@1309: local function check_scopes(permitted_scopes) bsw/jbe@1309: local missing_scope = false bsw/jbe@1309: for scope in pairs(requested_scopes) do bsw/jbe@1309: if not permitted_scopes[scope] then bsw/jbe@1309: missing_scope = true bsw/jbe@1309: end bsw/jbe@1309: end bsw/jbe@1309: return missing_scope bsw/jbe@1309: end bsw/jbe@1309: bsw/jbe@1309: local registered = false bsw/jbe@1309: local missing_scope = false bsw/jbe@1309: bsw/jbe@1309: local dynamic_application_scopes = DynamicApplicationScope:by_redirect_uri_and_flow(redirect_uri, requested_flow) bsw/jbe@1309: bsw/jbe@1309: if #dynamic_application_scopes > 0 then bsw/jbe@1309: registered = true bsw/jbe@1309: local permitted_scopes = {} bsw/jbe@1309: for i, dynamic_application_scope in ipairs(dynamic_application_scopes) do bsw/jbe@1309: permitted_scopes[dynamic_application_scope.scope] = true bsw/jbe@1309: end bsw/jbe@1309: missing_scope = check_scopes(permitted_scopes) bsw/jbe@1309: end bsw/jbe@1309: bsw/jbe@1309: if not registered or missing_scope then bsw/jbe@1309: local output, err, status = config.oauth2.host_func("_liquidfeedback_client." .. domain) bsw/jbe@1309: if output == nil then bsw/jbe@1309: error("Cannot execute host_func command") bsw/jbe@1309: end bsw/jbe@1309: if status == 0 then bsw/jbe@1309: for line in string.gmatch(output, "[^\r\n]+") do bsw/jbe@1309: local flow, result = string.match(line, '"dynamic client v1" "([^"]+)" (.+)$') bsw/jbe@1309: if flow == requested_flow then bsw/jbe@1309: registered = true bsw/jbe@1309: local permitted_scopes = {} bsw/jbe@1309: local wildcard = false bsw/jbe@1309: for entry in string.gmatch(result, '"([^"]+)"') do bsw/jbe@1309: if entry == "*" then bsw/jbe@1309: wildcard = true bsw/jbe@1309: break bsw/jbe@1309: end bsw/jbe@1309: permitted_scopes[entry] = true bsw/jbe@1309: end bsw/jbe@1309: if not wildcard then bsw/jbe@1309: missing_scope = check_scopes(permitted_scopes) bsw/jbe@1309: end bsw/jbe@1309: end bsw/jbe@1309: end bsw/jbe@1309: end bsw/jbe@1309: end bsw/jbe@1309: bsw/jbe@1309: if not registered then bsw/jbe@1309: return "not_registered" bsw/jbe@1309: elseif missing_scope then bsw/jbe@1309: return "missing_scope" bsw/jbe@1309: else bsw/jbe@1309: return "ok" bsw/jbe@1309: end bsw/jbe@1309: end