Extract a regex capturing group with rego - regex

I'm trying to build a rule based file access "engine", that evaluates whether a service is allowed to access a file or not via rego rules/data.
Here's what I have so far
data
{
"bucketname": "randombucket"
"bucketpaths": {
"service1": "/base/path/in/bucket"
}
"rules": {
"service1": {
"GET": ["/storage/service1/(.*)"]
// ^ This is basically a relative path and I'd like to extract it
}
}
}
rego rule
package org.test
import future.keywords.if
import future.keywords.in
default allow := false
default ttl := 60
basePath = data["bucketpaths"][input.ServiceType]
default relativePath := ""
allow if {
allowedPaths := data["rules"][input.ServiceType][input.Method]
some allowedPath in allowedPaths
regex.match(allowedPath, input.Path)
# here I would like to do three things:
# 1) check if the regex matches
# 2) extract the capuring group
# 3) set the value into relativePath
}
fullPath = concat(basePath, relativePath)
bucketName = data["bucketname"]
input
{
"ServiceType": "service1",
"Method": "GET",
"Path": "/storage/service1/a/relative/path"
}
Here's a link to the rego playground: https://play.openpolicyagent.org/p/3p7VAxwTcR
Disclaimer, I'm a noob to opa/rego, so these statements probably don't make any sense to experienced people...
I already tried using regex.find_all_string_submatch_n but I just cannot wrap my head around two things basically
I'm inside of an if statement, which is obviously not meant to set values - but how else would I do it?
How do I "just run a piece of code" to evaluate stuff "somewhere"? To - for example - evaluate the regex and just assign the result

Related

Regex Statement in VSCode snippet for removing file extension

I'd like to create a VS-Code snippet for importing css into a react component. If I'm using the snippet in "MyComponent.tsx", then I'd like the snippet to import the associated css file for the component:
import "./MyComponent.css";
The component and it's css will always be located in the same directory.
I thought that the following snippet would be able to do this:
//typescriptreact.json
"import componet css": {
"prefix": "icss2",
"body": [
"import \"./${1:$TM_FILENAME/^(.+)(\.[^ .]+)?$/}.css\";"
],
"description": ""
},
But this results in:
import "./MyComponent.tsx/^(.+)([^ .]+)?$/.css";
What's the correct way to do this?
You can use
"import componet css": {
"prefix": "icss2",
"body": [
"import \"./${TM_FILENAME_BASE/^(.*)\\..*/$1/}.css\";"
],
"description": ""
}
The ${TM_FILENAME_BASE} variable holds the file name without the path, and the ^(.*)\\..* regex matches and captures all up to the last . while just matching the extension, and only the captured part remains due to the $1 replacement pattern (that refers to Group 1 value).
"import component css": {
"prefix": "icss2",
"body": [
"import \"./${TM_FILENAME_BASE}.css\";"
],
"description": ""
}
TM_FILENAME_BASE The filename of the current document without its
extensions
from snippet variables documentation.
So there is no need to remove the .tsx extension via a transform - it is already done for you.
The more interesting question is what if you have a file like
myComponent.next.tsx // what should the final result be?
${TM_FILENAME_BASE} will only take off the final .tsx resulting in import "./myComponent.next.css";
#Wiktor's results in import "./myComponent.css";
Which is correct in your case? Is something like myComponent.next.tsx a possible case for you? If not just use ${TM_FILENAME_BASE} with no need for a transform.

How to write a regexp in elastisearch so that it gives me URLs with numbers?

I am trying to write a query in Kibana which works with Elastisearch Query DSL. The basic filter is as follows:
{
"query": {
"match": {
"path": {
"query": "/abc/",
"type": "phrase"
}
}
}
}
Now I need to write a query so that it gives me "path" which is of the form /abc/(0-9)/.
I tried the reference provided here but it does not make sense to me (I am not well versed with Elasticsearch):
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html
I would like to filter out results which are of the form path = /abc/12345/
This RegEx might help you to do so:
\x22query\x22:\s\x22(\/.*)\x22
It creates a target capturing group, where your desired output is and you might be able to call it using $1.
You may add additional boundaries to your pattern, if you wish, such as this RegEx:
\x22query\x22:\s\x22([\/a-z0-9]+)\x22

Config variables not being resolved in middleware.json in Loopback 3

