I'm using GetStream's Laravel integration (github.com/GetStream/stream-laravel) but noticed that 'actor' is just a swappable Model. I'm trying to allow logged in users to post, but I want to allow "anonymous" (unauthenticated) users to like the post using UserAgent/fingerprint/ip/session etc.
Has anybody done something similar or know of a method to hot swap the actors or allow the actor_id in specific situations to use another model?
You should be able to use the ActivityTrait (https://github.com/GetStream/stream-laravel/blob/master/src/GetStream/StreamLaravel/Eloquent/ActivityTrait.php) without using the activityActor method, which is called here: https://github.com/GetStream/stream-laravel/blob/master/src/GetStream/StreamLaravel/Eloquent/ActivityTrait.php#L130.
For example:
class Model
{
use ActivityTrait {activityActor as traitActivityActor;}
public function activityActor()
{
if (/* check if authenticated user */) {
return $this->traitActivityActor(); // Reusing the same method.
}
return /* some other logic to return identifier for anonymous user */;
}
}
There are other places to hook into and adjust the functionality by this package. But I think in your case this might be the easiest for this model.
I hope this help you in the right direction.
Related
I am trying to implement a pub/sub broker with ZeroMQ where it is possible to restrict clients from subscribing to prefixes they are not allowed to subscribe to. I found a tutorial that tries to achieve a similar thing using the ZMQ_XPUB_MANUAL option. With zeromq.js it is possible to set this option:
import * as zmq from "zeromq";
// ...
const socket = new zmq.XPublisher({ manual: true });
After setting this option I am able to receive the subscription messages by calling .receive() on this socket:
const [msg] = await socket.receive();
But I have no Idea how to accept this subscription. Usally this is done by calling setSockOpt with ZMQ_SUBSCRIBE but I don't know how to do this with zeromq.js.
Is there a way to call setSockOpt with zeromq.js or is there another way to accept a subscription?
Edit
I tried user3666197's suggestion to call setSockOpt directly, but I am not sure how to do this. Rather than doing that, I took another look in the sources and found this: https://github.com/zeromq/zeromq.js/blob/master/src/native.ts#L617
It seems like setSockOpt is exposed to the TypeScript side as protected methods of the Socket class. To try this out, I created my own class that inherits XPublisher and exposed an acceptSubscription message:
class CustomPublisher extends zmq.XPublisher {
constructor(options?: zmq.SocketOptions<zmq.XPublisher>) {
super(options);
}
public acceptSubscription(subscription: string | null): void {
// ZMQ_SUBSCRIBE has a value of 6
// reference:
// https://github.com/zeromq/libzmq/blob/master/include/zmq.h#L310
this.setStringOption(6, subscription);
}
}
This works like a charm! But do not forget to strip the first byte of the subscription messages, otherwise your client won't receive any messages since the prefix won't match.
Q : "Is there a way to call setSockOpt() with zeromq.js or is there another way to accept a subscription?"
So, let me first mention Somdoron to be, out of doubts & for ages, a master of the ZeroMQ tooling.
Next comes the issue. The GitHub-sources, I was able to review atm, seem to me, that permit the ZMQ_XPUB-Socket-archetypes to process the native API ZMQ_XPUB_MANUAL settings ( re-dressed into manual-property, an idiomatic shift ), yet present no method (so far visible for me) to actually permit user to meet the native API explicit protocol of:
ZMQ_XPUB_MANUAL: change the subscription handling to manual...with manual mode subscription requests are not added to the subscription list. To add subscription the user need to call setsockopt() with ZMQ_SUBSCRIBE on XPUB socket./__ from ZeroMQ native API v.4.3.2 documentation __/
Trying to blind-call the Socket-inherited .SetSockOpt() method may prove me wrong, yet if successful, it may be a way to inject the { ZMQ_SUBSCRIBE | ZMQ_UNSUBSCRIBE } subscription-management steps into the XPUB-instance currently having been switched into the ZMQ_XPUB_MANUAL-mode.
Please test it, and if it fails to work via this super-class inherited method, the shortest remedy would be to claim that collision/conceptual-shortcomings directly to the zeromq.js maintainers ( it might be a W.I.P. item, deeper in their actual v6+ refactoring backlog, so my fingers are crossed for either case ).
I am using NestJS (version 6.5, with Express platform) and I need to handle a request with a property that can either be a File or a String.
Here is the code I currently have, but I don't find a clean way to implement this.
MyAwesomeController
#Post()
#UseInterceptors(FileInterceptor('source'))
async handle(#UploadedFile() source, #Body() myDto: MyDto): Promise<any> {
//do things...
}
Am I missing something obvious or am I supposed to write my own interceptor to handle this case?
Design-wise, is this bad?
Based on the fact you're designing a REST API:
It depends what use case(s) you want to achieve: is your - client-side - flow designed to be performed in 2 steps o not ?
Can string and file params be both passed at the same time or is there only one of the two on each call ? (like if you want to update a file and its name, or some other non Multer related attributes).
When you pass a string as parameter to your endpoint call, is a file resource created / updated / deleted ? Or maybe not at all ?
Depending on the answer and the flow that you thought of, you should split both cases handling within two independent endpoints, or maybe it makes sense to handle both parameters at the same time.
If only one of the params can be passed at a time, I'd say go for two independent endpoints; you'll benefit from both maintenance and code readability.
If both params can be passed at the same time and they're related to the same resource, then it could make sense to handle both of them at once.
Hope this helps, don't hesitate to comment ;)
thanks for stopping by.
I have a class, let's call Class1, that I use to give users of my app discounts / coupons. When a user finishes the registration process, I create an object and store the pointer to it on the user.
I want to give this class CLP permissions so that the public can create, but not write to this object. Let it only be something that I use internally.
My problem is that the class has several arrays that can't be undefined, or other cloud functions will end up throwing errors trying to read those values. I set up a beforeSave() trigger for the class, and use the master key, but the object isn't being saved so my entire user save at the end of registration isn't working. How do I fix this while keeping my object secure and making sure users can't steal all of my app's services for free?
Here is my beforeSave trigger:
Parse.Cloud.beforeSave("Class1", function(request, response)
{
Parse.Cloud.useMasterKey();
var emptyArray = [];
class1 = request.object;
if( class1.isNew() )
{
class1.set("array1", emptyArray);
class1.set("array2", emptyArray);
class1.set("array3", emptyArray);
}
response.success();
});
So I guess you can't use the master key to override CLP / ACL stuff in a beforeSave trigger... though it makes sense, as that would entirely defeat the point.
However, if you give public create access, you can populate any initial data, you just can't update it without update access. So, the obvious answer was to just set these parameters on the client side when I created the object and before I saved it.
I've been evaluating Strongloop (& Loopback) over the past couple of days. I've written a couple of helper endpoints for me to get information about my models in order to generate a CMS frontend for the REST API.
I've create a boot script that returns the public models that are in use, and a bit about them, as well as a couple of custom fields to do with the display of models etc. Here it is:
module.exports = function mountModelDiscoveryService(server) {
server.get('/api/RemoteModules', function(req, res) {
var models = server.models();
var modelObject = [];
models.forEach(function(Model) {
if(Model.shared) {
modelObject.push({
name: Model.modelName,
plural: (Model.settings.plural || Model.modelName),
attributes: Model.definition.rawProperties,
uri: (Model.settings.plural || Model.modelName).toLowerCase(),
displaySettings: (Model.settings.display || {list: ["id", "title"]})
})
}
});
return res.send(modelObject);
})
}
This is working well and I've been pleased with the progress. However, I'd like to be able to get a list of models (+ endpoints) that I have access to as the currently logged in user.
I've implemented the ACL stuff as the tutorial describes, and this correctly allows me or denies me access based on my current permission level, but this is only at the point of making the call - I was essentially wondering if anyone had tried to use the permissions system on the frontend - I'd like to hide certain elements if a user doesn't have access to create new objects, for example.
Do you think I should add some sort of property to this object that just returns a cut-down version of the ACL object with a complete list of what everyone can do? Is there an internal Loopback method I can use to achieve this result?
Thanks a lot for your time.
In Yii, is there a best way to make sure a user can only see and access their own data in Yii?
I thought an Admin should be able to see anything, but for now, I'll cross that bridge later.
Thanks
Look into scopes. Default scopes will be your friend:
http://www.yiiframework.com/doc/guide/1.1/en/database.ar#named-scopes
Because the defaultScopes array is inside of a function, you can also do conditional default scopes:
public function defaultScope()
{
$t=$this->getTableAlias(false,false);
if(Yii::app()->user->notAdmin()) {
return array(
'condition'=>"$t.<column_name> = :<columnName>",
'params'=>array(':<columnName>'=>Yii::app()->user->notAdmin),
);
}
else return array();
}
Edit: Note that this can get you in trouble down the road if you aren't careful. See this issue on the Yii site for more info.
There is no way Yii will do this for you, you'll do it on your own, but it's fairly straight forward.
You can consider scopes, or look into Relations and base them all on current user. For example, to get all posts by a user, you can do:
$posts = Post::model()->findAll(); //WRONG
$posts = Yii::app()->user->posts(); //RIGHT (Should define the relation in the User model)
Check out a solution which I wrote:
http://www.yiiframework.com/forum/index.php/topic/42735-restrict-users-to-only-editingdeleting-their-own-entries/page_gopid_237608#entry237608