authorizations.go
package auth
import (
"errors"
"fmt"
"log"
"net/url"
"regexp"
"time"
"github.com/nsqio/nsq/internal/http_api"
)
type Authorization struct {
Topic string `json:"topic"`
Channels []string `json:"channels"`
Permissions []string `json:"permissions"`
}
type State struct {
TTL int `json:"ttl"`
Authorizations []Authorization `json:"authorizations"`
Identity string `json:"identity"`
IdentityURL string `json:"identity_url"`
Expires time.Time
}
func (a *Authorization) HasPermission(permission string) bool {
for _, p := range a.Permissions {
if permission == p {
return true
}
}
return false
}
func (a *Authorization) IsAllowed(topic, channel string) bool {
if channel != "" {
if !a.HasPermission("subscribe") {
return false
}
} else {
if !a.HasPermission("publish") {
return false
}
}
topicRegex := regexp.MustCompile(a.Topic)
if !topicRegex.MatchString(topic) {
return false
}
for _, c := range a.Channels {
channelRegex := regexp.MustCompile(c)
if channelRegex.MatchString(channel) {
return true
}
}
return false
}
func (a *State) IsAllowed(topic, channel string) bool {
for _, aa := range a.Authorizations {
if aa.IsAllowed(topic, channel) {
return true
}
}
return false
}
func (a *State) IsExpired() bool {
if a.Expires.Before(time.Now()) {
return true
}
return false
}
func QueryAnyAuthd(authd []string, remoteIP, tlsEnabled, authSecret string,
connectTimeout time.Duration, requestTimeout time.Duration) (*State, error) {
for _, a := range authd {
authState, err := QueryAuthd(a, remoteIP, tlsEnabled, authSecret, connectTimeout, requestTimeout)
if err != nil {
log.Printf("Error: failed auth against %s %s", a, err)
continue
}
return authState, nil
}
return nil, errors.New("Unable to access auth server")
}
func QueryAuthd(authd, remoteIP, tlsEnabled, authSecret string,
connectTimeout time.Duration, requestTimeout time.Duration) (*State, error) {
v := url.Values{}
v.Set("remote_ip", remoteIP)
v.Set("tls", tlsEnabled)
v.Set("secret", authSecret)
endpoint := fmt.Sprintf("http://%s/auth?%s", authd, v.Encode())
var authState State
client := http_api.NewClient(nil, connectTimeout, requestTimeout)
if err := client.GETV1(endpoint, &authState); err != nil {
return nil, err
}
// validation on response
for _, auth := range authState.Authorizations {
for _, p := range auth.Permissions {
switch p {
case "subscribe", "publish":
default:
return nil, fmt.Errorf("unknown permission %s", p)
}
}
if _, err := regexp.Compile(auth.Topic); err != nil {
return nil, fmt.Errorf("unable to compile topic %q %s", auth.Topic, err)
}
for _, channel := range auth.Channels {
if _, err := regexp.Compile(channel); err != nil {
return nil, fmt.Errorf("unable to compile channel %q %s", channel, err)
}
}
}
if authState.TTL <= 0 {
return nil, fmt.Errorf("invalid TTL %d (must be >0)", authState.TTL)
}
authState.Expires = time.Now().Add(time.Duration(authState.TTL) * time.Second)
return &authState, nil
}
authorizations.go的更多相关文章
- WSO2 API Manager 替换mysql作为数据库,解决AuthorizationUtils Could not set authorizations for the root问题
按照wso2官网(https://docs.wso2.com/display/ADMIN44x/Changing+to+MySQL)配置AM的数据库,想从H2换成Mysql5.7,费了将近一天的时间, ...
- (转载) RESTful API 设计指南
作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...
- 使用swagger作为restful api的doc文档生成
初衷 记得以前写接口,写完后会整理一份API接口文档,而文档的格式如果没有具体要求的话,最终展示的文档则完全决定于开发者的心情.也许多点,也许少点.甚至,接口总是需要适应新需求的,修改了,增加了,这份 ...
- .NET WebAPI 用ActionFilterAttribute实现token令牌验证与对Action的权限控制
项目背景是一个社区类的APP(求轻吐...),博主主要负责后台业务及接口.以前没玩过webAPI,但是领导要求必须用这个(具体原因鬼知道),只好硬着头皮上了. 最近刚做完权限这一块,分享出来给大家.欢 ...
- RESTful API 设计指南
转自:http://www.ruanyifeng.com/blog/2014/05/restful_api.html 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机. ...
- RESTful API URI 设计的一些总结
非常赞的四篇文章: Resource Naming Best Practices for Designing a Pragmatic RESTful API 撰写合格的 REST API JSON 风 ...
- PHP7函数大全(4553个函数)
转载来自: http://www.infocool.net/kb/PHP/201607/168683.html a 函数 说明 abs 绝对值 acos 反余弦 acosh 反双曲余弦 addcsla ...
- CentOS搭建SVN记录
1.安装subversion(client and server) $ yum install subversion $ yum install mod_dav_svn 安装成功之后使用 svnser ...
- geotrellis使用(五)使用scala操作Accumulo
要想搞明白Geotrellis的数据处理情况,首先要弄清楚数据的存放,Geotrellis将数据存放在Accumulo中. Accumulo是一个分布式的Key Value型NOSQL数据库,官网为( ...
随机推荐
- shc/unshc加/解密shell脚本
一.加密软件shcshc是linux的一款加密脚本的插件东西比较安全我们可以利用wget将文件放在root目录下也可以通过sftp放在root目录也可以直接利用cd命令选择目录一切随意shc官网:ht ...
- android DialogFragment 实现Dialog展示扫二维码图片展示
近期开发项目,做个按钮点击弹出展示微信二维码关注微信公众号的展示框,于是想到DialogFragment,期间对Dialog的title的底框字体颜色做出相关设置,记录如下: 下面是 DialogFr ...
- 知物由学|游戏开发者如何从容应对Unity手游风险?
本文由 网易云发布. "知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不 ...
- Eclipse配置SpringBoot
从这一博客开始学习SpringBoot,今天学习Eclipse配置SpringBoot.Eclipse导入SpringBoot有两种方式,一种是在线一个是离线方式. 一.在线安装 点击Eclipse中 ...
- git merge 与 git rebase
git merge git rebase merge V.S. rebase 参考材料 写在开始: 对merge和rebase的用法总有疑惑,好像两个都能完成"获取别的branch的comm ...
- Aptana下Django1.6以后的项目模板结构改造
Django1.6以后的manage.py放在项目包目录的根目录下,这种情况下在create app的app也在这个目录下面,由此可能导致app的名称有可能会和广大的内建包或者第三方包发生命名冲突,解 ...
- codechef Chef And Easy Xor Queries
做法:我们考虑前缀异或和,修改操作就变成了区间[i,n]都异或x 查询操作就变成了:区间[1,x]中有几个k 显然的分块,每个块打一个tag标记表示这个块中所有的元素都异或了tag[x] 然后处理出这 ...
- Invoke-ASCmd 部署SSAS database
Install-Module -Name SqlServer -RequiredVersion 21.0.17099 -AllowClobberInvoke-ASCmd -Server 10.162. ...
- removeElement
Description: Given an array and a value, remove all instances of that value in place and return the ...
- developers.google.com上的开发者文档如何切换显示语言
一个小的tip,搜索到developers.google.com上的开发者文档,有些被翻译了的会自动显示中本版,如果想看英文版,可以在当前url后面加?hl=en,就会变成英文版.估计是根据地区直接推 ...