在 Python 中使用 API 进行组权限管理

正在尝试弄清楚如何发送 PUT 请求来更新 group_permissions 或 permissions,不确定应该用哪一个。

基本上是想让某个分类变为只读,这样用户只能查看和回复已发布的帖子。

查看源代码后,似乎分类控制器只允许使用 permissions 字段,而不是 group_permissions

我尝试了以下几种方式,但即使收到错误,它也只是原样返回了分类信息:

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})  # 尝试过
}

# 也尝试过这个
"permission[]": [{'group_name':'admin','permission_type':1},{'group_name':'everyone','permission_type':2}] 

# 还尝试过这个:
"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+-+%28RBS%29&color=8B1D7B&text_color=FFFFFF&permission=%7B%22group_name%22%3A+%22everyone%22%2C+%22permission_type%22%3A+2%7D
    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}}'

我还尝试更新:

"read_restricted": True # 在请求参数中

但它仍然保持为 false。是否有某种默认的值列表,说明在 API 请求中可以或不可以更新哪些字段?我在文档中没有找到相关信息。

任何帮助都将不胜感激,谢谢

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

1 个赞

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:

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?

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});
2 个赞

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:

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:

3 个赞

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.