Skip to content

Commit

Permalink
lobster-codebeamer uses authentication token (#70)
Browse files Browse the repository at this point in the history
One new argument to pass the token has been added to lobster-codebeamer. The user can also define the token in cb config file.

Update lobster-codebeamer README

Update the documentation about the
configuration file of the `lobster-codebeamer` tool:
- update section about `refs`
- update section about `token`

Resolves #69

---------

Co-authored-by: Philipp Wullstein-Kammler <[email protected]>
  • Loading branch information
TannazVhdBMWExt and phiwuu authored Oct 11, 2024
1 parent b8bf732 commit 95ac5b1
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 27 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

### 0.9.18-dev

* The `lobster-codebeamer` tool now uses an authentication token.
Token can be added either in the config file or as an argument.

* The `lobster-python` tool adds the counter logic to the function
identifier. This improves the situations where different functions have
the same name. Line numbers are no longer used in the identifier.
Expand Down
49 changes: 37 additions & 12 deletions lobster/tools/codebeamer/codebeamer.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
from lobster.errors import Message_Handler, LOBSTER_Error
from lobster.io import lobster_read, lobster_write

TOKEN = 'token'
REFERENCES = 'references'


class References(Enum):
REFS = "refs"
Expand All @@ -71,14 +74,28 @@ def add_refs_refrences(req, flat_values_list):
}


class BearerAuth(requests.auth.AuthBase):
def __init__(self, token):
self.token = token

def __call__(self, r):
r.headers['Authorization'] = f'Bearer {self.token}'
return r


def query_cb_single(cb_config, url):
assert isinstance(cb_config, dict)
assert isinstance(url, str)

try:
if cb_config["token"]:
auth = BearerAuth(cb_config["token"])
else:
auth = (cb_config["user"],
cb_config["pass"])

result = requests.get(url,
auth=(cb_config["user"],
cb_config["pass"]),
auth=auth,
timeout=cb_config["timeout"],
verify=cb_config["verify_ssl"])
except requests.exceptions.ReadTimeout:
Expand Down Expand Up @@ -215,9 +232,9 @@ def to_lobster(cb_config, cb_item):
text = None,
status = status)

if cb_config.get('references'):
if cb_config.get(REFERENCES):
for reference_name, displayed_chosen_names in (
cb_config['references'].items()):
cb_config[REFERENCES].items()):
if reference_name not in map_reference_name_to_function:
continue

Expand Down Expand Up @@ -272,6 +289,11 @@ def parse_cb_config(file_name):
with open(file_name, "r", encoding='utf-8') as file:
data = json.loads(file.read())

json_config = {REFERENCES: {}}

if TOKEN in data:
json_config["token"] = data.pop(TOKEN)

provided_config_keys = set(data.keys())
supported_references = set(SUPPORTED_REFERENCES)

Expand All @@ -280,9 +302,9 @@ def parse_cb_config(file_name):
"supported referenes: '%s'" %
', '.join(SUPPORTED_REFERENCES))

json_config = {}
for key, value in data.items():
json_config[key] = ensure_array_of_strings(value)
json_config[REFERENCES][key] = ensure_array_of_strings(value)

return json_config


Expand Down Expand Up @@ -322,6 +344,7 @@ def main():
ap.add_argument("--cb-root", default=os.environ.get("CB_ROOT", None))
ap.add_argument("--cb-user", default=os.environ.get("CB_USERNAME", None))
ap.add_argument("--cb-pass", default=os.environ.get("CB_PASSWORD", None))
ap.add_argument("--cb-token", default=None)
ap.add_argument("--out", default=None)
options = ap.parse_args()

Expand All @@ -332,14 +355,15 @@ def main():
"base" : "%s/cb/api/v3" % options.cb_root,
"user" : options.cb_user,
"pass" : options.cb_pass,
"token" : options.cb_token,
"verify_ssl" : not options.ignore_ssl_errors,
"page_size" : options.query_size,
"timeout" : options.timeout,
}

if options.config:
if os.path.isfile(options.config):
cb_config["references"] = parse_cb_config(options.config)
cb_config.update(parse_cb_config(options.config))
else:
ap.error("cannot open config file '%s'" % options.config)