I'm unable to get the restApiRoot variable to resolve when using it in middleware.json. I'm using Loopback 3. Here's my setup:
config.json
{
"restApiRoot": "/api"
}
middleware.json
"auth": {
"./middleware/order-auth": {
"paths": [
"${restApiRoot}/Orders"
]
}
},
If I replace ${restApiRoot} with /api then it works. I found this issue which sounds identical, but their resolution was to update loopback and loopback-boot back in 2016, and my versions are well beyond this. My middleware.json matches my version (3) docs.
I believe that loopback-boot performs variable substitution only when } is the last character. See the source code in lib/plugin-base.js (loopback-boot version 3.x):
var DYNAMIC_CONFIG_PARAM = /\$\{(\w+)\}$/;
function getConfigVariable(app, param, useEnvVars) {
var configVariable = param;
var match = configVariable.match(DYNAMIC_CONFIG_PARAM);
// etc.

Commands Not Showing in Command Palette with RegReplace (Sublime Text 3)

I'm trying to run a series of commands with the RegReplace plugin in Sublime Text 3 but I cannot get the command to load and I cannot get the keybindings to work either. I have no clue what's wrong.
Steps Taken:
Installed RegReplace
Opened the Command Palette
Searched for "RegReplace: Create New Regular Expression"
Modified the Rule to the following
"""
If you don't need a setting, just leave it as None.
When the rule is parsed, the default will be used.
Each variable is evaluated separately, so you cannot substitute variables in other variables.
"""
# name (str): Rule name. Required.
name = "extract_variables"
# find (str): Regular expression pattern or literal string.
# Use (?i) for case insensitive. Use (?s) for dotall.
# See https://docs.python.org/3.4/library/re.html for more info on regex flags.
# Required unless "scope" is defined.
find = r".*\[(.*[^(<|>)]*?)\].*"
# replace (str - default=r'\g<0>'): Replace pattern.
replace = r"\1"
# literal (bool - default=False): Preform a non-regex, literal search and replace.
literal = None
# literal_ignorecase (bool - default=False): Ignore case when "literal" is true.
literal_ignorecase = None
# scope (str): Scope to search for and to apply optional regex to.
# Required unless "find" is defined.
scope = None
# scope_filter ([str] - default=[]): An array of scope qualifiers for the match.
# Only used when "scope" is not defined.
#
# - Any instance of scope qualifies match: scope.name
# - Entire match of scope qualifies match: !scope.name
# - Any instance of scope disqualifies match: -scope.name
# - Entire match of scope disqualifies match: -!scope.name
scope_filter = None
# greedy (bool - default=True): Apply action to all instances (find all).
# Used when "find" is defined.
greedy = None
# greedy_scope (bool - default=True): Find all the scopes specified by "scope."
greedy_scope = None
# format_replace (bool - default=False): Use format string style replace templates.
# Works only for Regex (with and without Backrefs) and Re (with Backrefs).
# See http://facelessuser.github.io/backrefs/#format-replacements for more info.
format_replace = None
# selection_inputs (bool -default=False): Use selection for inputs into find pattern.
# Global setting "selection_only" must be disabled for this to work.
selection_inputs = None
# multi_pass (bool - default=False): Perform multiple sweeps on the scope region to find
# and replace all instances of the regex when regex cannot be formatted to find
# all instances. Since a replace can change a scope, this can be useful.
multi_pass = None
# plugin (str): Define replace plugin for more advanced replace logic.
plugin = None
# args (dict): Arguments for 'plugin'.
args = None
# ----------------------------------------------------------------------------------------
# test: Here you can setup a test command. This is not saved and is just used for this session.
# - replacements ([str]): A list of regex rules to sequence together.
# - find_only (bool): Highlight current find results and prompt for action.
# - action (str): Apply the given action (fold|unfold|mark|unmark|select).
# This overrides the default replace action.
# - options (dict): optional parameters for actions (see documentation for more info).
# - key (str): Unique name for highlighted region.
# - scope (str - default="invalid"): Scope name to use as the color.
# - style (str - default="outline"): Highlight style (solid|underline|outline).
# - multi_pass (bool): Repeatedly sweep with sequence to find all instances.
# - no_selection (bool): Overrides the "selection_only" setting and forces no selections.
# - regex_full_file_with_selections (bool): Apply regex search to full file then apply
# action to results under selections.
test = {
"replacements": ["extract_variables"],
"find_only": True,
"action": None,
"options": {},
"multi_pass": False,
"no_selection": False,
"regex_full_file_with_selections": False
}
This code Generates the following in AppData\Roaming\Sublime Text 3\Packages\User\reg_replace_rules.sublime-settings
{
"replacements":
{
"extract_variables":
{
"find": ".*\\[(.*[^(<|>)]*?)\\].*",
"name": "extract_variables",
"replace": "\\1"
}
}
}
And then I created the following command under the same directory with filename Default.sublime-commands
[
{
"caption": "Reg Replace: Extract ERS Variables",
"command": "extract_ers_variables",
"args": {
"replacements": [
"extract_variables"
]
}
}
]
After saving all of this, I still do not see the command in the command palette and it didn't show when I tried to save it as a keymap either.
Any help is much appreciated
Came here with my own troubles and may as well document my dumb mistakes. I know nothing of JSON.
When adding two replacements used together going by the examples at the developer's site, I could not get the command to show up in the Command Palette. I could get a keybinding to work, but it gave error messages that the first replacement could not be found…after having successfully used it. The culprit was a malformed reg_replace_rules.sublime-settings file:
//Wrong
{
"replacements":
{
"rep_one":
//stuff
},
"replacements":
{
"rep_two":
//other stuff
}
}
//Correct
{
"replacements":
{
"rep_one":
//stuff, comma
"rep_two":
//other stuff
}
}
Fixing that cleared up the error message, but the command still would not appear in the Command Palette. The problem there was more bad JSON, this time in Default.sublime-commands.
//Wrong
{
"caption": "My Command",
"command": "reg_replace",
"args": {"replacements": ["rep_one", "rep_two"]}
}
//Correct
[
{
"caption": "My Command",
"command": "reg_replace",
"args": {"replacements": ["rep_one", "rep_two"]}
}
]
This is probably obvious to people who have learned JSON properly and use it regularly, and perhaps one day I will be one of those.
The reason this doesn't work for you is that you have the command wrong in your Default.sublime-commands file. In particular, the command extract_ers_variables does not exist, so the entry for it in the command palette is hidden because selecting it wouldn't do anything. Visually speaking, if this command was in a sublime-menu file, the entry in the menu would appear disabled.
If you select Preferences > Package Settings > RegReplace > Quick Start Guide from the menu and follow through the example that's displayed, note that when it comes to the part about creating the command entry in Default.sublime-commands, it tells you to use reg_replace as the command, and the name of the replacements argument is what tells the command which replacement to do.
As such, your entry should look more like:
[
{
"caption": "Reg Replace: Extract ERS Variables",
"command": "reg_replace",
"args": {
"replacements": [
"extract_variables"
]
}
}
]

MongoDB: Aggregation using $cond with $regex

I am trying to group data in multiple stages.
At the moment my query looks like this:
db.captions.aggregate([
{$project: {
"videoId": "$videoId",
"plainText": "$plainText",
"Group1": {$cond: {if: {$eq: ["plainText", {"$regex": /leave\sa\scomment/i}]},
then: "Yes", else: "No"}}}}
])
I am not sure whether it is actually possible to use the $regex operator within a $cond in the aggregation stage. I would appreciate your help very much!
Thanks in advance
UPDATE: Starting with MongoDB v4.1.11, there finally appears to be a nice solution for your problem which is documented here.
Original answer:
As I wrote in the comments above, $regex does not work inside $cond as of now. There is an open JIRA ticket for that but it's, err, well, open...
In your specific case, I would tend to suggest you solve that topic on the client side unless you're dealing with crazy amounts of input data of which you will always only return small subsets. Judging by your query it would appear like you are always going to retrieve all document just bucketed into two result groups ("Yes" and "No").
If you don't want or cannot solve that topic on the client side, then here is something that uses $facet (MongoDB >= v3.4 required) - it's neither particularly fast nor overly pretty but it might help you to get started.
db.captions.aggregate([{
$facet: { // create two stages that will be processed using the full input data set from the "captions" collection
"CallToActionYes": [{ // the first stage will...
$match: { // only contain documents...
"plainText": /leave\sa\scomment/i // that are allowed by the $regex filter (which could be extended with multiple $or expressions or changed to $in/$nin which accept regular expressions, too)
}
}, {
$addFields: { // for all matching documents...
"CallToAction": "Yes" // we create a new field called "CallsToAction" which will be set to "Yes"
}
}],
"CallToActionNo": [{ // similar as above except we're doing the inverse filter using $not
$match: {
"plainText": { $not: /leave\sa\scomment/i }
}
}, {
$addFields: {
"CallToAction": "No" // and, of course, we set the field to "No"
}
}]
}
}, {
$project: { // we got two arrays of result documents out of the previous stage
"allDocuments" : { $setUnion: [ "$CallToActionYes", "$CallToActionNo" ] } // so let's merge them into a single one called "allDocuments"
}
}, {
$unwind: "$allDocuments" // flatten the "allDocuments" result array
}, {
$replaceRoot: { // restore the original document structure by moving everything inside "allDocuments" up to the top
newRoot: "$allDocuments"
}
}, {
$project: { // include only the two relevant fields in the output (and the _id)
"videoId": 1,
"CallToAction": 1
}
}])
As always with the aggregation framework, it may help to remove individual stages from the end of the pipeline and run the partial query in order to get an understanding of what each individual stage does.