CashPaymentFlow always generates anonymous change output - corda

The CashPaymentFlow has a parameter anonymous to say whether the recipient should be replaced by a confidential identity. In my case, I don't want the confidential identity, so I set it to false.
This works fine for the recipient output (Contains the well known party) but not for the change output to the sender (Contains an anonymous Party).
This happens even if the original sender input is not anonymous
Im on Corda Release 4 on a ubuntu azure VM.
fun sendPayment(amount: Amount<Currency>, recipient: Party): AbstractCashFlow.Result? {
val anonymous = false
val handle = proxy.startTrackedFlow(::CashPaymentFlow, amount, recipient, anonymous)
return handle.returnValue.get()
}
Assume we are sending from A to B and have one unspent output with owner A and value 1000 EUR. Now call sendPayment with amount 800 EUR and recipient B.
I would expect two outputs:
800 EUR, owner B
200 EUR, owner A
Instead I get
800 EUR, owner B
200 EUR, Anonymous(SDFOMWEORHEWLRKHWLEKR...)

Historically, change from cash spends in Corda have been returned using confidential identities. This is the default functionality when generating a spend with either confidential or well-known identities and can't be overridden through CashPaymentFlow.
The Tokens SDK will be replacing Cash (and the rest of the finance module) in due course through which you'll be able to make anonymous change keys optional.

Related

You do not have the following permissions on CodeUnit ... Execute

I have an AL extension deployed on a BC V20 On-Prem system (Version: GB Business Central 20.0 (Platform 20.0.37114.38150 + Application 20.0.37253.38230)). It was working fine until a new licence was installed. It also works on a Cloud Sandbox. A brief outline of the purpose of the extension is to provide a custom page with a subform and a report associated with it.
I believe I have permissions set-up correctly in my codeunit:-
Permissions = TableData TrialBalByDimParams = rimd,
TableData TrialBalanceByDim = rimd,
TableData "G/L Account" = r,
TableData "G/L Entry" = r,
TableData "General Ledger Setup" = r,
TableData "Dimension Value" = r,
TableData "Accounting Period" = r;
There's also a permission set (as below) which I have assigned to the current user for all companies.
permissionset 50000 CustomFuncsYW
{
Assignable = true;
Permissions = tabledata TrialBalanceByDim=RIMD,
tabledata TrialBalByDimParams=RIMD,
table TrialBalanceByDim=X,
table TrialBalByDimParams=X,
report CustomTrialBalanceByDim=X,
codeunit CustomTrialBalancePopulator=X,
page TrialBalanceByDim=X,
page TrialBalByDimParams=X,
query GleDv1=X;
}
In Effective Permissions the 'Execute Permission' column does not contain 'Yes' for my CodeUnit (see below). Is this incorrect?
From a Universal Code perspective, I do not have a Target setting in my app.json file. My understanding is, that means its default value is 'Cloud'.
Is there anything else code-wise I can check for that might cause it to work under one licence and not another?
Does this mean it's licence related? If yes, what can I look for in the licence file that may reveal the issue?
This does indeed look like a license issue.
To troubleshoot it and pinpoint the problem, try running the same action under a user account with SUPER permissions. If the same error still occurs, this will eliminate the option of a permission set misconfiguration.
To check the license, first of all, you can open the .flf or .bclicense (whichever you use) in Notepad and look at the summary section. It should contain the list of purchased objects, like this:
****************************************************************************
Name Amount
----------------------------------------------------------------- ----------
Country Code: Great Britain 1
Dyn365 Business Central Codeunits (100) 100
Dyn365 Business Central Codeunits (each) 23
Dyn365 Business Central Pages (100) 300
Dyn365 Business Central Pages (each) 34
Dyn365 Business Central Premium 50
Dyn365 Business Central Premium - Upgrade 100
Dyn365 Business Central Queries (100) 100
Dyn365 Business Central Reports (100) 100
Dyn365 Business Central Tables (10) 60
Dyn365 Business Central Tables (each) 4
Dyn365 Business Central XML Ports (100) 100
****************************************************************************
I assume the error that you encounter refers to the custom codeunit CustomTrialBalancePopulator. So at least one custom codeunit must be present in this list.
If this part is ok, check the assigned IDs in the license permissions. GB version of BC 20 has a report License Permissions which you can run, or simply open the table License Permission in the browser:
<BC Service URL>?table=2000000043
In this table, check if your codeunit ID has the execution permission assigned. If not - the license should be recreated with correct permission.
Correct list of objects with custom codeunit permissions should be like this:
Regarding the universal code - that's correct, if the target value is not specified in the app.json, the default is "Cloud".
Note that this object ID assignment only applies to BC on prem, cloud deployments don't need this hassle, therefore it works for you in a cloud sandbox.

Is there a syslog private enterprise number for custom/internal use?