Expand All @@ -349,7 +373,8 @@ def main():
if not cb_config["root"].startswith("https://"):
ap.error("codebeamer root %s must start with https://")

if cb_config["user"] is None or cb_config["pass"] is None:
if (cb_config["token"] is None and
(cb_config["user"] is None or cb_config["pass"] is None)):
netrc_file = os.path.join(os.path.expanduser("~"),
".netrc")
if os.path.isfile(netrc_file):
Expand All @@ -359,10 +384,10 @@ def main():
print("using .netrc login for %s" % cb_config["root"])
cb_config["user"], _, cb_config["pass"] = auth

if cb_config["user"] is None:
ap.error("please set CB_USERNAME or use --cb-user")
if cb_config["pass"] is None:
ap.error("please set CB_PASSWORD or use --cb-pass")
if (cb_config["token"] is None and
(cb_config["user"] is None or cb_config["pass"] is None)):
ap.error("please set --cb-token or add your token to the config-file"
"or use --cb-user and --cb-pass")

items_to_import = set()

Expand Down
77 changes: 62 additions & 15 deletions packages/lobster-tool-codebeamer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,46 +14,93 @@ requirements management tool
* `lobster-codebeamer`: Extrat requirements from codebeamer.

## Configuration
This tool works with an optional config file. In it you can declare which
codebeamer fields should be used as 'refs' reference in the codebeamer file.

For the 'refs' reference in config file you can write:

This tool works with an optional config file.
It allows to configure the following features:

### References
Codebeamer items can reference other items through
[Reference Fields](https://support.ptc.com/help/codebeamer/r2.1/en/index.html#page/codebeamer/user_guide/ug_reference_fields.html).
This piece of information can be extracted by the tool, and serialized into the
LOBSTER output file.
It only needs to know which fields to take into account.
Following the LOBSTER JSON schema, the item references will be added to the
`refs` property of the LOBSTER item.
Accordingly, the configuration parameter to specify the codebeamer field names
is called `refs`, too.
It can contain a single field name, or a list of field names.
Field IDs cannot be used, only the field names.

Examples:
```json
{
"refs" : "cb-fieldname"
}
```
or
```json
{
"refs" : "cb-fieldname"
"refs" : ["cb-fieldname"]
}
```
or
```json
{
"refs" : ["cb-fieldname1", "cb-fieldname2"]
}
```

### Bearer Authentication Token
It is also possible to define the Bearer authentication token in the
configuration file:
```json
{
"refs" : ["cb-fieldname"]
"token" : "your-codebeamer-Bearer-token"
}
```
or
Note:
- The Bearer authentication token can also be provided as a command line
argument (use `--cb-token=your-codebeamer-Bearer-token`).
- If the token is provided in the configuration file and as command line
argument, then the configuration file takes precedence.
- If `--cb-user` or `--cb-pass` is given together with a Bearer token (either
as a command line argument or through the configuration file), then the
Bearer authentication method is used, and the username and/or password are
ignored.
- If neither a token nor a username or password are given, then the tool tries
to read the username and password from the `.netrc` file in the user's home
directory.

### Example Configuration
Here is an example configuration file:
```json
{
"refs" : ["derived from", "satisfied by"],
"token" : "SomeTokenStringABC123"
}
```

Is it also possible to define the codebeamer token in this file:
```
{
"refs" : ["cb-fieldname1", "cb-fieldname2"]
"refs" : "cb-fieldname",
"token" : "your cb-token"
}
```

## Usage

There are two ways you can use this tool:

* Download all requirements mentioned by another lobster trace (this
1. Download all requirements mentioned by another lobster trace (this
way you do not get a completeness check) (using `--import-tagged`)

* Download all requirements generated by a saved codebeamer query
2. Download all requirements generated by a saved codebeamer query
(using `--import-query`)

* Configure the 'refs' upstream reference (this argument is optional)
(using `--config`)

## Limitations

The key limitation is item text, which is currently not
imported. However we do plan to also import item text eventually.
imported. However, we do plan to also import item text eventually.

## Copyright & License information

Expand Down

0 comments on commit 95ac5b1

Please sign in to comment.