Group_permissions using api in python


(David) #1

Trying to figure out how to make a put request ot update the group_permissions/permissions not sure which one.

Essentially trying to make a category read only. So user can only just see and reply to posts already created.

Looking at the source it seems the category controller only allows the permissions value as apposed to the group_permissions.

I have tired the following - I’m even getting an error it’s just spitting out the category as it was.

data = json.dumps([{'group_name':'admin','permission_type':1},{'group_name':'everyone','permission_type':2}])

params_for_update_cat = {
    'api_key': API_KEY,
    'api_username':"MarketDiscuss",
    "name": name_and_ticker,
    "color": bg_colour,
    "text_color": text_color,

    "permission": json.dumps({'group_name':'everyone','permission_type':2})  #tried
}

#tried this too
"permission[]": [{'group_name':'admin','permission_type':1},{'group_name':'everyone','permission_type':2}] 

#also tried this:
"permission": [{'group_name':'admin','permission_type':1},{'group_name':'everyone','permission_type':2}] 

update_cat_url = f'{BASE_URL}/categories/{cat_id}' 

ra = rq.put(url=update_cat_url, params=params_for_update_cat)

print(ra.url)

http://mydomainnnnn.com/categories/49?api_key=scrubbed&api_username=ausername&name=Royal+Bank+of+Scotland+-+(RBS)&color=8B1D7B&text_color=FFFFFF&permission={"group_name"%3A+"everyone"%2C+"permission_type"%3A+2}

print(ra.content)

b’{“success”:“OK”,“category”:{“id”:49,“name”:“Royal Bank of Scotland - (RBS)”,“color”:“8B1D7B”,“text_color”:“FFFFFF”,“slug”:“rbs”,“topic_count”:0,“post_count”:0,“position”:9,“description”:null,“description_text”:null,“topic_url”:"/t/about-the-royal-bank-of-scotland-rbs-category/65",“read_restricted”:false,“permission”:null,“parent_category_id”:9,“notification_level”:null,“can_edit”:true,“topic_template”:null,“has_children”:null,“sort_order”:null,“sort_ascending”:null,“show_subcategory_list”:false,“num_featured_topics”:3,“default_view”:null,“subcategory_list_style”:“rows_with_featured_topics”,“default_top_period”:“all”,“available_groups”:[“admins”,“everyone”,“moderators”,“staff”,“trust_level_0”,“trust_level_1”,“trust_level_2”,“trust_level_3”,“trust_level_4”],“auto_close_hours”:null,“auto_close_based_on_last_post”:false,“group_permissions”:[{“permission_type”:1,“group_name”:“everyone”}],“email_in”:null,“email_in_allow_strangers”:false,“mailinglist_mirror”:false,“suppress_from_latest”:false,“all_topics_wiki”:false,“can_delete”:true,“cannot_delete_reason”:null,“allow_badges”:true,“custom_fields”:{},“allowed_tags”:[],“allowed_tag_groups”:[],“topic_featured_link_allowed”:true,“uploaded_logo”:null,“uploaded_background”:null}}’

I also tried updating:

"read_restricted": True # in the request params

and it just stays false, is there any de-facto list of values I can or can’t update for the api requests? I don’t see anything in the docs.

Any help would be awesome thanks


#2

I couldnt tell you how to do it in python - but as a direct post call in order to update the category I have done the following:

Key:Value
permissions[ADDGROUPNAMEHERE]:1
1/2/3 being the permission level - Create Reply See / Reply See / See

Essentially trying to make a category read only. So user can only just see and reply to posts already created.

You cannot make it read only whilst allowing them to reply to posts too - With that you would have to set Reply See permissions which is Value 2 I believe


(David) #3

Thanks - the values were a touch confusing, this helped.

So this:

permissions[ADDGROUPNAMEHERE]:1 

is essentially a dictionary in python. Similar to an associative array in PHP or a Hash in Ruby. So like:

{ permission: {'admin':1, 'everyone':2} }

Butt I am struggling for the params to take. Whats frustrating is I am getting no errors :confused:


(David) #4

ok so I think I am a step closer…

first off -

 permissions: {admins: 1, staff: 2} 

The problem though is the above is cause this error:

NoMethodError (undefined method `each' for "stafff":String) /var/www/discourse/app/controllers       /categories_controller.rb:223:in `category_params'

Here’s the rub though… source code in discourse does the folowing:

        if p = params[:permissions]
          p.each do |k,v|
          p[k] = v.to_i
       end

The probelm here is p is not being seen as a hash in the controller… I tried converting the permissions value to a json string hoping it would be prased by the api - so I did this:

permissions: json.dumps({"admins": 2, 'stafff': 3})

but no dice - just got this error:

NoMethodError (undefined method `each' for "{\"admins\": 2, \"stafff\": 3}":String)
/var/www/discourse/app/controllers/categories_controller.rb:223:in `category_params'

Can anyone see anything wierd or missing?


(Kane York) #5

The HTTP library you’re using isn’t converting the parameters to a HTTP hash but a JSON string instead.

You’ll need to do this instead:

var params = {...};
var permissions = { admin: 1, everyone: 2 };
for (let group in permissions) {
  if (!HOP.call(permissions, group) continue;
  params[`permissions[${encodeURIComponent(group)}]`] =
    permissions[group];
}

resp = rq.put({url: update_cat_url, params});

(David) #6

The library is actually converting it to json. The problem is Discourse api doesn’t support content-type: application=/json requests it seems - I have searched on this forum and it’s been mentioned a few a times.

I have had to resort to manually building the url and using curl :confused:


(Blake Erickson) #7

You should be able to use python to do this just like the pydiscourse library does. You need to do what @riking said and create a hash in python just like:


(David) #8

I see what you both mean - thanks.

@blake your highlighted line is a little different to my issue because of the following:

The line you highlighted is simply adding in a new key value to the params. Where I am trying to add a new key who’s value is also a bunch of key/value pairs. This value of key-value pairs isn’t being parsed correctly by the requests library or I am doing something wrong(more likely).

There is clearly something I am not understanding here in terms of why the following two things are different.

# building the dict/keyvalue object in python like so as you guys are saying:
hash = {}
hash['new_key']="new value"

and

#Building the same object - like so:

hash = {'new_key": "new value"}

There doesn’t seem to be a diffence and I don’t really see how this changes when I pass the same object into the params argument of the requests field.