So I recently was looking for a way to add extra metadata to logs and found out that syslog got me covered. I can add custom metadata using SD-ID feature like this:
[meta#1234 project="project-name" version="1.0.0-RC5" environment="staging" user="somebody#example.com"]
The problem is that 1234 has to be a syslog private enterprise number.
I assume those are given to big companies like microsoft or apple, but not to indie developers.
So My question is, is there a reserved number for internal use that everyone could use without registration for internal purpose?
If you use RFC5424-formatted messages, you can (or could) create custom fields in the SDATA (Structured Data) part of the message.
The latter part of a custom field in the SDATA is, as you mentioned, the private enterprise number (or enterpiseId).
As per RFC5424 defined:
7.2.2. enterpriseId
The "enterpriseId" parameter MUST be a 'SMI Network Management Private Enterprise Code', maintained by IANA, whose prefix is iso.org.dod.internet.private.enterprise (1.3.6.1.4.1). The number that follows MUST be unique and MUST be registered with IANA as per RFC 2578 [RFC2578].
Of course it depends on what you're using it for, if it's only for local logs, you can use any enterpriseId or you can even use a predefined SDATA field with a reserved SD-ID and rewrite it's value. (See: syslog-ng Guide)

Allow JWT Tokens if Expired, Provided User is from Trusted IP address

Using flask-jwt-extended, I have a situation where the API has to serve both users, and also a series of web-applications (for example, one of the latter is a chatbot).
For the users, the package functionality out of the box is just perfect, however, for the web applications, I would like the JWT tokens to behave more like API-keys, where they don't necessarily expire after a period of time.
So what I would like to do, is to suppress the checks for 'expiry' provided the request has come from a predefined and trusted IP address.
I have a sqlalchemy model that stores trusted 'ip addresses', and this has a foreign key relationship with the users model, meaning that a user can specify one (or more) whitelisted ip addresses.
Now the decode_token function:
https://flask-jwt-extended.readthedocs.io/en/stable/_modules/flask_jwt_extended/utils.html#decode_token
Has an argument allow_expired, which permits the expiry to be overridden, however, this is not utilised in any way within the _decode_jwt_from_request(...) function, which seems to be instrumental when validating JWT tokens.
Ultimately, I am after a decorator replacement to #jwt_required, which permits expired tokens to be used, provided the request is coming from the whitelisted IP address.
My questions are twofold:
Is the above structure ok from a security point of view?, and,
Without having to duplicate (and slightly modify) entire functions from the library, how might I go about the above?
Unless anyone tells me a better way to do it, I ended up monkey patching the decode_token function:
I have highlighted the 'patched' region, which intercepts the 'ExpiredSignatureError', and checks if the ip address is in the user ip-whitelist, and if so, permits business as usual.
def decode_token(encoded_token, csrf_value=None, allow_expired=False):
"""
Returns the decoded token (python dict) from an encoded JWT. This does all
the checks to insure that the decoded token is valid before returning it.
:param encoded_token: The encoded JWT to decode into a python dict.
:param csrf_value: Expected CSRF double submit value (optional)
:param allow_expired: Options to ignore exp claim validation in token
:return: Dictionary containing contents of the JWT
"""
jwt_manager = _get_jwt_manager()
unverified_claims = jwt.decode(
encoded_token, verify=False, algorithms=config.decode_algorithms
)
unverified_headers = jwt.get_unverified_header(encoded_token)
# Attempt to call callback with both claims and headers, but fallback to just claims
# for backwards compatibility
try:
secret = jwt_manager._decode_key_callback(unverified_claims, unverified_headers)
except TypeError:
msg = (
"The single-argument (unverified_claims) form of decode_key_callback ",
"is deprecated. Update your code to use the two-argument form ",
"(unverified_claims, unverified_headers)."
)
warn(msg, DeprecationWarning)
secret = jwt_manager._decode_key_callback(unverified_claims)
try:
return decode_jwt(
encoded_token=encoded_token,
secret=secret,
algorithms=config.decode_algorithms,
identity_claim_key=config.identity_claim_key,
user_claims_key=config.user_claims_key,
csrf_value=csrf_value,
audience=config.audience,
issuer=config.issuer,
leeway=config.leeway,
allow_expired=allow_expired
)
except ExpiredSignatureError:
expired_token = decode_jwt(
encoded_token=encoded_token,
secret=secret,
algorithms=config.decode_algorithms,
identity_claim_key=config.identity_claim_key,
user_claims_key=config.user_claims_key,
csrf_value=csrf_value,
audience=config.audience,
issuer=config.issuer,
leeway=config.leeway,
allow_expired=True
)
# ------------------------------------------------------------
# Author: Nicholas E. Hamilton
# Date: 25th August 2019
# Patch: Check if ip address is in the whitelist,
# and if so, permit an expired token
# ------------------------------------------------------------
user = user_loader(expired_token[config.identity_claim_key])
ip_address = request.remote_addr
if user and ip_address:
ip_whitelist = [x.ip_address for x in user.ip_whitelist]
if ip_address in ip_whitelist:
return expired_token
# >>>> END PATCH
# Proceed as normal
ctx_stack.top.expired_jwt = expired_token
raise
flask_jwt_extended.view_decorators.decode_token = flask_jwt_extended.utils.decode_token = decode_token

Having quite a lot of issues when write massive record to firebase database

From my last question let me decided to write huge amount of data to
firebase databases for testing purpose.
Here is the outcome
1000 record: Nothing significant happen it work fine.
10000 record: Response from all other read operation from firebase return only after the write operation complete.
100000 record : Same as the result of 10000 record but took more longer, I can't perform any firebase operation unless force close the app and reopen it. The screen started hang for some time might because I perform loop in main thread(ios).
1 million record : I'm afraid so never try.
The reason I need to write such amount of data is because I building some social app(android,ios,web) it use SQL before but I think it is time to switch to firebase. By studying this I having the idea on how to build a user feed without using the IN clause. The data structure look like this
users
user1
name: bob
user2
name: alice
follows:
user1: true
posts
post1
author: user1
text: 'Hi there'
feeds
user2
post1: true
As the example If one of the user having 61 million follower it will need to insert record to 61 million feeds/$uid/. Which the write operation barely survive with 100k. On this link it suggest not to do it in the client side but big point of firebase is it is backendless how I suppose to write beside from client side.
So my question is there any efficient way to achieve on how to not get other read operation interupt by this kind of massive write operation? Or there is way better data modeling for this?
I really need help. I really apperciated even just a comment.
Lets start with an example Firebase structure using observers and events to capture feeds from specific users.
We have a users node which stores data about all of the users, in this case just their name. We also have a feeds node which stores the feeds. In this case we could also call it messages as we are just storing messages users create.
users
uid_0
name: "Scott"
uid_1
name: "Frank"
uid_2
name: "Leroy"
feeds
feed_0
uid: uid_1
msg: "some message from uid_1"
feed_1
uid: uid_2
msg: "a message from uid_2"
Assume that Scott (uid_0) wants to 'subscribe' to any feeds from Frank and Leroy.
func addSomeFeeds() {
self.addFeed(uidFeed: "uid_1")
self.addFeed(uidFeed: "uid_2")
}
func addFeed(uidFeed: String) {
let feedsRef = self.ref.child("feeds")
let feedQuery = feedsRef.queryOrdered(byChild: "uid").queryEqual(toValue: uidFeed)
feedQuery.observe(.childAdded, with: { snapshot in
let feedDict = snapshot.value as! [String: Any]
let msg = feedDict["msg"] as! String
print(msg)
})
}
and the output
some message from uid_1
a message from uid_2
and then if uid_2 adds another feed (with a message)
Feed From uid_2
The above code is run on Scott's device and attaches an observer to the Feeds node that 'watches' for any feeds added by Frank or Leroy.
This could expanded and watch for changes via .childChanged so if the feed has multiple 'posts' in it any time a post is updated in a particular feed, Scott's app will be notified of the changes within that feed.
Another option is to add a more generic observer to the feeds node wheras the app would be notified for any feed added, changed or removed. In that case, when the app receives a snapshot of the feed, simply compare it to an array of feeds the user is interested in and if doesn't match one of those, ignore it, otherwise, notify the user.

How to save Remote Party ID to CDR in Asterisk?

I'm new to Asterisk so any help will be greatly appreciated.
I'm trying to save remote party ID (CONNECTEDLINE) in CDR logs table in transferred calls. In blind transfers there's no problem because I'm getting Remote Party ID as Caller ID in src field.
In attended transfers I'm loosing the original caller ID.
This is how transfer goes:
A calls B (A talking with B)
B holds A, and calls C (B talking with C)
B transfers A to C (A talking with C)
Now, in CDRs table I'm getting two records. One for the first call (A<->B), and another for the two second calls (B<->C and A<->C). The point is in second CDR I have lost any reference to A.
I want to save Remote Party ID (A) in second CDR.
I've already added a custom field to CDR table (connectedID).
I'm reading about editing some configuration files, adding this kind of sentences:
"exten => s,1,set(CDR(connectedID)=${CONNECTEDLINE})"
However, I'm quite lost. I don't know which file I need to edit, even in what part of file I should put these lines of code.
Could somebody point me in the right direction?
You can use Func_SHARED,save cid in shared variables and do lookup by bridged channel name
However that all require debugging and your own effort.
http://www.voip-info.org/wiki/view/Asterisk+func+shared
Other option is collect events and remmember all transfers
Reading call events via AMI (thanks to #arheops) I manage how to save Remote Party ID in CDR.
In hangup event we can see Remote Party ID in ConnectedLineNum field.
For a transferred call like this one:
401 calls 208
208 calls 308 (401 on hold)
208 transfers original call to 308 (401 talking with 308)
this is a hangup event sample for the final segment of the call.
Event Hangup
Privilege: call,all
Channel: SIP/308-00000665
Uniqueid: 1421757614.1658
CallerIDNum: 208
CallerIDName: Juan Ruiz
ConnectedLineNum: 401
ConnectedLineName: Test1
Cause: 16
Cause-txt: Normal Clearing
Original caller is stored in ConnectedLineNum variable.
So I add this line to the hangup section:
exten => s,1,Set(CDR(connectedid)=${CONNECTEDLINE(number)})
I'm using Elastix 2.4.0, so I've added this line at the beggining of the [macro-hangupcall] macro in extensions_override_elastix.conf file.
In other Asterisk based distros it should be in another file.

Resources