diff --git a/auth.pb.go b/auth.pb.go index 617dddae0a..2e26dc6ff4 100644 --- a/auth.pb.go +++ b/auth.pb.go @@ -483,1388 +483,31 @@ func (x *AuthorizeRes) GetId() string { return "" } -type AddPolicyReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` - SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` - SubjectRelation string `protobuf:"bytes,3,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` - SubjectKind string `protobuf:"bytes,4,opt,name=subject_kind,json=subjectKind,proto3" json:"subject_kind,omitempty"` - Subject string `protobuf:"bytes,5,opt,name=subject,proto3" json:"subject,omitempty"` - Relation string `protobuf:"bytes,6,opt,name=relation,proto3" json:"relation,omitempty"` - Permission string `protobuf:"bytes,7,opt,name=permission,proto3" json:"permission,omitempty"` - Object string `protobuf:"bytes,8,opt,name=object,proto3" json:"object,omitempty"` - ObjectKind string `protobuf:"bytes,9,opt,name=object_kind,json=objectKind,proto3" json:"object_kind,omitempty"` - ObjectType string `protobuf:"bytes,10,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` -} - -func (x *AddPolicyReq) Reset() { - *x = AddPolicyReq{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddPolicyReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddPolicyReq) ProtoMessage() {} - -func (x *AddPolicyReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddPolicyReq.ProtoReflect.Descriptor instead. -func (*AddPolicyReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{7} -} - -func (x *AddPolicyReq) GetDomain() string { - if x != nil { - return x.Domain - } - return "" -} - -func (x *AddPolicyReq) GetSubjectType() string { - if x != nil { - return x.SubjectType - } - return "" -} - -func (x *AddPolicyReq) GetSubjectRelation() string { - if x != nil { - return x.SubjectRelation - } - return "" -} - -func (x *AddPolicyReq) GetSubjectKind() string { - if x != nil { - return x.SubjectKind - } - return "" -} - -func (x *AddPolicyReq) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *AddPolicyReq) GetRelation() string { - if x != nil { - return x.Relation - } - return "" -} - -func (x *AddPolicyReq) GetPermission() string { - if x != nil { - return x.Permission - } - return "" -} - -func (x *AddPolicyReq) GetObject() string { - if x != nil { - return x.Object - } - return "" -} - -func (x *AddPolicyReq) GetObjectKind() string { - if x != nil { - return x.ObjectKind - } - return "" -} - -func (x *AddPolicyReq) GetObjectType() string { - if x != nil { - return x.ObjectType - } - return "" -} - -type AddPoliciesReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AddPoliciesReq []*AddPolicyReq `protobuf:"bytes,1,rep,name=addPoliciesReq,proto3" json:"addPoliciesReq,omitempty"` -} - -func (x *AddPoliciesReq) Reset() { - *x = AddPoliciesReq{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddPoliciesReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddPoliciesReq) ProtoMessage() {} - -func (x *AddPoliciesReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddPoliciesReq.ProtoReflect.Descriptor instead. -func (*AddPoliciesReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{8} -} - -func (x *AddPoliciesReq) GetAddPoliciesReq() []*AddPolicyReq { - if x != nil { - return x.AddPoliciesReq - } - return nil -} - -type AddPolicyRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Added bool `protobuf:"varint,1,opt,name=added,proto3" json:"added,omitempty"` -} - -func (x *AddPolicyRes) Reset() { - *x = AddPolicyRes{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddPolicyRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddPolicyRes) ProtoMessage() {} - -func (x *AddPolicyRes) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddPolicyRes.ProtoReflect.Descriptor instead. -func (*AddPolicyRes) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{9} -} - -func (x *AddPolicyRes) GetAdded() bool { - if x != nil { - return x.Added - } - return false -} - -type AddPoliciesRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Added bool `protobuf:"varint,1,opt,name=added,proto3" json:"added,omitempty"` -} - -func (x *AddPoliciesRes) Reset() { - *x = AddPoliciesRes{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddPoliciesRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddPoliciesRes) ProtoMessage() {} - -func (x *AddPoliciesRes) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddPoliciesRes.ProtoReflect.Descriptor instead. -func (*AddPoliciesRes) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{10} -} - -func (x *AddPoliciesRes) GetAdded() bool { - if x != nil { - return x.Added - } - return false -} - -type DeletePolicyFilterReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` - SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` - SubjectRelation string `protobuf:"bytes,3,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` - SubjectKind string `protobuf:"bytes,4,opt,name=subject_kind,json=subjectKind,proto3" json:"subject_kind,omitempty"` - Subject string `protobuf:"bytes,5,opt,name=subject,proto3" json:"subject,omitempty"` - Relation string `protobuf:"bytes,6,opt,name=relation,proto3" json:"relation,omitempty"` - Permission string `protobuf:"bytes,7,opt,name=permission,proto3" json:"permission,omitempty"` - Object string `protobuf:"bytes,8,opt,name=object,proto3" json:"object,omitempty"` - ObjectKind string `protobuf:"bytes,9,opt,name=object_kind,json=objectKind,proto3" json:"object_kind,omitempty"` - ObjectType string `protobuf:"bytes,10,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` -} - -func (x *DeletePolicyFilterReq) Reset() { - *x = DeletePolicyFilterReq{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeletePolicyFilterReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeletePolicyFilterReq) ProtoMessage() {} - -func (x *DeletePolicyFilterReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeletePolicyFilterReq.ProtoReflect.Descriptor instead. -func (*DeletePolicyFilterReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{11} -} - -func (x *DeletePolicyFilterReq) GetDomain() string { - if x != nil { - return x.Domain - } - return "" -} - -func (x *DeletePolicyFilterReq) GetSubjectType() string { - if x != nil { - return x.SubjectType - } - return "" -} - -func (x *DeletePolicyFilterReq) GetSubjectRelation() string { - if x != nil { - return x.SubjectRelation - } - return "" -} - -func (x *DeletePolicyFilterReq) GetSubjectKind() string { - if x != nil { - return x.SubjectKind - } - return "" -} - -func (x *DeletePolicyFilterReq) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *DeletePolicyFilterReq) GetRelation() string { - if x != nil { - return x.Relation - } - return "" -} - -func (x *DeletePolicyFilterReq) GetPermission() string { - if x != nil { - return x.Permission - } - return "" -} - -func (x *DeletePolicyFilterReq) GetObject() string { - if x != nil { - return x.Object - } - return "" -} - -func (x *DeletePolicyFilterReq) GetObjectKind() string { - if x != nil { - return x.ObjectKind - } - return "" -} - -func (x *DeletePolicyFilterReq) GetObjectType() string { - if x != nil { - return x.ObjectType - } - return "" -} - -type DeletePoliciesReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DeletePoliciesReq []*DeletePolicyReq `protobuf:"bytes,1,rep,name=deletePoliciesReq,proto3" json:"deletePoliciesReq,omitempty"` -} - -func (x *DeletePoliciesReq) Reset() { - *x = DeletePoliciesReq{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeletePoliciesReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeletePoliciesReq) ProtoMessage() {} - -func (x *DeletePoliciesReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeletePoliciesReq.ProtoReflect.Descriptor instead. -func (*DeletePoliciesReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{12} -} - -func (x *DeletePoliciesReq) GetDeletePoliciesReq() []*DeletePolicyReq { - if x != nil { - return x.DeletePoliciesReq - } - return nil -} - -type DeletePolicyReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` - SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` - SubjectRelation string `protobuf:"bytes,3,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` - SubjectKind string `protobuf:"bytes,4,opt,name=subject_kind,json=subjectKind,proto3" json:"subject_kind,omitempty"` - Subject string `protobuf:"bytes,5,opt,name=subject,proto3" json:"subject,omitempty"` - Relation string `protobuf:"bytes,6,opt,name=relation,proto3" json:"relation,omitempty"` - Permission string `protobuf:"bytes,7,opt,name=permission,proto3" json:"permission,omitempty"` - Object string `protobuf:"bytes,8,opt,name=object,proto3" json:"object,omitempty"` - ObjectKind string `protobuf:"bytes,9,opt,name=object_kind,json=objectKind,proto3" json:"object_kind,omitempty"` - ObjectType string `protobuf:"bytes,10,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` -} - -func (x *DeletePolicyReq) Reset() { - *x = DeletePolicyReq{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeletePolicyReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeletePolicyReq) ProtoMessage() {} - -func (x *DeletePolicyReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeletePolicyReq.ProtoReflect.Descriptor instead. -func (*DeletePolicyReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{13} -} - -func (x *DeletePolicyReq) GetDomain() string { - if x != nil { - return x.Domain - } - return "" -} - -func (x *DeletePolicyReq) GetSubjectType() string { - if x != nil { - return x.SubjectType - } - return "" -} - -func (x *DeletePolicyReq) GetSubjectRelation() string { - if x != nil { - return x.SubjectRelation - } - return "" -} - -func (x *DeletePolicyReq) GetSubjectKind() string { - if x != nil { - return x.SubjectKind - } - return "" -} - -func (x *DeletePolicyReq) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *DeletePolicyReq) GetRelation() string { - if x != nil { - return x.Relation - } - return "" -} - -func (x *DeletePolicyReq) GetPermission() string { - if x != nil { - return x.Permission - } - return "" -} - -func (x *DeletePolicyReq) GetObject() string { - if x != nil { - return x.Object - } - return "" -} - -func (x *DeletePolicyReq) GetObjectKind() string { - if x != nil { - return x.ObjectKind - } - return "" -} - -func (x *DeletePolicyReq) GetObjectType() string { - if x != nil { - return x.ObjectType - } - return "" -} - -type DeletePolicyRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Deleted bool `protobuf:"varint,1,opt,name=deleted,proto3" json:"deleted,omitempty"` -} - -func (x *DeletePolicyRes) Reset() { - *x = DeletePolicyRes{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeletePolicyRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeletePolicyRes) ProtoMessage() {} - -func (x *DeletePolicyRes) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeletePolicyRes.ProtoReflect.Descriptor instead. -func (*DeletePolicyRes) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{14} -} - -func (x *DeletePolicyRes) GetDeleted() bool { - if x != nil { - return x.Deleted - } - return false -} - -type ListObjectsReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` - SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` - SubjectRelation string `protobuf:"bytes,3,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` - Subject string `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"` - Relation string `protobuf:"bytes,5,opt,name=relation,proto3" json:"relation,omitempty"` - Permission string `protobuf:"bytes,6,opt,name=permission,proto3" json:"permission,omitempty"` - Object string `protobuf:"bytes,7,opt,name=object,proto3" json:"object,omitempty"` - ObjectType string `protobuf:"bytes,8,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` - NextPageToken string `protobuf:"bytes,9,opt,name=nextPageToken,proto3" json:"nextPageToken,omitempty"` - Limit uint64 `protobuf:"varint,10,opt,name=limit,proto3" json:"limit,omitempty"` -} - -func (x *ListObjectsReq) Reset() { - *x = ListObjectsReq{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListObjectsReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListObjectsReq) ProtoMessage() {} - -func (x *ListObjectsReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListObjectsReq.ProtoReflect.Descriptor instead. -func (*ListObjectsReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{15} -} - -func (x *ListObjectsReq) GetDomain() string { - if x != nil { - return x.Domain - } - return "" -} - -func (x *ListObjectsReq) GetSubjectType() string { - if x != nil { - return x.SubjectType - } - return "" -} - -func (x *ListObjectsReq) GetSubjectRelation() string { - if x != nil { - return x.SubjectRelation - } - return "" -} - -func (x *ListObjectsReq) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *ListObjectsReq) GetRelation() string { - if x != nil { - return x.Relation - } - return "" -} - -func (x *ListObjectsReq) GetPermission() string { - if x != nil { - return x.Permission - } - return "" -} - -func (x *ListObjectsReq) GetObject() string { - if x != nil { - return x.Object - } - return "" -} - -func (x *ListObjectsReq) GetObjectType() string { - if x != nil { - return x.ObjectType - } - return "" -} - -func (x *ListObjectsReq) GetNextPageToken() string { - if x != nil { - return x.NextPageToken - } - return "" -} - -func (x *ListObjectsReq) GetLimit() uint64 { - if x != nil { - return x.Limit - } - return 0 -} - -type ListObjectsRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Policies []string `protobuf:"bytes,1,rep,name=policies,proto3" json:"policies,omitempty"` - NextPageToken string `protobuf:"bytes,2,opt,name=nextPageToken,proto3" json:"nextPageToken,omitempty"` -} - -func (x *ListObjectsRes) Reset() { - *x = ListObjectsRes{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListObjectsRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListObjectsRes) ProtoMessage() {} - -func (x *ListObjectsRes) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListObjectsRes.ProtoReflect.Descriptor instead. -func (*ListObjectsRes) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{16} -} - -func (x *ListObjectsRes) GetPolicies() []string { - if x != nil { - return x.Policies - } - return nil -} - -func (x *ListObjectsRes) GetNextPageToken() string { - if x != nil { - return x.NextPageToken - } - return "" -} - -type CountObjectsReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` - SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` - SubjectRelation string `protobuf:"bytes,3,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` - Subject string `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"` - Relation string `protobuf:"bytes,5,opt,name=relation,proto3" json:"relation,omitempty"` - Permission string `protobuf:"bytes,6,opt,name=permission,proto3" json:"permission,omitempty"` - Object string `protobuf:"bytes,7,opt,name=object,proto3" json:"object,omitempty"` - ObjectType string `protobuf:"bytes,8,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` - NextPageToken string `protobuf:"bytes,9,opt,name=nextPageToken,proto3" json:"nextPageToken,omitempty"` -} - -func (x *CountObjectsReq) Reset() { - *x = CountObjectsReq{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CountObjectsReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CountObjectsReq) ProtoMessage() {} - -func (x *CountObjectsReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CountObjectsReq.ProtoReflect.Descriptor instead. -func (*CountObjectsReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{17} -} - -func (x *CountObjectsReq) GetDomain() string { - if x != nil { - return x.Domain - } - return "" -} - -func (x *CountObjectsReq) GetSubjectType() string { - if x != nil { - return x.SubjectType - } - return "" -} - -func (x *CountObjectsReq) GetSubjectRelation() string { - if x != nil { - return x.SubjectRelation - } - return "" -} - -func (x *CountObjectsReq) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *CountObjectsReq) GetRelation() string { - if x != nil { - return x.Relation - } - return "" -} - -func (x *CountObjectsReq) GetPermission() string { - if x != nil { - return x.Permission - } - return "" -} - -func (x *CountObjectsReq) GetObject() string { - if x != nil { - return x.Object - } - return "" -} - -func (x *CountObjectsReq) GetObjectType() string { - if x != nil { - return x.ObjectType - } - return "" -} - -func (x *CountObjectsReq) GetNextPageToken() string { - if x != nil { - return x.NextPageToken - } - return "" -} - -type CountObjectsRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Count uint64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` -} - -func (x *CountObjectsRes) Reset() { - *x = CountObjectsRes{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CountObjectsRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CountObjectsRes) ProtoMessage() {} - -func (x *CountObjectsRes) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CountObjectsRes.ProtoReflect.Descriptor instead. -func (*CountObjectsRes) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{18} -} - -func (x *CountObjectsRes) GetCount() uint64 { - if x != nil { - return x.Count - } - return 0 -} - -type ListSubjectsReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` - SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` - SubjectRelation string `protobuf:"bytes,3,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` - Subject string `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"` - Relation string `protobuf:"bytes,5,opt,name=relation,proto3" json:"relation,omitempty"` - Permission string `protobuf:"bytes,6,opt,name=permission,proto3" json:"permission,omitempty"` - Object string `protobuf:"bytes,7,opt,name=object,proto3" json:"object,omitempty"` - ObjectType string `protobuf:"bytes,8,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` - NextPageToken string `protobuf:"bytes,9,opt,name=nextPageToken,proto3" json:"nextPageToken,omitempty"` - Limit uint64 `protobuf:"varint,10,opt,name=limit,proto3" json:"limit,omitempty"` -} - -func (x *ListSubjectsReq) Reset() { - *x = ListSubjectsReq{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListSubjectsReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListSubjectsReq) ProtoMessage() {} - -func (x *ListSubjectsReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListSubjectsReq.ProtoReflect.Descriptor instead. -func (*ListSubjectsReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{19} -} - -func (x *ListSubjectsReq) GetDomain() string { - if x != nil { - return x.Domain - } - return "" -} - -func (x *ListSubjectsReq) GetSubjectType() string { - if x != nil { - return x.SubjectType - } - return "" -} - -func (x *ListSubjectsReq) GetSubjectRelation() string { - if x != nil { - return x.SubjectRelation - } - return "" -} - -func (x *ListSubjectsReq) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *ListSubjectsReq) GetRelation() string { - if x != nil { - return x.Relation - } - return "" -} - -func (x *ListSubjectsReq) GetPermission() string { - if x != nil { - return x.Permission - } - return "" -} - -func (x *ListSubjectsReq) GetObject() string { - if x != nil { - return x.Object - } - return "" -} - -func (x *ListSubjectsReq) GetObjectType() string { - if x != nil { - return x.ObjectType - } - return "" -} - -func (x *ListSubjectsReq) GetNextPageToken() string { - if x != nil { - return x.NextPageToken - } - return "" -} - -func (x *ListSubjectsReq) GetLimit() uint64 { - if x != nil { - return x.Limit - } - return 0 -} - -type ListSubjectsRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Policies []string `protobuf:"bytes,1,rep,name=policies,proto3" json:"policies,omitempty"` - NextPageToken string `protobuf:"bytes,2,opt,name=nextPageToken,proto3" json:"nextPageToken,omitempty"` -} - -func (x *ListSubjectsRes) Reset() { - *x = ListSubjectsRes{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListSubjectsRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListSubjectsRes) ProtoMessage() {} - -func (x *ListSubjectsRes) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListSubjectsRes.ProtoReflect.Descriptor instead. -func (*ListSubjectsRes) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{20} -} - -func (x *ListSubjectsRes) GetPolicies() []string { - if x != nil { - return x.Policies - } - return nil -} - -func (x *ListSubjectsRes) GetNextPageToken() string { - if x != nil { - return x.NextPageToken - } - return "" -} - -type CountSubjectsReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` - SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` - SubjectRelation string `protobuf:"bytes,3,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` - Subject string `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"` - Relation string `protobuf:"bytes,5,opt,name=relation,proto3" json:"relation,omitempty"` - Permission string `protobuf:"bytes,6,opt,name=permission,proto3" json:"permission,omitempty"` - Object string `protobuf:"bytes,7,opt,name=object,proto3" json:"object,omitempty"` - ObjectType string `protobuf:"bytes,8,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` - NextPageToken string `protobuf:"bytes,9,opt,name=nextPageToken,proto3" json:"nextPageToken,omitempty"` -} - -func (x *CountSubjectsReq) Reset() { - *x = CountSubjectsReq{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CountSubjectsReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CountSubjectsReq) ProtoMessage() {} - -func (x *CountSubjectsReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CountSubjectsReq.ProtoReflect.Descriptor instead. -func (*CountSubjectsReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{21} -} - -func (x *CountSubjectsReq) GetDomain() string { - if x != nil { - return x.Domain - } - return "" -} - -func (x *CountSubjectsReq) GetSubjectType() string { - if x != nil { - return x.SubjectType - } - return "" -} - -func (x *CountSubjectsReq) GetSubjectRelation() string { - if x != nil { - return x.SubjectRelation - } - return "" -} - -func (x *CountSubjectsReq) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *CountSubjectsReq) GetRelation() string { - if x != nil { - return x.Relation - } - return "" -} - -func (x *CountSubjectsReq) GetPermission() string { - if x != nil { - return x.Permission - } - return "" -} - -func (x *CountSubjectsReq) GetObject() string { - if x != nil { - return x.Object - } - return "" -} - -func (x *CountSubjectsReq) GetObjectType() string { - if x != nil { - return x.ObjectType - } - return "" -} - -func (x *CountSubjectsReq) GetNextPageToken() string { - if x != nil { - return x.NextPageToken - } - return "" -} - -type CountSubjectsRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Count uint64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` -} - -func (x *CountSubjectsRes) Reset() { - *x = CountSubjectsRes{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CountSubjectsRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CountSubjectsRes) ProtoMessage() {} - -func (x *CountSubjectsRes) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CountSubjectsRes.ProtoReflect.Descriptor instead. -func (*CountSubjectsRes) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{22} -} - -func (x *CountSubjectsRes) GetCount() uint64 { - if x != nil { - return x.Count - } - return 0 -} - -type ListPermissionsReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` - SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` - SubjectRelation string `protobuf:"bytes,3,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` - Subject string `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"` - Object string `protobuf:"bytes,5,opt,name=object,proto3" json:"object,omitempty"` - ObjectType string `protobuf:"bytes,6,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` - FilterPermissions []string `protobuf:"bytes,7,rep,name=filter_permissions,json=filterPermissions,proto3" json:"filter_permissions,omitempty"` -} - -func (x *ListPermissionsReq) Reset() { - *x = ListPermissionsReq{} - if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListPermissionsReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListPermissionsReq) ProtoMessage() {} - -func (x *ListPermissionsReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListPermissionsReq.ProtoReflect.Descriptor instead. -func (*ListPermissionsReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{23} -} - -func (x *ListPermissionsReq) GetDomain() string { - if x != nil { - return x.Domain - } - return "" -} - -func (x *ListPermissionsReq) GetSubjectType() string { - if x != nil { - return x.SubjectType - } - return "" -} - -func (x *ListPermissionsReq) GetSubjectRelation() string { - if x != nil { - return x.SubjectRelation - } - return "" -} - -func (x *ListPermissionsReq) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *ListPermissionsReq) GetObject() string { - if x != nil { - return x.Object - } - return "" -} - -func (x *ListPermissionsReq) GetObjectType() string { - if x != nil { - return x.ObjectType - } - return "" -} - -func (x *ListPermissionsReq) GetFilterPermissions() []string { - if x != nil { - return x.FilterPermissions - } - return nil -} - -type ListPermissionsRes struct { +type DeletePolicyRes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` - SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` - SubjectRelation string `protobuf:"bytes,3,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` - Subject string `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"` - Object string `protobuf:"bytes,5,opt,name=object,proto3" json:"object,omitempty"` - ObjectType string `protobuf:"bytes,6,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` - Permissions []string `protobuf:"bytes,7,rep,name=permissions,proto3" json:"permissions,omitempty"` + Deleted bool `protobuf:"varint,1,opt,name=deleted,proto3" json:"deleted,omitempty"` } -func (x *ListPermissionsRes) Reset() { - *x = ListPermissionsRes{} +func (x *DeletePolicyRes) Reset() { + *x = DeletePolicyRes{} if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[24] + mi := &file_auth_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ListPermissionsRes) String() string { +func (x *DeletePolicyRes) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListPermissionsRes) ProtoMessage() {} +func (*DeletePolicyRes) ProtoMessage() {} -func (x *ListPermissionsRes) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[24] +func (x *DeletePolicyRes) ProtoReflect() protoreflect.Message { + mi := &file_auth_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1875,86 +518,43 @@ func (x *ListPermissionsRes) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListPermissionsRes.ProtoReflect.Descriptor instead. -func (*ListPermissionsRes) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{24} -} - -func (x *ListPermissionsRes) GetDomain() string { - if x != nil { - return x.Domain - } - return "" -} - -func (x *ListPermissionsRes) GetSubjectType() string { - if x != nil { - return x.SubjectType - } - return "" -} - -func (x *ListPermissionsRes) GetSubjectRelation() string { - if x != nil { - return x.SubjectRelation - } - return "" -} - -func (x *ListPermissionsRes) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *ListPermissionsRes) GetObject() string { - if x != nil { - return x.Object - } - return "" -} - -func (x *ListPermissionsRes) GetObjectType() string { - if x != nil { - return x.ObjectType - } - return "" +// Deprecated: Use DeletePolicyRes.ProtoReflect.Descriptor instead. +func (*DeletePolicyRes) Descriptor() ([]byte, []int) { + return file_auth_proto_rawDescGZIP(), []int{7} } -func (x *ListPermissionsRes) GetPermissions() []string { +func (x *DeletePolicyRes) GetDeleted() bool { if x != nil { - return x.Permissions + return x.Deleted } - return nil + return false } -type DeleteEntityPoliciesReq struct { +type DeleteUserPoliciesReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - EntityType string `protobuf:"bytes,1,opt,name=entity_type,json=entityType,proto3" json:"entity_type,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` } -func (x *DeleteEntityPoliciesReq) Reset() { - *x = DeleteEntityPoliciesReq{} +func (x *DeleteUserPoliciesReq) Reset() { + *x = DeleteUserPoliciesReq{} if protoimpl.UnsafeEnabled { - mi := &file_auth_proto_msgTypes[25] + mi := &file_auth_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *DeleteEntityPoliciesReq) String() string { +func (x *DeleteUserPoliciesReq) String() string { return protoimpl.X.MessageStringOf(x) } -func (*DeleteEntityPoliciesReq) ProtoMessage() {} +func (*DeleteUserPoliciesReq) ProtoMessage() {} -func (x *DeleteEntityPoliciesReq) ProtoReflect() protoreflect.Message { - mi := &file_auth_proto_msgTypes[25] +func (x *DeleteUserPoliciesReq) ProtoReflect() protoreflect.Message { + mi := &file_auth_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1965,19 +565,12 @@ func (x *DeleteEntityPoliciesReq) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use DeleteEntityPoliciesReq.ProtoReflect.Descriptor instead. -func (*DeleteEntityPoliciesReq) Descriptor() ([]byte, []int) { - return file_auth_proto_rawDescGZIP(), []int{25} -} - -func (x *DeleteEntityPoliciesReq) GetEntityType() string { - if x != nil { - return x.EntityType - } - return "" +// Deprecated: Use DeleteUserPoliciesReq.ProtoReflect.Descriptor instead. +func (*DeleteUserPoliciesReq) Descriptor() ([]byte, []int) { + return file_auth_proto_rawDescGZIP(), []int{8} } -func (x *DeleteEntityPoliciesReq) GetId() string { +func (x *DeleteUserPoliciesReq) GetId() string { if x != nil { return x.Id } @@ -2039,298 +632,38 @@ var file_auth_proto_rawDesc = []byte{ 0x0c, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xc7, 0x02, - 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x12, 0x16, - 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, - 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, - 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, - 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, - 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x52, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x12, 0x40, 0x0a, 0x0e, 0x61, 0x64, 0x64, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x41, - 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x52, 0x0e, 0x61, 0x64, 0x64, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x22, 0x24, 0x0a, 0x0c, 0x41, - 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, - 0x64, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x64, 0x64, 0x65, - 0x64, 0x22, 0x26, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x22, 0xd0, 0x02, 0x0a, 0x15, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, - 0x0a, 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x5e, 0x0a, 0x11, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x12, 0x49, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, - 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x52, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x22, 0xca, 0x02, 0x0a, - 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, - 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x2b, 0x0a, 0x0f, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, - 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0xc1, 0x02, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, - 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x0a, - 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, - 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x52, 0x0a, 0x0e, 0x4c, 0x69, - 0x73, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, - 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xac, - 0x02, 0x0a, 0x0f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, - 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, - 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, - 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, - 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, - 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x27, 0x0a, - 0x0f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, - 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xc2, 0x02, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, - 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, - 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x24, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x53, 0x0a, 0x0f, 0x4c, - 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x12, 0x1a, - 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6e, 0x65, - 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x22, 0xad, 0x02, 0x0a, 0x10, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x73, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x21, 0x0a, - 0x0c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x29, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6e, 0x65, - 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x22, 0x28, 0x0a, 0x10, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xfc, 0x01, 0x0a, 0x12, 0x4c, - 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x71, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xef, 0x01, 0x0a, 0x12, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, - 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, - 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x4a, 0x0a, 0x17, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x32, 0x51, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x7a, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, - 0x61, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x18, - 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x22, 0x00, 0x32, 0xba, 0x01, 0x0a, 0x0c, 0x41, - 0x75, 0x74, 0x68, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x49, - 0x73, 0x73, 0x75, 0x65, 0x12, 0x14, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, - 0x61, 0x2e, 0x49, 0x73, 0x73, 0x75, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x00, 0x12, - 0x36, 0x0a, 0x07, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x16, 0x2e, 0x6d, 0x61, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, - 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x66, 0x79, 0x12, 0x17, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, - 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x6d, - 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x32, 0xbf, 0x07, 0x0a, 0x0d, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x41, 0x64, 0x64, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x18, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, - 0x61, 0x6c, 0x61, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, - 0x1a, 0x18, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x41, 0x64, - 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0b, - 0x41, 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x1a, 0x2e, 0x6d, 0x61, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, - 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x6d, 0x61, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1b, - 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x4e, 0x0a, - 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, - 0x1d, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1b, - 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x47, 0x0a, - 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x6d, - 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, - 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, - 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, - 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x1a, - 0x1b, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x4a, - 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x1b, - 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x6d, 0x61, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x0f, 0x4c, 0x69, - 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x1b, 0x2e, - 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x6d, 0x61, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x0d, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, - 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x2e, 0x6d, 0x61, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1e, 0x2e, 0x6d, 0x61, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x5a, 0x0a, - 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, - 0x6c, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x6d, 0x61, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x0e, 0x5a, 0x0c, 0x2e, 0x2f, 0x6d, - 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2b, 0x0a, + 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x27, 0x0a, 0x15, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x32, 0x51, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, + 0x12, 0x18, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x6d, 0x61, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x65, 0x52, 0x65, 0x73, 0x22, 0x00, 0x32, 0xba, 0x01, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x49, 0x73, 0x73, 0x75, 0x65, + 0x12, 0x14, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x49, 0x73, + 0x73, 0x75, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x61, 0x6c, 0x61, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x52, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x16, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x61, 0x6c, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x11, + 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, + 0x17, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, + 0x73, 0x22, 0x00, 0x32, 0x67, 0x0a, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x56, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x6d, 0x61, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, + 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x0e, 0x5a, 0x0c, + 0x2e, 0x2f, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2345,75 +678,34 @@ func file_auth_proto_rawDescGZIP() []byte { return file_auth_proto_rawDescData } -var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 26) +var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_auth_proto_goTypes = []any{ - (*Token)(nil), // 0: magistrala.Token - (*IdentityReq)(nil), // 1: magistrala.IdentityReq - (*IdentityRes)(nil), // 2: magistrala.IdentityRes - (*IssueReq)(nil), // 3: magistrala.IssueReq - (*RefreshReq)(nil), // 4: magistrala.RefreshReq - (*AuthorizeReq)(nil), // 5: magistrala.AuthorizeReq - (*AuthorizeRes)(nil), // 6: magistrala.AuthorizeRes - (*AddPolicyReq)(nil), // 7: magistrala.AddPolicyReq - (*AddPoliciesReq)(nil), // 8: magistrala.AddPoliciesReq - (*AddPolicyRes)(nil), // 9: magistrala.AddPolicyRes - (*AddPoliciesRes)(nil), // 10: magistrala.AddPoliciesRes - (*DeletePolicyFilterReq)(nil), // 11: magistrala.DeletePolicyFilterReq - (*DeletePoliciesReq)(nil), // 12: magistrala.DeletePoliciesReq - (*DeletePolicyReq)(nil), // 13: magistrala.DeletePolicyReq - (*DeletePolicyRes)(nil), // 14: magistrala.DeletePolicyRes - (*ListObjectsReq)(nil), // 15: magistrala.ListObjectsReq - (*ListObjectsRes)(nil), // 16: magistrala.ListObjectsRes - (*CountObjectsReq)(nil), // 17: magistrala.CountObjectsReq - (*CountObjectsRes)(nil), // 18: magistrala.CountObjectsRes - (*ListSubjectsReq)(nil), // 19: magistrala.ListSubjectsReq - (*ListSubjectsRes)(nil), // 20: magistrala.ListSubjectsRes - (*CountSubjectsReq)(nil), // 21: magistrala.CountSubjectsReq - (*CountSubjectsRes)(nil), // 22: magistrala.CountSubjectsRes - (*ListPermissionsReq)(nil), // 23: magistrala.ListPermissionsReq - (*ListPermissionsRes)(nil), // 24: magistrala.ListPermissionsRes - (*DeleteEntityPoliciesReq)(nil), // 25: magistrala.DeleteEntityPoliciesReq + (*Token)(nil), // 0: magistrala.Token + (*IdentityReq)(nil), // 1: magistrala.IdentityReq + (*IdentityRes)(nil), // 2: magistrala.IdentityRes + (*IssueReq)(nil), // 3: magistrala.IssueReq + (*RefreshReq)(nil), // 4: magistrala.RefreshReq + (*AuthorizeReq)(nil), // 5: magistrala.AuthorizeReq + (*AuthorizeRes)(nil), // 6: magistrala.AuthorizeRes + (*DeletePolicyRes)(nil), // 7: magistrala.DeletePolicyRes + (*DeleteUserPoliciesReq)(nil), // 8: magistrala.DeleteUserPoliciesReq } var file_auth_proto_depIdxs = []int32{ - 7, // 0: magistrala.AddPoliciesReq.addPoliciesReq:type_name -> magistrala.AddPolicyReq - 13, // 1: magistrala.DeletePoliciesReq.deletePoliciesReq:type_name -> magistrala.DeletePolicyReq - 5, // 2: magistrala.AuthzService.Authorize:input_type -> magistrala.AuthorizeReq - 3, // 3: magistrala.AuthnService.Issue:input_type -> magistrala.IssueReq - 4, // 4: magistrala.AuthnService.Refresh:input_type -> magistrala.RefreshReq - 1, // 5: magistrala.AuthnService.Identify:input_type -> magistrala.IdentityReq - 7, // 6: magistrala.PolicyService.AddPolicy:input_type -> magistrala.AddPolicyReq - 8, // 7: magistrala.PolicyService.AddPolicies:input_type -> magistrala.AddPoliciesReq - 11, // 8: magistrala.PolicyService.DeletePolicyFilter:input_type -> magistrala.DeletePolicyFilterReq - 12, // 9: magistrala.PolicyService.DeletePolicies:input_type -> magistrala.DeletePoliciesReq - 15, // 10: magistrala.PolicyService.ListObjects:input_type -> magistrala.ListObjectsReq - 15, // 11: magistrala.PolicyService.ListAllObjects:input_type -> magistrala.ListObjectsReq - 17, // 12: magistrala.PolicyService.CountObjects:input_type -> magistrala.CountObjectsReq - 19, // 13: magistrala.PolicyService.ListSubjects:input_type -> magistrala.ListSubjectsReq - 19, // 14: magistrala.PolicyService.ListAllSubjects:input_type -> magistrala.ListSubjectsReq - 21, // 15: magistrala.PolicyService.CountSubjects:input_type -> magistrala.CountSubjectsReq - 23, // 16: magistrala.PolicyService.ListPermissions:input_type -> magistrala.ListPermissionsReq - 25, // 17: magistrala.PolicyService.DeleteEntityPolicies:input_type -> magistrala.DeleteEntityPoliciesReq - 6, // 18: magistrala.AuthzService.Authorize:output_type -> magistrala.AuthorizeRes - 0, // 19: magistrala.AuthnService.Issue:output_type -> magistrala.Token - 0, // 20: magistrala.AuthnService.Refresh:output_type -> magistrala.Token - 2, // 21: magistrala.AuthnService.Identify:output_type -> magistrala.IdentityRes - 9, // 22: magistrala.PolicyService.AddPolicy:output_type -> magistrala.AddPolicyRes - 10, // 23: magistrala.PolicyService.AddPolicies:output_type -> magistrala.AddPoliciesRes - 14, // 24: magistrala.PolicyService.DeletePolicyFilter:output_type -> magistrala.DeletePolicyRes - 14, // 25: magistrala.PolicyService.DeletePolicies:output_type -> magistrala.DeletePolicyRes - 16, // 26: magistrala.PolicyService.ListObjects:output_type -> magistrala.ListObjectsRes - 16, // 27: magistrala.PolicyService.ListAllObjects:output_type -> magistrala.ListObjectsRes - 18, // 28: magistrala.PolicyService.CountObjects:output_type -> magistrala.CountObjectsRes - 20, // 29: magistrala.PolicyService.ListSubjects:output_type -> magistrala.ListSubjectsRes - 20, // 30: magistrala.PolicyService.ListAllSubjects:output_type -> magistrala.ListSubjectsRes - 22, // 31: magistrala.PolicyService.CountSubjects:output_type -> magistrala.CountSubjectsRes - 24, // 32: magistrala.PolicyService.ListPermissions:output_type -> magistrala.ListPermissionsRes - 14, // 33: magistrala.PolicyService.DeleteEntityPolicies:output_type -> magistrala.DeletePolicyRes - 18, // [18:34] is the sub-list for method output_type - 2, // [2:18] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 5, // 0: magistrala.AuthzService.Authorize:input_type -> magistrala.AuthorizeReq + 3, // 1: magistrala.AuthnService.Issue:input_type -> magistrala.IssueReq + 4, // 2: magistrala.AuthnService.Refresh:input_type -> magistrala.RefreshReq + 1, // 3: magistrala.AuthnService.Identify:input_type -> magistrala.IdentityReq + 8, // 4: magistrala.PolicyService.DeleteUserPolicies:input_type -> magistrala.DeleteUserPoliciesReq + 6, // 5: magistrala.AuthzService.Authorize:output_type -> magistrala.AuthorizeRes + 0, // 6: magistrala.AuthnService.Issue:output_type -> magistrala.Token + 0, // 7: magistrala.AuthnService.Refresh:output_type -> magistrala.Token + 2, // 8: magistrala.AuthnService.Identify:output_type -> magistrala.IdentityRes + 7, // 9: magistrala.PolicyService.DeleteUserPolicies:output_type -> magistrala.DeletePolicyRes + 5, // [5:10] is the sub-list for method output_type + 0, // [0:5] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_auth_proto_init() } @@ -2507,90 +799,6 @@ func file_auth_proto_init() { } } file_auth_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*AddPolicyReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*AddPoliciesReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*AddPolicyRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*AddPoliciesRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*DeletePolicyFilterReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*DeletePoliciesReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*DeletePolicyReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[14].Exporter = func(v any, i int) any { switch v := v.(*DeletePolicyRes); i { case 0: return &v.state @@ -2602,128 +810,8 @@ func file_auth_proto_init() { return nil } } - file_auth_proto_msgTypes[15].Exporter = func(v any, i int) any { - switch v := v.(*ListObjectsReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[16].Exporter = func(v any, i int) any { - switch v := v.(*ListObjectsRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[17].Exporter = func(v any, i int) any { - switch v := v.(*CountObjectsReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[18].Exporter = func(v any, i int) any { - switch v := v.(*CountObjectsRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[19].Exporter = func(v any, i int) any { - switch v := v.(*ListSubjectsReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[20].Exporter = func(v any, i int) any { - switch v := v.(*ListSubjectsRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[21].Exporter = func(v any, i int) any { - switch v := v.(*CountSubjectsReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[22].Exporter = func(v any, i int) any { - switch v := v.(*CountSubjectsRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[23].Exporter = func(v any, i int) any { - switch v := v.(*ListPermissionsReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[24].Exporter = func(v any, i int) any { - switch v := v.(*ListPermissionsRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_auth_proto_msgTypes[25].Exporter = func(v any, i int) any { - switch v := v.(*DeleteEntityPoliciesReq); i { + file_auth_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*DeleteUserPoliciesReq); i { case 0: return &v.state case 1: @@ -2744,7 +832,7 @@ func file_auth_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_auth_proto_rawDesc, NumEnums: 0, - NumMessages: 26, + NumMessages: 9, NumExtensions: 0, NumServices: 3, }, diff --git a/auth.proto b/auth.proto index fb034ab81c..c54df715d1 100644 --- a/auth.proto +++ b/auth.proto @@ -25,18 +25,7 @@ service AuthnService { // PolicyService is a service that provides policy CRUD // functionalities for magistrala services. service PolicyService { - rpc AddPolicy(AddPolicyReq) returns (AddPolicyRes) {} - rpc AddPolicies(AddPoliciesReq) returns (AddPoliciesRes) {} - rpc DeletePolicyFilter(DeletePolicyFilterReq) returns (DeletePolicyRes) {} - rpc DeletePolicies(DeletePoliciesReq) returns (DeletePolicyRes) {} - rpc ListObjects(ListObjectsReq) returns (ListObjectsRes) {} - rpc ListAllObjects(ListObjectsReq) returns (ListObjectsRes) {} - rpc CountObjects(CountObjectsReq) returns (CountObjectsRes) {} - rpc ListSubjects(ListSubjectsReq) returns (ListSubjectsRes) {} - rpc ListAllSubjects(ListSubjectsReq) returns (ListSubjectsRes) {} - rpc CountSubjects(CountSubjectsReq) returns (CountSubjectsRes) {} - rpc ListPermissions(ListPermissionsReq) returns (ListPermissionsRes) {} - rpc DeleteEntityPolicies(DeleteEntityPoliciesReq) returns (DeletePolicyRes) {} + rpc DeleteUserPolicies(DeleteUserPoliciesReq) returns (DeletePolicyRes) {} } // If a token is not carrying any information itself, the type @@ -86,144 +75,8 @@ message AuthorizeRes { string id = 2; } -message AddPolicyReq { - string domain = 1; - string subject_type = 2; - string subject_relation = 3; - string subject_kind = 4; - string subject = 5; - string relation = 6; - string permission = 7; - string object = 8; - string object_kind = 9; - string object_type = 10; -} - -message AddPoliciesReq{ - repeated AddPolicyReq addPoliciesReq= 1; -} - -message AddPolicyRes { bool added = 1; } - -message AddPoliciesRes { bool added = 1; } - -message DeletePolicyFilterReq { - string domain = 1; - string subject_type = 2; - string subject_relation = 3; - string subject_kind = 4; - string subject = 5; - string relation = 6; - string permission = 7; - string object = 8; - string object_kind = 9; - string object_type = 10; -} - -message DeletePoliciesReq { - repeated DeletePolicyReq deletePoliciesReq = 1; -} - -message DeletePolicyReq { - string domain = 1; - string subject_type = 2; - string subject_relation = 3; - string subject_kind = 4; - string subject = 5; - string relation = 6; - string permission = 7; - string object = 8; - string object_kind = 9; - string object_type = 10; -} - message DeletePolicyRes { bool deleted = 1; } -message ListObjectsReq { - string domain = 1; - string subject_type = 2; - string subject_relation = 3; - string subject = 4; - string relation = 5; - string permission = 6; - string object = 7; - string object_type = 8; - string nextPageToken = 9; - uint64 limit = 10; -} - -message ListObjectsRes { - repeated string policies = 1; - string nextPageToken = 2; -} - -message CountObjectsReq { - string domain = 1; - string subject_type = 2; - string subject_relation = 3; - string subject = 4; - string relation = 5; - string permission = 6; - string object = 7; - string object_type = 8; - string nextPageToken = 9; -} - -message CountObjectsRes { uint64 count = 1; } - -message ListSubjectsReq { - string domain = 1; - string subject_type = 2; - string subject_relation = 3; - string subject = 4; - string relation = 5; - string permission = 6; - string object = 7; - string object_type = 8; - string nextPageToken = 9; - uint64 limit = 10; -} - -message ListSubjectsRes { - repeated string policies = 1; - string nextPageToken = 2; -} - -message CountSubjectsReq { - string domain = 1; - string subject_type = 2; - string subject_relation = 3; - string subject = 4; - string relation = 5; - string permission = 6; - string object = 7; - string object_type = 8; - string nextPageToken = 9; -} - -message CountSubjectsRes { uint64 count = 1; } - -message ListPermissionsReq { - string domain = 1; - string subject_type = 2; - string subject_relation = 3; - string subject = 4; - string object = 5; - string object_type = 6; - repeated string filter_permissions = 7; -} - -message ListPermissionsRes { - string domain = 1; - string subject_type = 2; - string subject_relation = 3; - string subject = 4; - string object = 5; - string object_type = 6; - repeated string permissions = 7; -} - -message DeleteEntityPoliciesReq{ - string entity_type = 1; - string id = 2; +message DeleteUserPoliciesReq{ + string id = 1; } diff --git a/auth/api/grpc/client.go b/auth/api/grpc/client.go index 2d193c3ed3..7b30ba8c05 100644 --- a/auth/api/grpc/client.go +++ b/auth/api/grpc/client.go @@ -195,118 +195,19 @@ func encodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{} } type policyGrpcClient struct { - addPolicy endpoint.Endpoint - addPolicies endpoint.Endpoint - deletePolicyFilter endpoint.Endpoint - deletePolicies endpoint.Endpoint - listObjects endpoint.Endpoint - listAllObjects endpoint.Endpoint - countObjects endpoint.Endpoint - listSubjects endpoint.Endpoint - listAllSubjects endpoint.Endpoint - countSubjects endpoint.Endpoint - listPermissions endpoint.Endpoint - deleteEntityPolicies endpoint.Endpoint - timeout time.Duration + deleteUserPolicies endpoint.Endpoint + timeout time.Duration } // NewPolicyClient returns new policy gRPC client instance. func NewPolicyClient(conn *grpc.ClientConn, timeout time.Duration) magistrala.PolicyServiceClient { return &policyGrpcClient{ - addPolicy: kitgrpc.NewClient( + deleteUserPolicies: kitgrpc.NewClient( conn, policySvcName, - "AddPolicy", - encodeAddPolicyRequest, - decodeAddPolicyResponse, - magistrala.AddPolicyRes{}, - ).Endpoint(), - addPolicies: kitgrpc.NewClient( - conn, - policySvcName, - "AddPolicies", - encodeAddPoliciesRequest, - decodeAddPoliciesResponse, - magistrala.AddPoliciesRes{}, - ).Endpoint(), - deletePolicyFilter: kitgrpc.NewClient( - conn, - policySvcName, - "DeletePolicyFilter", - encodeDeletePolicyFilterRequest, - decodeDeletePolicyFilterResponse, - magistrala.DeletePolicyRes{}, - ).Endpoint(), - deletePolicies: kitgrpc.NewClient( - conn, - policySvcName, - "DeletePolicies", - encodeDeletePoliciesRequest, - decodeDeletePoliciesResponse, - magistrala.DeletePolicyRes{}, - ).Endpoint(), - listObjects: kitgrpc.NewClient( - conn, - policySvcName, - "ListObjects", - encodeListObjectsRequest, - decodeListObjectsResponse, - magistrala.ListObjectsRes{}, - ).Endpoint(), - listAllObjects: kitgrpc.NewClient( - conn, - policySvcName, - "ListAllObjects", - encodeListObjectsRequest, - decodeListObjectsResponse, - magistrala.ListObjectsRes{}, - ).Endpoint(), - countObjects: kitgrpc.NewClient( - conn, - policySvcName, - "CountObjects", - encodeCountObjectsRequest, - decodeCountObjectsResponse, - magistrala.CountObjectsRes{}, - ).Endpoint(), - listSubjects: kitgrpc.NewClient( - conn, - policySvcName, - "ListSubjects", - encodeListSubjectsRequest, - decodeListSubjectsResponse, - magistrala.ListSubjectsRes{}, - ).Endpoint(), - listAllSubjects: kitgrpc.NewClient( - conn, - policySvcName, - "ListAllSubjects", - encodeListSubjectsRequest, - decodeListSubjectsResponse, - magistrala.ListSubjectsRes{}, - ).Endpoint(), - countSubjects: kitgrpc.NewClient( - conn, - policySvcName, - "CountSubjects", - encodeCountSubjectsRequest, - decodeCountSubjectsResponse, - magistrala.CountSubjectsRes{}, - ).Endpoint(), - listPermissions: kitgrpc.NewClient( - conn, - policySvcName, - "ListPermissions", - encodeListPermissionsRequest, - decodeListPermissionsResponse, - magistrala.ListPermissionsRes{}, - ).Endpoint(), - deleteEntityPolicies: kitgrpc.NewClient( - conn, - policySvcName, - "DeleteEntityPolicies", - encodeDeleteEntityPoliciesRequest, - decodeDeleteEntityPoliciesResponse, + "DeleteUserPolicies", + encodeDeleteUserPoliciesRequest, + decodeDeleteUserPoliciesResponse, magistrala.DeletePolicyRes{}, ).Endpoint(), @@ -314,462 +215,12 @@ func NewPolicyClient(conn *grpc.ClientConn, timeout time.Duration) magistrala.Po } } -func (client policyGrpcClient) AddPolicy(ctx context.Context, in *magistrala.AddPolicyReq, opts ...grpc.CallOption) (*magistrala.AddPolicyRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - - res, err := client.addPolicy(ctx, policyReq{ - Domain: in.GetDomain(), - SubjectType: in.GetSubjectType(), - SubjectKind: in.GetSubjectKind(), - Subject: in.GetSubject(), - Relation: in.GetRelation(), - Permission: in.GetPermission(), - ObjectType: in.GetObjectType(), - ObjectKind: in.GetObjectKind(), - Object: in.GetObject(), - }) - if err != nil { - return &magistrala.AddPolicyRes{}, decodeError(err) - } - - apr := res.(addPolicyRes) - return &magistrala.AddPolicyRes{Added: apr.added}, nil -} - -func decodeAddPolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*magistrala.AddPolicyRes) - return addPolicyRes{added: res.Added}, nil -} - -func encodeAddPolicyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(policyReq) - return &magistrala.AddPolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - SubjectKind: req.SubjectKind, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - ObjectKind: req.ObjectKind, - Object: req.Object, - }, nil -} - -func (client policyGrpcClient) AddPolicies(ctx context.Context, in *magistrala.AddPoliciesReq, opts ...grpc.CallOption) (*magistrala.AddPoliciesRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - r := policiesReq{} - if in.GetAddPoliciesReq() != nil { - for _, mgApr := range in.GetAddPoliciesReq() { - r = append(r, policyReq{ - Domain: mgApr.GetDomain(), - SubjectType: mgApr.GetSubjectType(), - SubjectKind: mgApr.GetSubjectKind(), - Subject: mgApr.GetSubject(), - Relation: mgApr.GetRelation(), - Permission: mgApr.GetPermission(), - ObjectType: mgApr.GetObjectType(), - ObjectKind: mgApr.GetObjectKind(), - Object: mgApr.GetObject(), - }) - } - } - - res, err := client.addPolicies(ctx, r) - if err != nil { - return &magistrala.AddPoliciesRes{}, decodeError(err) - } - - apr := res.(addPoliciesRes) - return &magistrala.AddPoliciesRes{Added: apr.added}, nil -} - -func decodeAddPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*magistrala.AddPoliciesRes) - return addPoliciesRes{added: res.Added}, nil -} - -func encodeAddPoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - reqs := grpcReq.(policiesReq) - - addPolicies := []*magistrala.AddPolicyReq{} - - for _, req := range reqs { - addPolicies = append(addPolicies, &magistrala.AddPolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - SubjectKind: req.SubjectKind, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - ObjectKind: req.ObjectKind, - Object: req.Object, - }) - } - return &magistrala.AddPoliciesReq{AddPoliciesReq: addPolicies}, nil -} - -func (client policyGrpcClient) DeletePolicyFilter(ctx context.Context, in *magistrala.DeletePolicyFilterReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - - res, err := client.deletePolicyFilter(ctx, policyReq{ - Domain: in.GetDomain(), - SubjectType: in.GetSubjectType(), - SubjectKind: in.GetSubjectKind(), - Subject: in.GetSubject(), - Relation: in.GetRelation(), - Permission: in.GetPermission(), - ObjectType: in.GetObjectType(), - ObjectKind: in.GetObjectKind(), - Object: in.GetObject(), - }) - if err != nil { - return &magistrala.DeletePolicyRes{}, decodeError(err) - } - - dpr := res.(deletePolicyRes) - return &magistrala.DeletePolicyRes{Deleted: dpr.deleted}, nil -} - -func decodeDeletePolicyFilterResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*magistrala.DeletePolicyRes) - return deletePolicyRes{deleted: res.GetDeleted()}, nil -} - -func encodeDeletePolicyFilterRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(policyReq) - return &magistrala.DeletePolicyFilterReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - SubjectKind: req.SubjectKind, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - ObjectKind: req.ObjectKind, - Object: req.Object, - }, nil -} - -func (client policyGrpcClient) DeletePolicies(ctx context.Context, in *magistrala.DeletePoliciesReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - r := policiesReq{} - - if in.GetDeletePoliciesReq() != nil { - for _, mgApr := range in.GetDeletePoliciesReq() { - r = append(r, policyReq{ - Domain: mgApr.GetDomain(), - SubjectType: mgApr.GetSubjectType(), - SubjectKind: mgApr.GetSubjectKind(), - Subject: mgApr.GetSubject(), - Relation: mgApr.GetRelation(), - Permission: mgApr.GetPermission(), - ObjectType: mgApr.GetObjectType(), - ObjectKind: mgApr.GetObjectKind(), - Object: mgApr.GetObject(), - }) - } - } - res, err := client.deletePolicies(ctx, r) - if err != nil { - return &magistrala.DeletePolicyRes{}, decodeError(err) - } - - dpr := res.(deletePolicyRes) - return &magistrala.DeletePolicyRes{Deleted: dpr.deleted}, nil -} - -func decodeDeletePoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*magistrala.DeletePolicyRes) - return deletePolicyRes{deleted: res.GetDeleted()}, nil -} - -func encodeDeletePoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - reqs := grpcReq.(policiesReq) - - deletePolicies := []*magistrala.DeletePolicyReq{} - - for _, req := range reqs { - deletePolicies = append(deletePolicies, &magistrala.DeletePolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - SubjectKind: req.SubjectKind, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - ObjectKind: req.ObjectKind, - Object: req.Object, - }) - } - return &magistrala.DeletePoliciesReq{DeletePoliciesReq: deletePolicies}, nil -} - -func (client policyGrpcClient) ListObjects(ctx context.Context, in *magistrala.ListObjectsReq, opts ...grpc.CallOption) (*magistrala.ListObjectsRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - - res, err := client.listObjects(ctx, listObjectsReq{ - Domain: in.GetDomain(), - SubjectType: in.GetSubjectType(), - Subject: in.GetSubject(), - Relation: in.GetRelation(), - Permission: in.GetPermission(), - ObjectType: in.GetObjectType(), - Object: in.GetObject(), - }) - if err != nil { - return &magistrala.ListObjectsRes{}, decodeError(err) - } - - lpr := res.(listObjectsRes) - return &magistrala.ListObjectsRes{Policies: lpr.policies}, nil -} - -func decodeListObjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*magistrala.ListObjectsRes) - return listObjectsRes{policies: res.GetPolicies()}, nil -} - -func encodeListObjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(listObjectsReq) - return &magistrala.ListObjectsReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - Object: req.Object, - }, nil -} - -func (client policyGrpcClient) ListAllObjects(ctx context.Context, in *magistrala.ListObjectsReq, opts ...grpc.CallOption) (*magistrala.ListObjectsRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - - res, err := client.listAllObjects(ctx, listObjectsReq{ - Domain: in.GetDomain(), - SubjectType: in.GetSubjectType(), - Subject: in.GetSubject(), - Relation: in.GetRelation(), - Permission: in.GetPermission(), - ObjectType: in.GetObjectType(), - Object: in.GetObject(), - }) - if err != nil { - return &magistrala.ListObjectsRes{}, decodeError(err) - } - - lpr := res.(listObjectsRes) - return &magistrala.ListObjectsRes{Policies: lpr.policies}, nil -} - -func (client policyGrpcClient) CountObjects(ctx context.Context, in *magistrala.CountObjectsReq, opts ...grpc.CallOption) (*magistrala.CountObjectsRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - - res, err := client.countObjects(ctx, countObjectsReq{ - Domain: in.GetDomain(), - SubjectType: in.GetSubjectType(), - Subject: in.GetSubject(), - Relation: in.GetRelation(), - Permission: in.GetPermission(), - ObjectType: in.GetObjectType(), - Object: in.GetObject(), - }) - if err != nil { - return &magistrala.CountObjectsRes{}, decodeError(err) - } - - cp := res.(countObjectsRes) - return &magistrala.CountObjectsRes{Count: cp.count}, nil -} - -func decodeCountObjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*magistrala.CountObjectsRes) - return countObjectsRes{count: res.GetCount()}, nil -} - -func encodeCountObjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(countObjectsReq) - return &magistrala.CountObjectsReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - Object: req.Object, - }, nil -} - -func (client policyGrpcClient) ListSubjects(ctx context.Context, in *magistrala.ListSubjectsReq, opts ...grpc.CallOption) (*magistrala.ListSubjectsRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - - res, err := client.listSubjects(ctx, listSubjectsReq{ - Domain: in.GetDomain(), - SubjectType: in.GetSubjectType(), - Subject: in.GetSubject(), - Relation: in.GetRelation(), - Permission: in.GetPermission(), - ObjectType: in.GetObjectType(), - Object: in.GetObject(), - NextPageToken: in.GetNextPageToken(), - }) - if err != nil { - return &magistrala.ListSubjectsRes{}, decodeError(err) - } - - lpr := res.(listSubjectsRes) - return &magistrala.ListSubjectsRes{Policies: lpr.policies}, nil -} - -func decodeListSubjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*magistrala.ListSubjectsRes) - return listSubjectsRes{policies: res.GetPolicies()}, nil -} - -func encodeListSubjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(listSubjectsReq) - return &magistrala.ListSubjectsReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - Object: req.Object, - }, nil -} - -func (client policyGrpcClient) ListAllSubjects(ctx context.Context, in *magistrala.ListSubjectsReq, opts ...grpc.CallOption) (*magistrala.ListSubjectsRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - - res, err := client.listAllSubjects(ctx, listSubjectsReq{ - Domain: in.GetDomain(), - SubjectType: in.GetSubjectType(), - Subject: in.GetSubject(), - Relation: in.GetRelation(), - Permission: in.GetPermission(), - ObjectType: in.GetObjectType(), - Object: in.GetObject(), - }) - if err != nil { - return &magistrala.ListSubjectsRes{}, decodeError(err) - } - - lpr := res.(listSubjectsRes) - return &magistrala.ListSubjectsRes{Policies: lpr.policies}, nil -} - -func (client policyGrpcClient) CountSubjects(ctx context.Context, in *magistrala.CountSubjectsReq, opts ...grpc.CallOption) (*magistrala.CountSubjectsRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - - res, err := client.countSubjects(ctx, countSubjectsReq{ - Domain: in.GetDomain(), - SubjectType: in.GetSubjectType(), - Subject: in.GetSubject(), - Relation: in.GetRelation(), - Permission: in.GetPermission(), - ObjectType: in.GetObjectType(), - Object: in.GetObject(), - }) - if err != nil { - return &magistrala.CountSubjectsRes{}, err - } - - cp := res.(countSubjectsRes) - return &magistrala.CountSubjectsRes{Count: cp.count}, err -} - -func decodeCountSubjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*magistrala.CountSubjectsRes) - return countSubjectsRes{count: res.GetCount()}, nil -} - -func encodeCountSubjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(countSubjectsReq) - return &magistrala.CountSubjectsReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - Object: req.Object, - }, nil -} - -func (client policyGrpcClient) ListPermissions(ctx context.Context, in *magistrala.ListPermissionsReq, opts ...grpc.CallOption) (*magistrala.ListPermissionsRes, error) { - ctx, cancel := context.WithTimeout(ctx, client.timeout) - defer cancel() - - res, err := client.listPermissions(ctx, listPermissionsReq{ - Domain: in.GetDomain(), - SubjectType: in.GetSubjectType(), - Subject: in.GetSubject(), - SubjectRelation: in.GetSubjectRelation(), - ObjectType: in.GetObjectType(), - Object: in.GetObject(), - FilterPermissions: in.GetFilterPermissions(), - }) - if err != nil { - return &magistrala.ListPermissionsRes{}, decodeError(err) - } - - lp := res.(listPermissionsRes) - return &magistrala.ListPermissionsRes{ - Domain: lp.Domain, - SubjectType: lp.SubjectType, - Subject: lp.Subject, - SubjectRelation: lp.SubjectRelation, - ObjectType: lp.ObjectType, - Object: lp.Object, - Permissions: lp.Permissions, - }, nil -} - -func decodeListPermissionsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(*magistrala.ListPermissionsRes) - return listPermissionsRes{ - Domain: res.GetDomain(), - SubjectType: res.GetSubjectType(), - Subject: res.GetSubject(), - SubjectRelation: res.GetSubjectRelation(), - ObjectType: res.GetObjectType(), - Object: res.GetObject(), - Permissions: res.GetPermissions(), - }, nil -} - -func encodeListPermissionsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(listPermissionsReq) - return &magistrala.ListPermissionsReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - ObjectType: req.ObjectType, - Object: req.Object, - FilterPermissions: req.FilterPermissions, - }, nil -} - -func (client policyGrpcClient) DeleteEntityPolicies(ctx context.Context, in *magistrala.DeleteEntityPoliciesReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { +func (client policyGrpcClient) DeleteUserPolicies(ctx context.Context, in *magistrala.DeleteUserPoliciesReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { ctx, cancel := context.WithTimeout(ctx, client.timeout) defer cancel() - res, err := client.deleteEntityPolicies(ctx, deleteEntityPoliciesReq{ - EntityType: in.GetEntityType(), - ID: in.GetId(), + res, err := client.deleteUserPolicies(ctx, deleteUserPoliciesReq{ + ID: in.GetId(), }) if err != nil { return &magistrala.DeletePolicyRes{}, decodeError(err) @@ -779,16 +230,15 @@ func (client policyGrpcClient) DeleteEntityPolicies(ctx context.Context, in *mag return &magistrala.DeletePolicyRes{Deleted: dpr.deleted}, nil } -func decodeDeleteEntityPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { +func decodeDeleteUserPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { res := grpcRes.(*magistrala.DeletePolicyRes) return deletePolicyRes{deleted: res.GetDeleted()}, nil } -func encodeDeleteEntityPoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(deleteEntityPoliciesReq) - return &magistrala.DeleteEntityPoliciesReq{ - EntityType: req.EntityType, - Id: req.ID, +func encodeDeleteUserPoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { + req := grpcReq.(deleteUserPoliciesReq) + return &magistrala.DeleteUserPoliciesReq{ + Id: req.ID, }, nil } diff --git a/auth/api/grpc/endpoint.go b/auth/api/grpc/endpoint.go index 47e9d78f42..f95fcdafd7 100644 --- a/auth/api/grpc/endpoint.go +++ b/auth/api/grpc/endpoint.go @@ -96,268 +96,14 @@ func authorizeEndpoint(svc auth.Service) endpoint.Endpoint { } } -func addPolicyEndpoint(svc auth.Service) endpoint.Endpoint { +func deleteUserPoliciesEndpoint(svc auth.Service) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(policyReq) - if err := req.validate(); err != nil { - return addPolicyRes{}, err - } - - err := svc.AddPolicy(ctx, auth.PolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - SubjectKind: req.SubjectKind, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - ObjectKind: req.ObjectKind, - Object: req.Object, - }) - if err != nil { - return addPolicyRes{}, err - } - return addPolicyRes{added: true}, err - } -} - -func addPoliciesEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - reqs := request.(policiesReq) - if err := reqs.validate(); err != nil { - return addPoliciesRes{}, err - } - - prs := []auth.PolicyReq{} - - for _, req := range reqs { - prs = append(prs, auth.PolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - SubjectKind: req.SubjectKind, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - ObjectKind: req.ObjectKind, - Object: req.Object, - }) - } - - if err := svc.AddPolicies(ctx, prs); err != nil { - return addPoliciesRes{}, err - } - return addPoliciesRes{added: true}, nil - } -} - -func deletePolicyFilterEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(policyReq) - if err := req.validate(); err != nil { - return deletePolicyRes{}, err - } - - err := svc.DeletePolicyFilter(ctx, auth.PolicyReq{ - Domain: req.Domain, - SubjectKind: req.SubjectKind, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - ObjectKind: req.ObjectKind, - Object: req.Object, - }) - if err != nil { - return deletePolicyRes{}, err - } - return deletePolicyRes{deleted: true}, nil - } -} - -func deletePoliciesEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - reqs := request.(policiesReq) - if err := reqs.validate(); err != nil { - return deletePolicyRes{}, err - } - - prs := []auth.PolicyReq{} - - for _, req := range reqs { - prs = append(prs, auth.PolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - SubjectKind: req.SubjectKind, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - ObjectKind: req.ObjectKind, - Object: req.Object, - }) - } - - if err := svc.DeletePolicies(ctx, prs); err != nil { - return deletePolicyRes{}, err - } - return deletePolicyRes{deleted: true}, nil - } -} - -func listObjectsEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(listObjectsReq) - - page, err := svc.ListObjects(ctx, auth.PolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - Object: req.Object, - }, req.NextPageToken, req.Limit) - if err != nil { - return listObjectsRes{}, err - } - return listObjectsRes{policies: page.Policies, nextPageToken: page.NextPageToken}, nil - } -} - -func listAllObjectsEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(listObjectsReq) - - page, err := svc.ListAllObjects(ctx, auth.PolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - Object: req.Object, - }) - if err != nil { - return listObjectsRes{}, err - } - return listObjectsRes{policies: page.Policies, nextPageToken: page.NextPageToken}, nil - } -} - -func countObjectsEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(countObjectsReq) - - count, err := svc.CountObjects(ctx, auth.PolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - Object: req.Object, - }) - if err != nil { - return countObjectsRes{}, err - } - return countObjectsRes{count: count}, nil - } -} - -func listSubjectsEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(listSubjectsReq) - - page, err := svc.ListSubjects(ctx, auth.PolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - Object: req.Object, - }, req.NextPageToken, req.Limit) - if err != nil { - return listSubjectsRes{}, err - } - return listSubjectsRes{policies: page.Policies, nextPageToken: page.NextPageToken}, nil - } -} - -func listAllSubjectsEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(listSubjectsReq) - - page, err := svc.ListAllSubjects(ctx, auth.PolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - Object: req.Object, - }) - if err != nil { - return listSubjectsRes{}, err - } - return listSubjectsRes{policies: page.Policies, nextPageToken: page.NextPageToken}, nil - } -} - -func countSubjectsEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(countSubjectsReq) - - count, err := svc.CountSubjects(ctx, auth.PolicyReq{ - Domain: req.Domain, - SubjectType: req.SubjectType, - Subject: req.Subject, - Relation: req.Relation, - Permission: req.Permission, - ObjectType: req.ObjectType, - Object: req.Object, - }) - if err != nil { - return countSubjectsRes{}, err - } - return countSubjectsRes{count: count}, nil - } -} - -func listPermissionsEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(listPermissionsReq) - permissions, err := svc.ListPermissions(ctx, auth.PolicyReq{ - SubjectType: req.SubjectType, - SubjectRelation: req.SubjectRelation, - Subject: req.Subject, - Object: req.Object, - ObjectType: req.ObjectType, - }, req.FilterPermissions) - if err != nil { - return listPermissionsRes{}, err - } - return listPermissionsRes{ - SubjectType: req.SubjectType, - SubjectRelation: req.SubjectRelation, - Subject: req.Subject, - Object: req.Object, - ObjectType: req.ObjectType, - Permissions: permissions, - }, nil - } -} - -func deleteEntityPoliciesEndpoint(svc auth.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - req := request.(deleteEntityPoliciesReq) + req := request.(deleteUserPoliciesReq) if err := req.validate(); err != nil { return deletePolicyRes{}, err } - if err := svc.DeleteEntityPolicies(ctx, req.EntityType, req.ID); err != nil { + if err := svc.DeleteUserPolicies(ctx, req.ID); err != nil { return deletePolicyRes{}, err } diff --git a/auth/api/grpc/endpoint_test.go b/auth/api/grpc/endpoint_test.go index 381e5443e3..ab5c2ed3c8 100644 --- a/auth/api/grpc/endpoint_test.go +++ b/auth/api/grpc/endpoint_test.go @@ -20,9 +20,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "google.golang.org/grpc" - "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" - "google.golang.org/grpc/status" ) const ( @@ -345,675 +343,7 @@ func TestAuthorize(t *testing.T) { } } -func TestAddPolicy(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - groupAdminObj := "groupadmin" - - cases := []struct { - desc string - token string - addPolicyReq *magistrala.AddPolicyReq - addPolicyRes *magistrala.AddPolicyRes - err error - }{ - { - desc: "add groupadmin policy to user", - token: validToken, - addPolicyReq: &magistrala.AddPolicyReq{ - Subject: id, - SubjectType: usersType, - Object: groupAdminObj, - ObjectType: usersType, - Relation: memberRelation, - Permission: adminpermission, - }, - addPolicyRes: &magistrala.AddPolicyRes{Added: true}, - err: nil, - }, - { - desc: "add groupadmin policy to user with invalid token", - token: inValidToken, - addPolicyReq: &magistrala.AddPolicyReq{ - Subject: id, - SubjectType: usersType, - Object: groupAdminObj, - ObjectType: usersType, - Relation: memberRelation, - Permission: adminpermission, - }, - addPolicyRes: &magistrala.AddPolicyRes{Added: false}, - err: svcerr.ErrAuthorization, - }, - } - for _, tc := range cases { - svcCall := svc.On("AddPolicy", mock.Anything, mock.Anything).Return(tc.err) - apr, err := client.AddPolicy(context.Background(), tc.addPolicyReq) - if apr != nil { - assert.Equal(t, tc.addPolicyRes, apr, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.addPolicyRes, apr)) - } - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) - svcCall.Unset() - } -} - -func TestAddPolicies(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - groupAdminObj := "groupadmin" - - cases := []struct { - desc string - token string - pr *magistrala.AddPoliciesReq - ar *magistrala.AddPoliciesRes - err error - }{ - { - desc: "add groupadmin policy to user", - token: validToken, - pr: &magistrala.AddPoliciesReq{ - AddPoliciesReq: []*magistrala.AddPolicyReq{ - { - Subject: id, - SubjectType: usersType, - Object: groupAdminObj, - ObjectType: usersType, - Relation: memberRelation, - Permission: adminpermission, - }, - }, - }, - ar: &magistrala.AddPoliciesRes{Added: true}, - err: nil, - }, - { - desc: "add groupadmin policy to user with invalid token", - token: inValidToken, - pr: &magistrala.AddPoliciesReq{ - AddPoliciesReq: []*magistrala.AddPolicyReq{ - { - Subject: id, - SubjectType: usersType, - Object: groupAdminObj, - ObjectType: usersType, - Relation: memberRelation, - Permission: adminpermission, - }, - }, - }, - ar: &magistrala.AddPoliciesRes{Added: false}, - err: svcerr.ErrAuthorization, - }, - } - for _, tc := range cases { - svcCall := svc.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.err) - apr, err := client.AddPolicies(context.Background(), tc.pr) - if apr != nil { - assert.Equal(t, tc.ar, apr, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.ar, apr)) - } - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) - svcCall.Unset() - } -} - -func TestDeletePolicyFilter(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - readRelation := "read" - thingID := "thing" - - cases := []struct { - desc string - token string - deletePolicyFilterReq *magistrala.DeletePolicyFilterReq - deletePolicyFilterRes *magistrala.DeletePolicyRes - err error - }{ - { - desc: "delete valid policy", - token: validToken, - deletePolicyFilterReq: &magistrala.DeletePolicyFilterReq{ - Subject: id, - SubjectType: usersType, - Object: thingID, - ObjectType: thingsType, - Relation: readRelation, - Permission: readRelation, - }, - deletePolicyFilterRes: &magistrala.DeletePolicyRes{Deleted: true}, - err: nil, - }, - { - desc: "delete invalid policy with invalid token", - token: inValidToken, - deletePolicyFilterReq: &magistrala.DeletePolicyFilterReq{ - Subject: id, - SubjectType: usersType, - Object: thingID, - ObjectType: thingsType, - Relation: readRelation, - Permission: readRelation, - }, - deletePolicyFilterRes: &magistrala.DeletePolicyRes{Deleted: false}, - err: svcerr.ErrAuthorization, - }, - } - for _, tc := range cases { - svcCall := svc.On("DeletePolicyFilter", mock.Anything, mock.Anything).Return(tc.err) - dpr, err := client.DeletePolicyFilter(context.Background(), tc.deletePolicyFilterReq) - assert.Equal(t, tc.deletePolicyFilterRes.GetDeleted(), dpr.GetDeleted(), fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.deletePolicyFilterRes.GetDeleted(), dpr.GetDeleted())) - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) - svcCall.Unset() - } -} - -func TestDeletePolicies(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - readRelation := "read" - thingID := "thing" - - cases := []struct { - desc string - token string - deletePoliciesReq *magistrala.DeletePoliciesReq - deletePoliciesRes *magistrala.DeletePolicyRes - err error - }{ - { - desc: "delete policies with valid token", - token: validToken, - deletePoliciesReq: &magistrala.DeletePoliciesReq{ - DeletePoliciesReq: []*magistrala.DeletePolicyReq{ - { - Subject: id, - SubjectType: usersType, - Object: thingID, - ObjectType: thingsType, - Relation: readRelation, - Permission: readRelation, - }, - }, - }, - deletePoliciesRes: &magistrala.DeletePolicyRes{Deleted: true}, - err: nil, - }, - { - desc: "delete policies with invalid token", - token: inValidToken, - deletePoliciesReq: &magistrala.DeletePoliciesReq{ - DeletePoliciesReq: []*magistrala.DeletePolicyReq{ - { - Subject: id, - SubjectType: usersType, - Object: thingID, - ObjectType: thingsType, - Relation: readRelation, - Permission: readRelation, - }, - }, - }, - deletePoliciesRes: &magistrala.DeletePolicyRes{Deleted: false}, - err: svcerr.ErrAuthorization, - }, - } - for _, tc := range cases { - svcCall := svc.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.err) - apr, err := client.DeletePolicies(context.Background(), tc.deletePoliciesReq) - if apr != nil { - assert.Equal(t, tc.deletePoliciesRes, apr, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.deletePoliciesRes, apr)) - } - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) - svcCall.Unset() - } -} - -func TestListObjects(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - cases := []struct { - desc string - token string - listObjectsReq *magistrala.ListObjectsReq - listObjectsRes *magistrala.ListObjectsRes - err error - }{ - { - desc: "list objects with valid token", - token: validToken, - listObjectsReq: &magistrala.ListObjectsReq{ - Domain: domainID, - ObjectType: thingsType, - Relation: memberRelation, - Permission: adminpermission, - }, - listObjectsRes: &magistrala.ListObjectsRes{ - Policies: []string{validPolicy}, - }, - err: nil, - }, - { - desc: "list objects with invalid token", - token: inValidToken, - listObjectsReq: &magistrala.ListObjectsReq{ - Domain: domainID, - ObjectType: thingsType, - Relation: memberRelation, - Permission: adminpermission, - }, - listObjectsRes: &magistrala.ListObjectsRes{}, - err: svcerr.ErrAuthorization, - }, - } - for _, tc := range cases { - svcCall := svc.On("ListObjects", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(auth.PolicyPage{Policies: tc.listObjectsRes.Policies}, tc.err) - apr, err := client.ListObjects(context.Background(), tc.listObjectsReq) - if apr != nil { - assert.Equal(t, tc.listObjectsRes, apr, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.listObjectsRes, apr)) - } - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) - svcCall.Unset() - } -} - -func TestListAllObjects(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - cases := []struct { - desc string - token string - listAllObjectsReq *magistrala.ListObjectsReq - listAllObjectsRes *magistrala.ListObjectsRes - err error - }{ - { - desc: "list all objects with valid token", - token: validToken, - listAllObjectsReq: &magistrala.ListObjectsReq{ - Domain: domainID, - ObjectType: thingsType, - Relation: memberRelation, - Permission: adminpermission, - }, - listAllObjectsRes: &magistrala.ListObjectsRes{ - Policies: []string{validPolicy}, - }, - err: nil, - }, - { - desc: "list all objects with invalid token", - token: inValidToken, - listAllObjectsReq: &magistrala.ListObjectsReq{ - Domain: domainID, - ObjectType: thingsType, - Relation: memberRelation, - Permission: adminpermission, - }, - listAllObjectsRes: &magistrala.ListObjectsRes{}, - err: svcerr.ErrAuthorization, - }, - } - for _, tc := range cases { - svcCall := svc.On("ListAllObjects", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(auth.PolicyPage{Policies: tc.listAllObjectsRes.Policies}, tc.err) - apr, err := client.ListAllObjects(context.Background(), tc.listAllObjectsReq) - if apr != nil { - assert.Equal(t, tc.listAllObjectsRes, apr, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.listAllObjectsRes, apr)) - } - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) - svcCall.Unset() - } -} - -func TestCountObects(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - cases := []struct { - desc string - token string - countObjectsReq *magistrala.CountObjectsReq - countObjectsRes *magistrala.CountObjectsRes - err error - }{ - { - desc: "count objects with valid token", - token: validToken, - countObjectsReq: &magistrala.CountObjectsReq{ - Domain: domainID, - ObjectType: thingsType, - Relation: memberRelation, - Permission: adminpermission, - }, - countObjectsRes: &magistrala.CountObjectsRes{ - Count: 1, - }, - err: nil, - }, - { - desc: "count objects with invalid token", - token: inValidToken, - countObjectsReq: &magistrala.CountObjectsReq{ - Domain: domainID, - ObjectType: thingsType, - Relation: memberRelation, - Permission: adminpermission, - }, - countObjectsRes: &magistrala.CountObjectsRes{}, - err: svcerr.ErrAuthorization, - }, - } - for _, tc := range cases { - svcCall := svc.On("CountObjects", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.countObjectsRes.Count, tc.err) - apr, err := client.CountObjects(context.Background(), tc.countObjectsReq) - if apr != nil { - assert.Equal(t, tc.countObjectsRes, apr, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.countObjectsRes, apr)) - } - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) - svcCall.Unset() - } -} - -func TestListSubjects(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - cases := []struct { - desc string - token string - listSubjectsReq *magistrala.ListSubjectsReq - listSubjectsRes *magistrala.ListSubjectsRes - err error - }{ - { - desc: "list subjects with valid token", - token: validToken, - listSubjectsReq: &magistrala.ListSubjectsReq{ - Domain: domainID, - SubjectType: usersType, - Relation: memberRelation, - Permission: adminpermission, - }, - listSubjectsRes: &magistrala.ListSubjectsRes{ - Policies: []string{validPolicy}, - }, - err: nil, - }, - { - desc: "list subjects with invalid token", - token: inValidToken, - listSubjectsReq: &magistrala.ListSubjectsReq{ - Domain: domainID, - SubjectType: usersType, - Relation: memberRelation, - Permission: adminpermission, - }, - listSubjectsRes: &magistrala.ListSubjectsRes{}, - err: svcerr.ErrAuthorization, - }, - } - for _, tc := range cases { - svcCall := svc.On("ListSubjects", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(auth.PolicyPage{Policies: tc.listSubjectsRes.Policies}, tc.err) - apr, err := client.ListSubjects(context.Background(), tc.listSubjectsReq) - if apr != nil { - assert.Equal(t, tc.listSubjectsRes, apr, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.listSubjectsRes, apr)) - } - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) - svcCall.Unset() - } -} - -func TestListAllSubjects(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf(`"Unexpected error creating client connection %s"`, err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - cases := []struct { - desc string - token string - listSubjectsReq *magistrala.ListSubjectsReq - listSubjectsRes *magistrala.ListSubjectsRes - err error - }{ - { - desc: "list all subjects with valid token", - token: validToken, - listSubjectsReq: &magistrala.ListSubjectsReq{ - Domain: domainID, - SubjectType: auth.UserType, - Relation: memberRelation, - Permission: adminpermission, - }, - listSubjectsRes: &magistrala.ListSubjectsRes{ - Policies: []string{validPolicy}, - }, - err: nil, - }, - { - desc: "list all subjects with invalid token", - token: inValidToken, - listSubjectsReq: &magistrala.ListSubjectsReq{ - Domain: domainID, - SubjectType: usersType, - Relation: memberRelation, - Permission: adminpermission, - }, - listSubjectsRes: &magistrala.ListSubjectsRes{}, - err: svcerr.ErrAuthorization, - }, - } - for _, tc := range cases { - svcCall := svc.On("ListAllSubjects", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(auth.PolicyPage{Policies: tc.listSubjectsRes.Policies}, tc.err) - apr, err := client.ListAllSubjects(context.Background(), tc.listSubjectsReq) - if apr != nil { - assert.Equal(t, tc.listSubjectsRes, apr, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.listSubjectsRes, apr)) - } - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) - svcCall.Unset() - } -} - -func TestCountSubjects(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - cases := []struct { - desc string - token string - countSubjectsReq *magistrala.CountSubjectsReq - countSubjectsRes *magistrala.CountSubjectsRes - err error - code codes.Code - }{ - { - desc: "count subjects with valid token", - token: validToken, - countSubjectsReq: &magistrala.CountSubjectsReq{ - Domain: domainID, - SubjectType: usersType, - Relation: memberRelation, - Permission: adminpermission, - }, - countSubjectsRes: &magistrala.CountSubjectsRes{ - Count: 1, - }, - code: codes.OK, - err: nil, - }, - { - desc: "count subjects with invalid token", - token: inValidToken, - countSubjectsReq: &magistrala.CountSubjectsReq{ - Domain: domainID, - SubjectType: usersType, - Relation: memberRelation, - Permission: adminpermission, - }, - countSubjectsRes: &magistrala.CountSubjectsRes{}, - err: svcerr.ErrAuthentication, - code: codes.Unauthenticated, - }, - } - for _, tc := range cases { - svcCall := svc.On("CountSubjects", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.countSubjectsRes.Count, tc.err) - apr, err := client.CountSubjects(context.Background(), tc.countSubjectsReq) - if apr != nil { - assert.Equal(t, tc.countSubjectsRes, apr, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.countSubjectsRes, apr)) - } - e, ok := status.FromError(err) - assert.True(t, ok, "gRPC status can't be extracted from the error") - assert.Equal(t, tc.code, e.Code(), fmt.Sprintf("%s: expected %s got %s", tc.desc, tc.code, e.Code())) - svcCall.Unset() - } -} - -func TestListPermissions(t *testing.T) { - conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) - assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) - client := grpcapi.NewPolicyClient(conn, time.Second) - - cases := []struct { - desc string - token string - listPermissionsReq *magistrala.ListPermissionsReq - listPermissionsRes *magistrala.ListPermissionsRes - err error - }{ - { - desc: "list permissions of thing type with valid token", - token: validToken, - listPermissionsReq: &magistrala.ListPermissionsReq{ - Domain: domainID, - SubjectType: auth.UserType, - Subject: id, - ObjectType: auth.ThingType, - Object: validID, - FilterPermissions: []string{"view"}, - }, - listPermissionsRes: &magistrala.ListPermissionsRes{ - SubjectType: auth.UserType, - Subject: id, - ObjectType: auth.ThingType, - Object: validID, - Permissions: []string{"view"}, - }, - err: nil, - }, - { - desc: "list permissions of group type with valid token", - token: validToken, - listPermissionsReq: &magistrala.ListPermissionsReq{ - Domain: domainID, - SubjectType: auth.UserType, - Subject: id, - ObjectType: auth.GroupType, - Object: validID, - FilterPermissions: []string{"view"}, - }, - listPermissionsRes: &magistrala.ListPermissionsRes{ - SubjectType: auth.UserType, - Subject: id, - ObjectType: auth.GroupType, - Object: validID, - Permissions: []string{"view"}, - }, - err: nil, - }, - { - desc: "list permissions of platform type with valid token", - token: validToken, - listPermissionsReq: &magistrala.ListPermissionsReq{ - Domain: domainID, - SubjectType: auth.UserType, - Subject: id, - ObjectType: auth.PlatformType, - Object: validID, - FilterPermissions: []string{"view"}, - }, - listPermissionsRes: &magistrala.ListPermissionsRes{ - SubjectType: auth.UserType, - Subject: id, - ObjectType: auth.PlatformType, - Object: validID, - Permissions: []string{"view"}, - }, - err: nil, - }, - { - desc: "list permissions of domain type with valid token", - token: validToken, - listPermissionsReq: &magistrala.ListPermissionsReq{ - Domain: domainID, - SubjectType: auth.UserType, - Subject: id, - ObjectType: auth.DomainType, - Object: validID, - FilterPermissions: []string{"view"}, - }, - listPermissionsRes: &magistrala.ListPermissionsRes{ - SubjectType: auth.UserType, - Subject: id, - ObjectType: auth.DomainType, - Object: validID, - Permissions: []string{"view"}, - }, - err: nil, - }, - { - desc: "list permissions of thing type with invalid token", - token: inValidToken, - listPermissionsReq: &magistrala.ListPermissionsReq{ - Domain: domainID, - SubjectType: auth.UserType, - Subject: id, - ObjectType: auth.ThingType, - Object: validID, - FilterPermissions: []string{"view"}, - }, - listPermissionsRes: &magistrala.ListPermissionsRes{}, - err: svcerr.ErrAuthentication, - }, - { - desc: "list permissions with invalid object type", - token: validToken, - listPermissionsReq: &magistrala.ListPermissionsReq{ - Domain: domainID, - SubjectType: auth.UserType, - Subject: id, - ObjectType: "invalid", - Object: validID, - }, - listPermissionsRes: &magistrala.ListPermissionsRes{}, - err: apiutil.ErrMalformedPolicy, - }, - } - for _, tc := range cases { - svcCall := svc.On("ListPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(auth.Permissions{"view"}, tc.err) - apr, err := client.ListPermissions(context.Background(), tc.listPermissionsReq) - if apr != nil { - assert.Equal(t, tc.listPermissionsRes, apr, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.listPermissionsRes, apr)) - } - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) - svcCall.Unset() - } -} - -func TestDeleteEntityPolicies(t *testing.T) { +func TestDeleteUserPolicies(t *testing.T) { conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err)) client := grpcapi.NewPolicyClient(conn, time.Second) @@ -1021,33 +351,30 @@ func TestDeleteEntityPolicies(t *testing.T) { cases := []struct { desc string token string - deleteEntityPoliciesReq *magistrala.DeleteEntityPoliciesReq + deleteUserPoliciesReq *magistrala.DeleteUserPoliciesReq deletePolicyRes *magistrala.DeletePolicyRes err error }{ { desc: "delete valid req", token: validToken, - deleteEntityPoliciesReq: &magistrala.DeleteEntityPoliciesReq{ - Id: id, - EntityType: usersType, + deleteUserPoliciesReq: &magistrala.DeleteUserPoliciesReq{ + Id: id, }, deletePolicyRes: &magistrala.DeletePolicyRes{Deleted: true}, err: nil, }, { - desc: "delete invalid req with invalid token", - token: inValidToken, - deleteEntityPoliciesReq: &magistrala.DeleteEntityPoliciesReq{ - EntityType: usersType, - }, - deletePolicyRes: &magistrala.DeletePolicyRes{Deleted: false}, - err: apiutil.ErrMissingID, + desc: "delete invalid req with invalid token", + token: inValidToken, + deleteUserPoliciesReq: &magistrala.DeleteUserPoliciesReq{}, + deletePolicyRes: &magistrala.DeletePolicyRes{Deleted: false}, + err: apiutil.ErrMissingID, }, { desc: "delete invalid req with invalid token", token: inValidToken, - deleteEntityPoliciesReq: &magistrala.DeleteEntityPoliciesReq{ + deleteUserPoliciesReq: &magistrala.DeleteUserPoliciesReq{ Id: id, }, deletePolicyRes: &magistrala.DeletePolicyRes{Deleted: false}, @@ -1055,8 +382,8 @@ func TestDeleteEntityPolicies(t *testing.T) { }, } for _, tc := range cases { - repoCall := svc.On("DeleteEntityPolicies", mock.Anything, tc.deleteEntityPoliciesReq.EntityType, tc.deleteEntityPoliciesReq.Id).Return(tc.err) - dpr, err := client.DeleteEntityPolicies(context.Background(), tc.deleteEntityPoliciesReq) + repoCall := svc.On("DeleteUserPolicies", mock.Anything, tc.deleteUserPoliciesReq.Id).Return(tc.err) + dpr, err := client.DeleteUserPolicies(context.Background(), tc.deleteUserPoliciesReq) assert.Equal(t, tc.deletePolicyRes.GetDeleted(), dpr.GetDeleted(), fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.deletePolicyRes.GetDeleted(), dpr.GetDeleted())) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) repoCall.Unset() diff --git a/auth/api/grpc/requests.go b/auth/api/grpc/requests.go index cc21348f7a..e86ff355e2 100644 --- a/auth/api/grpc/requests.go +++ b/auth/api/grpc/requests.go @@ -81,96 +81,14 @@ func (req authReq) validate() error { return nil } -type policyReq struct { - Domain string - SubjectType string - Subject string - SubjectKind string - Relation string - Permission string - ObjectType string - ObjectKind string - Object string -} - -func (req policyReq) validate() error { - return nil -} - -type policiesReq []policyReq - -func (prs policiesReq) validate() error { - return nil -} - -type listObjectsReq struct { - Domain string - SubjectType string - Subject string - Relation string - Permission string - ObjectType string - Object string - NextPageToken string - Limit uint64 -} - -type countObjectsReq struct { - Domain string - SubjectType string - Subject string - Relation string - Permission string - ObjectType string - Object string - NextPageToken string -} - -type listSubjectsReq struct { - Domain string - SubjectType string - Subject string - Relation string - Permission string - ObjectType string - Object string - NextPageToken string - Limit uint64 +type deleteUserPoliciesReq struct { + ID string } -type countSubjectsReq struct { - Domain string - SubjectType string - Subject string - Relation string - Permission string - ObjectType string - Object string - NextPageToken string -} - -type listPermissionsReq struct { - Domain string - SubjectType string - Subject string - SubjectRelation string - ObjectType string - Object string - FilterPermissions []string -} - -type deleteEntityPoliciesReq struct { - EntityType string - ID string -} - -func (req deleteEntityPoliciesReq) validate() error { +func (req deleteUserPoliciesReq) validate() error { if req.ID == "" { return apiutil.ErrMissingID } - if req.EntityType == "" { - return apiutil.ErrMissingPolicyEntityType - } return nil } diff --git a/auth/api/grpc/responses.go b/auth/api/grpc/responses.go index 8685826e1c..62e16e9251 100644 --- a/auth/api/grpc/responses.go +++ b/auth/api/grpc/responses.go @@ -20,41 +20,6 @@ type authorizeRes struct { authorized bool } -type addPolicyRes struct { - added bool -} -type addPoliciesRes struct { - added bool -} - type deletePolicyRes struct { deleted bool } - -type listObjectsRes struct { - policies []string - nextPageToken string -} - -type countObjectsRes struct { - count uint64 -} - -type listSubjectsRes struct { - policies []string - nextPageToken string -} - -type countSubjectsRes struct { - count uint64 -} - -type listPermissionsRes struct { - Domain string - SubjectType string - Subject string - SubjectRelation string - ObjectType string - Object string - Permissions []string -} diff --git a/auth/api/grpc/server.go b/auth/api/grpc/server.go index 89500bb4ba..d013d6aad2 100644 --- a/auth/api/grpc/server.go +++ b/auth/api/grpc/server.go @@ -100,175 +100,21 @@ func (s *authnGrpcServer) Identify(ctx context.Context, token *magistrala.Identi type policyGrpcServer struct { magistrala.UnimplementedPolicyServiceServer - addPolicy kitgrpc.Handler - addPolicies kitgrpc.Handler - deletePolicyFilter kitgrpc.Handler - deletePolicies kitgrpc.Handler - listObjects kitgrpc.Handler - listAllObjects kitgrpc.Handler - countObjects kitgrpc.Handler - listSubjects kitgrpc.Handler - listAllSubjects kitgrpc.Handler - countSubjects kitgrpc.Handler - listPermissions kitgrpc.Handler - deleteEntityPolicies kitgrpc.Handler + deleteUserPolicies kitgrpc.Handler } func NewPolicyServer(svc auth.Service) magistrala.PolicyServiceServer { return &policyGrpcServer{ - addPolicy: kitgrpc.NewServer( - (addPolicyEndpoint(svc)), - decodeAddPolicyRequest, - encodeAddPolicyResponse, + deleteUserPolicies: kitgrpc.NewServer( + (deleteUserPoliciesEndpoint(svc)), + decodeDeleteUserPoliciesRequest, + encodeDeleteUserPoliciesResponse, ), - addPolicies: kitgrpc.NewServer( - (addPoliciesEndpoint(svc)), - decodeAddPoliciesRequest, - encodeAddPoliciesResponse, - ), - deletePolicyFilter: kitgrpc.NewServer( - (deletePolicyFilterEndpoint(svc)), - decodeDeletePolicyFilterRequest, - encodeDeletePolicyFilterResponse, - ), - deletePolicies: kitgrpc.NewServer( - (deletePoliciesEndpoint(svc)), - decodeDeletePoliciesRequest, - encodeDeletePoliciesResponse, - ), - listObjects: kitgrpc.NewServer( - (listObjectsEndpoint(svc)), - decodeListObjectsRequest, - encodeListObjectsResponse, - ), - listAllObjects: kitgrpc.NewServer( - (listAllObjectsEndpoint(svc)), - decodeListObjectsRequest, - encodeListObjectsResponse, - ), - countObjects: kitgrpc.NewServer( - (countObjectsEndpoint(svc)), - decodeCountObjectsRequest, - encodeCountObjectsResponse, - ), - listSubjects: kitgrpc.NewServer( - (listSubjectsEndpoint(svc)), - decodeListSubjectsRequest, - encodeListSubjectsResponse, - ), - listAllSubjects: kitgrpc.NewServer( - (listAllSubjectsEndpoint(svc)), - decodeListSubjectsRequest, - encodeListSubjectsResponse, - ), - countSubjects: kitgrpc.NewServer( - (countSubjectsEndpoint(svc)), - decodeCountSubjectsRequest, - encodeCountSubjectsResponse, - ), - listPermissions: kitgrpc.NewServer( - (listPermissionsEndpoint(svc)), - decodeListPermissionsRequest, - encodeListPermissionsResponse, - ), - deleteEntityPolicies: kitgrpc.NewServer( - (deleteEntityPoliciesEndpoint(svc)), - decodeDeleteEntityPoliciesRequest, - encodeDeleteEntityPoliciesResponse, - ), - } -} - -func (s *policyGrpcServer) AddPolicy(ctx context.Context, req *magistrala.AddPolicyReq) (*magistrala.AddPolicyRes, error) { - _, res, err := s.addPolicy.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) } - return res.(*magistrala.AddPolicyRes), nil } -func (s *policyGrpcServer) AddPolicies(ctx context.Context, req *magistrala.AddPoliciesReq) (*magistrala.AddPoliciesRes, error) { - _, res, err := s.addPolicies.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*magistrala.AddPoliciesRes), nil -} - -func (s *policyGrpcServer) DeletePolicyFilter(ctx context.Context, req *magistrala.DeletePolicyFilterReq) (*magistrala.DeletePolicyRes, error) { - _, res, err := s.deletePolicyFilter.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*magistrala.DeletePolicyRes), nil -} - -func (s *policyGrpcServer) DeletePolicies(ctx context.Context, req *magistrala.DeletePoliciesReq) (*magistrala.DeletePolicyRes, error) { - _, res, err := s.deletePolicies.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*magistrala.DeletePolicyRes), nil -} - -func (s *policyGrpcServer) ListObjects(ctx context.Context, req *magistrala.ListObjectsReq) (*magistrala.ListObjectsRes, error) { - _, res, err := s.listObjects.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*magistrala.ListObjectsRes), nil -} - -func (s *policyGrpcServer) ListAllObjects(ctx context.Context, req *magistrala.ListObjectsReq) (*magistrala.ListObjectsRes, error) { - _, res, err := s.listAllObjects.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*magistrala.ListObjectsRes), nil -} - -func (s *policyGrpcServer) CountObjects(ctx context.Context, req *magistrala.CountObjectsReq) (*magistrala.CountObjectsRes, error) { - _, res, err := s.countObjects.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*magistrala.CountObjectsRes), nil -} - -func (s *policyGrpcServer) ListSubjects(ctx context.Context, req *magistrala.ListSubjectsReq) (*magistrala.ListSubjectsRes, error) { - _, res, err := s.listSubjects.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*magistrala.ListSubjectsRes), nil -} - -func (s *policyGrpcServer) ListAllSubjects(ctx context.Context, req *magistrala.ListSubjectsReq) (*magistrala.ListSubjectsRes, error) { - _, res, err := s.listAllSubjects.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*magistrala.ListSubjectsRes), nil -} - -func (s *policyGrpcServer) CountSubjects(ctx context.Context, req *magistrala.CountSubjectsReq) (*magistrala.CountSubjectsRes, error) { - _, res, err := s.countSubjects.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*magistrala.CountSubjectsRes), nil -} - -func (s *policyGrpcServer) ListPermissions(ctx context.Context, req *magistrala.ListPermissionsReq) (*magistrala.ListPermissionsRes, error) { - _, res, err := s.listPermissions.ServeGRPC(ctx, req) - if err != nil { - return nil, encodeError(err) - } - return res.(*magistrala.ListPermissionsRes), nil -} - -func (s *policyGrpcServer) DeleteEntityPolicies(ctx context.Context, req *magistrala.DeleteEntityPoliciesReq) (*magistrala.DeletePolicyRes, error) { - _, res, err := s.deleteEntityPolicies.ServeGRPC(ctx, req) +func (s *policyGrpcServer) DeleteUserPolicies(ctx context.Context, req *magistrala.DeleteUserPoliciesReq) (*magistrala.DeletePolicyRes, error) { + _, res, err := s.deleteUserPolicies.ServeGRPC(ctx, req) if err != nil { return nil, encodeError(err) } @@ -328,203 +174,14 @@ func encodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{ return &magistrala.AuthorizeRes{Authorized: res.authorized, Id: res.id}, nil } -func decodeAddPolicyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*magistrala.AddPolicyReq) - return policyReq{ - Domain: req.GetDomain(), - SubjectType: req.GetSubjectType(), - SubjectKind: req.GetSubjectKind(), - Subject: req.GetSubject(), - Relation: req.GetRelation(), - Permission: req.GetPermission(), - ObjectType: req.GetObjectType(), - ObjectKind: req.GetObjectKind(), - Object: req.GetObject(), - }, nil -} - -func encodeAddPolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(addPolicyRes) - return &magistrala.AddPolicyRes{Added: res.added}, nil -} - -func decodeAddPoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - reqs := grpcReq.(*magistrala.AddPoliciesReq) - r := policiesReq{} - for _, req := range reqs.AddPoliciesReq { - r = append(r, policyReq{ - Domain: req.GetDomain(), - SubjectType: req.GetSubjectType(), - SubjectKind: req.GetSubjectKind(), - Subject: req.GetSubject(), - Relation: req.GetRelation(), - Permission: req.GetPermission(), - ObjectType: req.GetObjectType(), - ObjectKind: req.GetObjectKind(), - Object: req.GetObject(), - }) - } - return r, nil -} - -func encodeAddPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(addPoliciesRes) - return &magistrala.AddPoliciesRes{Added: res.added}, nil -} - -func decodeDeletePolicyFilterRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*magistrala.DeletePolicyFilterReq) - return policyReq{ - Domain: req.GetDomain(), - SubjectType: req.GetSubjectType(), - SubjectKind: req.GetSubjectKind(), - Subject: req.GetSubject(), - Relation: req.GetRelation(), - Permission: req.GetPermission(), - ObjectType: req.GetObjectType(), - ObjectKind: req.GetObjectKind(), - Object: req.GetObject(), - }, nil -} - -func encodeDeletePolicyFilterResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(deletePolicyRes) - return &magistrala.DeletePolicyRes{Deleted: res.deleted}, nil -} - -func decodeDeletePoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - reqs := grpcReq.(*magistrala.DeletePoliciesReq) - r := policiesReq{} - for _, req := range reqs.DeletePoliciesReq { - r = append(r, policyReq{ - Domain: req.GetDomain(), - SubjectType: req.GetSubjectType(), - SubjectKind: req.GetSubjectKind(), - Subject: req.GetSubject(), - Relation: req.GetRelation(), - Permission: req.GetPermission(), - ObjectType: req.GetObjectType(), - ObjectKind: req.GetObjectKind(), - Object: req.GetObject(), - }) - } - return r, nil -} - -func encodeDeletePoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(deletePolicyRes) - return &magistrala.DeletePolicyRes{Deleted: res.deleted}, nil -} - -func decodeListObjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*magistrala.ListObjectsReq) - return listObjectsReq{ - Domain: req.GetDomain(), - SubjectType: req.GetSubjectType(), - Subject: req.GetSubject(), - Relation: req.GetRelation(), - Permission: req.GetPermission(), - ObjectType: req.GetObjectType(), - Object: req.GetObject(), - NextPageToken: req.GetNextPageToken(), - Limit: req.GetLimit(), - }, nil -} - -func encodeListObjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(listObjectsRes) - return &magistrala.ListObjectsRes{Policies: res.policies}, nil -} - -func decodeCountObjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*magistrala.CountObjectsReq) - return countObjectsReq{ - Domain: req.GetDomain(), - SubjectType: req.GetSubjectType(), - Subject: req.GetSubject(), - Relation: req.GetRelation(), - Permission: req.GetPermission(), - ObjectType: req.GetObjectType(), - Object: req.GetObject(), - }, nil -} - -func encodeCountObjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(countObjectsRes) - return &magistrala.CountObjectsRes{Count: res.count}, nil -} - -func decodeListSubjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*magistrala.ListSubjectsReq) - return listSubjectsReq{ - Domain: req.GetDomain(), - SubjectType: req.GetSubjectType(), - Subject: req.GetSubject(), - Relation: req.GetRelation(), - Permission: req.GetPermission(), - ObjectType: req.GetObjectType(), - Object: req.GetObject(), NextPageToken: req.GetNextPageToken(), Limit: req.GetLimit(), - }, nil -} - -func encodeListSubjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(listSubjectsRes) - return &magistrala.ListSubjectsRes{Policies: res.policies}, nil -} - -func decodeCountSubjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*magistrala.CountSubjectsReq) - return countSubjectsReq{ - Domain: req.GetDomain(), - SubjectType: req.GetSubjectType(), - Subject: req.GetSubject(), - Relation: req.GetRelation(), - Permission: req.GetPermission(), - ObjectType: req.GetObjectType(), - Object: req.GetObject(), - }, nil -} - -func encodeCountSubjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(countSubjectsRes) - return &magistrala.CountSubjectsRes{Count: res.count}, nil -} - -func decodeListPermissionsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*magistrala.ListPermissionsReq) - return listPermissionsReq{ - Domain: req.GetDomain(), - SubjectType: req.GetSubjectType(), - Subject: req.GetSubject(), - SubjectRelation: req.GetSubjectRelation(), - ObjectType: req.GetObjectType(), - Object: req.GetObject(), - FilterPermissions: req.GetFilterPermissions(), - }, nil -} - -func encodeListPermissionsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { - res := grpcRes.(listPermissionsRes) - return &magistrala.ListPermissionsRes{ - Domain: res.Domain, - SubjectType: res.SubjectType, - Subject: res.Subject, - SubjectRelation: res.SubjectRelation, - ObjectType: res.ObjectType, - Object: res.Object, - Permissions: res.Permissions, - }, nil -} - -func decodeDeleteEntityPoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { - req := grpcReq.(*magistrala.DeleteEntityPoliciesReq) - return deleteEntityPoliciesReq{ - EntityType: req.GetEntityType(), - ID: req.GetId(), +func decodeDeleteUserPoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) { + req := grpcReq.(*magistrala.DeleteUserPoliciesReq) + return deleteUserPoliciesReq{ + ID: req.GetId(), }, nil } -func encodeDeleteEntityPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { +func encodeDeleteUserPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) { res := grpcRes.(deletePolicyRes) return &magistrala.DeletePolicyRes{Deleted: res.deleted}, nil } diff --git a/auth/api/http/keys/endpoint_test.go b/auth/api/http/keys/endpoint_test.go index f200f9f5ee..60c17c8d73 100644 --- a/auth/api/http/keys/endpoint_test.go +++ b/auth/api/http/keys/endpoint_test.go @@ -21,6 +21,7 @@ import ( mglog "github.com/absmach/magistrala/logger" "github.com/absmach/magistrala/pkg/apiutil" svcerr "github.com/absmach/magistrala/pkg/errors/service" + policymocks "github.com/absmach/magistrala/pkg/policy/mocks" "github.com/absmach/magistrala/pkg/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -71,10 +72,11 @@ func newService() (auth.Service, *mocks.KeyRepository) { prepo := new(mocks.PolicyAgent) drepo := new(mocks.DomainsRepository) idProvider := uuid.NewMock() + policy := new(policymocks.PolicyClient) t := jwt.New([]byte(secret)) - return auth.New(krepo, drepo, idProvider, t, prepo, loginDuration, refreshDuration, invalidDuration), krepo + return auth.New(krepo, drepo, idProvider, t, prepo, policy, loginDuration, refreshDuration, invalidDuration), krepo } func newServer(svc auth.Service) *httptest.Server { diff --git a/auth/api/logging.go b/auth/api/logging.go index 7240af2d27..61847270a5 100644 --- a/auth/api/logging.go +++ b/auth/api/logging.go @@ -7,11 +7,11 @@ package api import ( "context" - "fmt" "log/slog" "time" "github.com/absmach/magistrala/auth" + "github.com/absmach/magistrala/pkg/policy" ) var _ auth.Service = (*loggingMiddleware)(nil) @@ -26,136 +26,6 @@ func LoggingMiddleware(svc auth.Service, logger *slog.Logger) auth.Service { return &loggingMiddleware{logger, svc} } -func (lm *loggingMiddleware) ListObjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (p auth.PolicyPage, err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - slog.Int64("limit", int64(limit)), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn("List objects failed", args...) - return - } - lm.logger.Info("List objects completed successfully", args...) - }(time.Now()) - - return lm.svc.ListObjects(ctx, pr, nextPageToken, limit) -} - -func (lm *loggingMiddleware) ListAllObjects(ctx context.Context, pr auth.PolicyReq) (p auth.PolicyPage, err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - slog.Group("policy_request", - slog.String("object_type", pr.ObjectType), - slog.String("subject_id", pr.Subject), - slog.String("subject_type", pr.SubjectType), - slog.String("permission", pr.Permission), - ), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn("List all objects failed", args...) - return - } - lm.logger.Info("List all objects completed successfully", args...) - }(time.Now()) - - return lm.svc.ListAllObjects(ctx, pr) -} - -func (lm *loggingMiddleware) CountObjects(ctx context.Context, pr auth.PolicyReq) (count uint64, err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn("Count objects failed", args...) - return - } - lm.logger.Info("Count objects completed successfully", args...) - }(time.Now()) - return lm.svc.CountObjects(ctx, pr) -} - -func (lm *loggingMiddleware) ListSubjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (p auth.PolicyPage, err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn("List subjects failed", args...) - return - } - lm.logger.Info("List subjects completed successfully", args...) - }(time.Now()) - - return lm.svc.ListSubjects(ctx, pr, nextPageToken, limit) -} - -func (lm *loggingMiddleware) ListAllSubjects(ctx context.Context, pr auth.PolicyReq) (p auth.PolicyPage, err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - slog.Group("policy_request", - slog.String("sybject_type", pr.SubjectType), - slog.String("object_id", pr.Object), - slog.String("object_type", pr.ObjectType), - slog.String("permission", pr.Permission), - ), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn("List all subjects failed", args...) - return - } - lm.logger.Info("List all subjects completed successfully", args...) - }(time.Now()) - - return lm.svc.ListAllSubjects(ctx, pr) -} - -func (lm *loggingMiddleware) CountSubjects(ctx context.Context, pr auth.PolicyReq) (count uint64, err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn("Count subjects failed", args...) - return - } - lm.logger.Info("Count subjects completed successfully", args...) - }(time.Now()) - return lm.svc.CountSubjects(ctx, pr) -} - -func (lm *loggingMiddleware) ListPermissions(ctx context.Context, pr auth.PolicyReq, filterPermissions []string) (p auth.Permissions, err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - slog.Any("filter_permissions", filterPermissions), - slog.Group("policy_request", - slog.String("object_id", pr.Object), - slog.String("object_type", pr.ObjectType), - slog.String("subject_id", pr.Subject), - slog.String("subject_type", pr.SubjectType), - ), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn("List permissions failed", args...) - return - } - lm.logger.Info("List permissions completed successfully", args...) - }(time.Now()) - - return lm.svc.ListPermissions(ctx, pr, filterPermissions) -} - func (lm *loggingMiddleware) Issue(ctx context.Context, token string, key auth.Key) (tkn auth.Token, err error) { defer func(begin time.Time) { args := []any{ @@ -255,81 +125,6 @@ func (lm *loggingMiddleware) Authorize(ctx context.Context, pr auth.PolicyReq) ( return lm.svc.Authorize(ctx, pr) } -func (lm *loggingMiddleware) AddPolicy(ctx context.Context, pr auth.PolicyReq) (err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - slog.Group("policy_request", - slog.String("object_id", pr.Object), - slog.String("object_type", pr.ObjectType), - slog.String("subject_id", pr.Subject), - slog.String("subject_type", pr.SubjectType), - slog.String("relation", pr.Relation), - ), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn("Add policy failed", args...) - return - } - lm.logger.Info("Add policy completed successfully", args...) - }(time.Now()) - return lm.svc.AddPolicy(ctx, pr) -} - -func (lm *loggingMiddleware) AddPolicies(ctx context.Context, prs []auth.PolicyReq) (err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn(fmt.Sprintf("Add %d policies failed", len(prs)), args...) - return - } - lm.logger.Info(fmt.Sprintf("Add %d policies completed successfully", len(prs)), args...) - }(time.Now()) - - return lm.svc.AddPolicies(ctx, prs) -} - -func (lm *loggingMiddleware) DeletePolicyFilter(ctx context.Context, pr auth.PolicyReq) (err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - slog.Group("policy_request", - slog.String("object_id", pr.Object), - slog.String("object_type", pr.ObjectType), - slog.String("subject_id", pr.Subject), - slog.String("subject_type", pr.SubjectType), - slog.String("relation", pr.Relation), - ), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn("Delete policy filter failed", args...) - return - } - lm.logger.Info("Delete policy filter completed successfully", args...) - }(time.Now()) - return lm.svc.DeletePolicyFilter(ctx, pr) -} - -func (lm *loggingMiddleware) DeletePolicies(ctx context.Context, prs []auth.PolicyReq) (err error) { - defer func(begin time.Time) { - args := []any{ - slog.String("duration", time.Since(begin).String()), - } - if err != nil { - args = append(args, slog.Any("error", err)) - lm.logger.Warn(fmt.Sprintf("Delete %d policies failed", len(prs)), args...) - return - } - lm.logger.Info(fmt.Sprintf("Delete %d policies completed successfully", len(prs)), args...) - }(time.Now()) - return lm.svc.DeletePolicies(ctx, prs) -} - func (lm *loggingMiddleware) CreateDomain(ctx context.Context, token string, d auth.Domain) (do auth.Domain, err error) { defer func(begin time.Time) { args := []any{ @@ -365,7 +160,7 @@ func (lm *loggingMiddleware) RetrieveDomain(ctx context.Context, token, id strin return lm.svc.RetrieveDomain(ctx, token, id) } -func (lm *loggingMiddleware) RetrieveDomainPermissions(ctx context.Context, token, id string) (permissions auth.Permissions, err error) { +func (lm *loggingMiddleware) RetrieveDomainPermissions(ctx context.Context, token, id string) (permissions policy.Permissions, err error) { defer func(begin time.Time) { args := []any{ slog.String("duration", time.Since(begin).String()), @@ -491,11 +286,10 @@ func (lm *loggingMiddleware) ListUserDomains(ctx context.Context, token, userID return lm.svc.ListUserDomains(ctx, token, userID, page) } -func (lm *loggingMiddleware) DeleteEntityPolicies(ctx context.Context, entityType, id string) (err error) { +func (lm *loggingMiddleware) DeleteUserPolicies(ctx context.Context, id string) (err error) { defer func(begin time.Time) { args := []any{ slog.String("duration", time.Since(begin).String()), - slog.String("entity_type", entityType), slog.String("id", id), } if err != nil { @@ -505,5 +299,5 @@ func (lm *loggingMiddleware) DeleteEntityPolicies(ctx context.Context, entityTyp } lm.logger.Info("Delete entity policies completed successfully", args...) }(time.Now()) - return lm.svc.DeleteEntityPolicies(ctx, entityType, id) + return lm.svc.DeleteUserPolicies(ctx, id) } diff --git a/auth/api/metrics.go b/auth/api/metrics.go index 8ed201a82d..775abe21b3 100644 --- a/auth/api/metrics.go +++ b/auth/api/metrics.go @@ -10,6 +10,7 @@ import ( "time" "github.com/absmach/magistrala/auth" + "github.com/absmach/magistrala/pkg/policy" "github.com/go-kit/kit/metrics" ) @@ -30,67 +31,6 @@ func MetricsMiddleware(svc auth.Service, counter metrics.Counter, latency metric } } -func (ms *metricsMiddleware) ListObjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (p auth.PolicyPage, err error) { - defer func(begin time.Time) { - ms.counter.With("method", "list_objects").Add(1) - ms.latency.With("method", "list_objects").Observe(time.Since(begin).Seconds()) - }(time.Now()) - - return ms.svc.ListObjects(ctx, pr, nextPageToken, limit) -} - -func (ms *metricsMiddleware) ListAllObjects(ctx context.Context, pr auth.PolicyReq) (p auth.PolicyPage, err error) { - defer func(begin time.Time) { - ms.counter.With("method", "list_all_objects").Add(1) - ms.latency.With("method", "list_all_objects").Observe(time.Since(begin).Seconds()) - }(time.Now()) - - return ms.svc.ListAllObjects(ctx, pr) -} - -func (ms *metricsMiddleware) CountObjects(ctx context.Context, pr auth.PolicyReq) (count uint64, err error) { - defer func(begin time.Time) { - ms.counter.With("method", "count_objects").Add(1) - ms.latency.With("method", "count_objects").Observe(time.Since(begin).Seconds()) - }(time.Now()) - return ms.svc.CountObjects(ctx, pr) -} - -func (ms *metricsMiddleware) ListSubjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (p auth.PolicyPage, err error) { - defer func(begin time.Time) { - ms.counter.With("method", "list_subjects").Add(1) - ms.latency.With("method", "list_subjects").Observe(time.Since(begin).Seconds()) - }(time.Now()) - - return ms.svc.ListSubjects(ctx, pr, nextPageToken, limit) -} - -func (ms *metricsMiddleware) ListAllSubjects(ctx context.Context, pr auth.PolicyReq) (p auth.PolicyPage, err error) { - defer func(begin time.Time) { - ms.counter.With("method", "list_all_subjects").Add(1) - ms.latency.With("method", "list_all_subjects").Observe(time.Since(begin).Seconds()) - }(time.Now()) - - return ms.svc.ListAllSubjects(ctx, pr) -} - -func (ms *metricsMiddleware) CountSubjects(ctx context.Context, pr auth.PolicyReq) (count uint64, err error) { - defer func(begin time.Time) { - ms.counter.With("method", "count_subjects").Add(1) - ms.latency.With("method", "count_subjects").Observe(time.Since(begin).Seconds()) - }(time.Now()) - return ms.svc.CountSubjects(ctx, pr) -} - -func (ms *metricsMiddleware) ListPermissions(ctx context.Context, pr auth.PolicyReq, filterPermissions []string) (p auth.Permissions, err error) { - defer func(begin time.Time) { - ms.counter.With("method", "list_permissions").Add(1) - ms.latency.With("method", "list_permissions").Observe(time.Since(begin).Seconds()) - }(time.Now()) - - return ms.svc.ListPermissions(ctx, pr, filterPermissions) -} - func (ms *metricsMiddleware) Issue(ctx context.Context, token string, key auth.Key) (auth.Token, error) { defer func(begin time.Time) { ms.counter.With("method", "issue_key").Add(1) @@ -135,39 +75,6 @@ func (ms *metricsMiddleware) Authorize(ctx context.Context, pr auth.PolicyReq) e return ms.svc.Authorize(ctx, pr) } -func (ms *metricsMiddleware) AddPolicy(ctx context.Context, pr auth.PolicyReq) error { - defer func(begin time.Time) { - ms.counter.With("method", "add_policy").Add(1) - ms.latency.With("method", "add_policy").Observe(time.Since(begin).Seconds()) - }(time.Now()) - return ms.svc.AddPolicy(ctx, pr) -} - -func (ms *metricsMiddleware) AddPolicies(ctx context.Context, prs []auth.PolicyReq) (err error) { - defer func(begin time.Time) { - ms.counter.With("method", "create_policy_bulk").Add(1) - ms.latency.With("method", "create_policy_bulk").Observe(time.Since(begin).Seconds()) - }(time.Now()) - - return ms.svc.AddPolicies(ctx, prs) -} - -func (ms *metricsMiddleware) DeletePolicyFilter(ctx context.Context, pr auth.PolicyReq) error { - defer func(begin time.Time) { - ms.counter.With("method", "delete_policy_filter").Add(1) - ms.latency.With("method", "delete_policy_filter").Observe(time.Since(begin).Seconds()) - }(time.Now()) - return ms.svc.DeletePolicyFilter(ctx, pr) -} - -func (ms *metricsMiddleware) DeletePolicies(ctx context.Context, prs []auth.PolicyReq) error { - defer func(begin time.Time) { - ms.counter.With("method", "delete_policies").Add(1) - ms.latency.With("method", "delete_policies").Observe(time.Since(begin).Seconds()) - }(time.Now()) - return ms.svc.DeletePolicies(ctx, prs) -} - func (ms *metricsMiddleware) CreateDomain(ctx context.Context, token string, d auth.Domain) (auth.Domain, error) { defer func(begin time.Time) { ms.counter.With("method", "create_domain").Add(1) @@ -184,7 +91,7 @@ func (ms *metricsMiddleware) RetrieveDomain(ctx context.Context, token, id strin return ms.svc.RetrieveDomain(ctx, token, id) } -func (ms *metricsMiddleware) RetrieveDomainPermissions(ctx context.Context, token, id string) (auth.Permissions, error) { +func (ms *metricsMiddleware) RetrieveDomainPermissions(ctx context.Context, token, id string) (policy.Permissions, error) { defer func(begin time.Time) { ms.counter.With("method", "retrieve_domain_permissions").Add(1) ms.latency.With("method", "retrieve_domain_permissions").Observe(time.Since(begin).Seconds()) @@ -240,10 +147,10 @@ func (ms *metricsMiddleware) ListUserDomains(ctx context.Context, token, userID return ms.svc.ListUserDomains(ctx, token, userID, page) } -func (ms *metricsMiddleware) DeleteEntityPolicies(ctx context.Context, entityType, id string) error { +func (ms *metricsMiddleware) DeleteUserPolicies(ctx context.Context, id string) error { defer func(begin time.Time) { ms.counter.With("method", "delete_entity_policies").Add(1) ms.latency.With("method", "delete_entity_policies").Observe(time.Since(begin).Seconds()) }(time.Now()) - return ms.svc.DeleteEntityPolicies(ctx, entityType, id) + return ms.svc.DeleteUserPolicies(ctx, id) } diff --git a/auth/domains.go b/auth/domains.go index 13fc4f6286..0aae2e8196 100644 --- a/auth/domains.go +++ b/auth/domains.go @@ -11,6 +11,7 @@ import ( "github.com/absmach/magistrala/pkg/clients" svcerr "github.com/absmach/magistrala/pkg/errors/service" + "github.com/absmach/magistrala/pkg/policy" ) // Status represents Domain status. @@ -157,7 +158,7 @@ type Policy struct { type Domains interface { CreateDomain(ctx context.Context, token string, d Domain) (Domain, error) RetrieveDomain(ctx context.Context, token string, id string) (Domain, error) - RetrieveDomainPermissions(ctx context.Context, token string, id string) (Permissions, error) + RetrieveDomainPermissions(ctx context.Context, token string, id string) (policy.Permissions, error) UpdateDomain(ctx context.Context, token string, id string, d DomainReq) (Domain, error) ChangeDomainStatus(ctx context.Context, token string, id string, d DomainReq) (Domain, error) ListDomains(ctx context.Context, token string, page Page) (DomainsPage, error) diff --git a/auth/events/events.go b/auth/events/events.go index b8714298fb..caa09bd40f 100644 --- a/auth/events/events.go +++ b/auth/events/events.go @@ -8,6 +8,7 @@ import ( "github.com/absmach/magistrala/auth" "github.com/absmach/magistrala/pkg/events" + "github.com/absmach/magistrala/pkg/policy" ) const ( @@ -99,7 +100,7 @@ func (rde retrieveDomainEvent) Encode() (map[string]interface{}, error) { type retrieveDomainPermissionsEvent struct { domainID string - permissions auth.Permissions + permissions policy.Permissions } func (rpe retrieveDomainPermissionsEvent) Encode() (map[string]interface{}, error) { diff --git a/auth/events/streams.go b/auth/events/streams.go index 0081a962fa..71bbad140a 100644 --- a/auth/events/streams.go +++ b/auth/events/streams.go @@ -9,6 +9,7 @@ import ( "github.com/absmach/magistrala/auth" "github.com/absmach/magistrala/pkg/events" "github.com/absmach/magistrala/pkg/events/store" + "github.com/absmach/magistrala/pkg/policy" ) const streamID = "magistrala.auth" @@ -68,7 +69,7 @@ func (es *eventStore) RetrieveDomain(ctx context.Context, token, id string) (aut return domain, nil } -func (es *eventStore) RetrieveDomainPermissions(ctx context.Context, token, id string) (auth.Permissions, error) { +func (es *eventStore) RetrieveDomainPermissions(ctx context.Context, token, id string) (policy.Permissions, error) { permissions, err := es.svc.RetrieveDomainPermissions(ctx, token, id) if err != nil { return permissions, err @@ -215,50 +216,6 @@ func (es *eventStore) Authorize(ctx context.Context, pr auth.PolicyReq) error { return es.svc.Authorize(ctx, pr) } -func (es *eventStore) AddPolicy(ctx context.Context, pr auth.PolicyReq) error { - return es.svc.AddPolicy(ctx, pr) -} - -func (es *eventStore) AddPolicies(ctx context.Context, prs []auth.PolicyReq) error { - return es.svc.AddPolicies(ctx, prs) -} - -func (es *eventStore) DeletePolicyFilter(ctx context.Context, pr auth.PolicyReq) error { - return es.svc.DeletePolicyFilter(ctx, pr) -} - -func (es *eventStore) DeleteEntityPolicies(ctx context.Context, entityType, id string) error { - return es.svc.DeleteEntityPolicies(ctx, entityType, id) -} - -func (es *eventStore) DeletePolicies(ctx context.Context, prs []auth.PolicyReq) error { - return es.svc.DeletePolicies(ctx, prs) -} - -func (es *eventStore) ListObjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (auth.PolicyPage, error) { - return es.svc.ListObjects(ctx, pr, nextPageToken, limit) -} - -func (es *eventStore) ListAllObjects(ctx context.Context, pr auth.PolicyReq) (auth.PolicyPage, error) { - return es.svc.ListAllObjects(ctx, pr) -} - -func (es *eventStore) CountObjects(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - return es.svc.CountObjects(ctx, pr) -} - -func (es *eventStore) ListSubjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (auth.PolicyPage, error) { - return es.svc.ListSubjects(ctx, pr, nextPageToken, limit) -} - -func (es *eventStore) ListAllSubjects(ctx context.Context, pr auth.PolicyReq) (auth.PolicyPage, error) { - return es.svc.ListAllSubjects(ctx, pr) -} - -func (es *eventStore) CountSubjects(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - return es.svc.CountSubjects(ctx, pr) -} - -func (es *eventStore) ListPermissions(ctx context.Context, pr auth.PolicyReq, filterPermission []string) (auth.Permissions, error) { - return es.svc.ListPermissions(ctx, pr, filterPermission) +func (es *eventStore) DeleteUserPolicies(ctx context.Context, id string) error { + return es.svc.DeleteUserPolicies(ctx, id) } diff --git a/auth/mocks/agent.go b/auth/mocks/agent.go index 160a661221..b0386d0ccd 100644 --- a/auth/mocks/agent.go +++ b/auth/mocks/agent.go @@ -17,42 +17,6 @@ type PolicyAgent struct { mock.Mock } -// AddPolicies provides a mock function with given fields: ctx, prs -func (_m *PolicyAgent) AddPolicies(ctx context.Context, prs []auth.PolicyReq) error { - ret := _m.Called(ctx, prs) - - if len(ret) == 0 { - panic("no return value specified for AddPolicies") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []auth.PolicyReq) error); ok { - r0 = rf(ctx, prs) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// AddPolicy provides a mock function with given fields: ctx, pr -func (_m *PolicyAgent) AddPolicy(ctx context.Context, pr auth.PolicyReq) error { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for AddPolicy") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) error); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // CheckPolicy provides a mock function with given fields: ctx, pr func (_m *PolicyAgent) CheckPolicy(ctx context.Context, pr auth.PolicyReq) error { ret := _m.Called(ctx, pr) @@ -71,262 +35,6 @@ func (_m *PolicyAgent) CheckPolicy(ctx context.Context, pr auth.PolicyReq) error return r0 } -// DeletePolicies provides a mock function with given fields: ctx, pr -func (_m *PolicyAgent) DeletePolicies(ctx context.Context, pr []auth.PolicyReq) error { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for DeletePolicies") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []auth.PolicyReq) error); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// DeletePolicyFilter provides a mock function with given fields: ctx, pr -func (_m *PolicyAgent) DeletePolicyFilter(ctx context.Context, pr auth.PolicyReq) error { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for DeletePolicyFilter") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) error); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// RetrieveAllObjects provides a mock function with given fields: ctx, pr -func (_m *PolicyAgent) RetrieveAllObjects(ctx context.Context, pr auth.PolicyReq) ([]auth.PolicyRes, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for RetrieveAllObjects") - } - - var r0 []auth.PolicyRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) ([]auth.PolicyRes, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) []auth.PolicyRes); ok { - r0 = rf(ctx, pr) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]auth.PolicyRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RetrieveAllObjectsCount provides a mock function with given fields: ctx, pr -func (_m *PolicyAgent) RetrieveAllObjectsCount(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for RetrieveAllObjectsCount") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) (uint64, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) uint64); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RetrieveAllSubjects provides a mock function with given fields: ctx, pr -func (_m *PolicyAgent) RetrieveAllSubjects(ctx context.Context, pr auth.PolicyReq) ([]auth.PolicyRes, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for RetrieveAllSubjects") - } - - var r0 []auth.PolicyRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) ([]auth.PolicyRes, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) []auth.PolicyRes); ok { - r0 = rf(ctx, pr) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]auth.PolicyRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RetrieveAllSubjectsCount provides a mock function with given fields: ctx, pr -func (_m *PolicyAgent) RetrieveAllSubjectsCount(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for RetrieveAllSubjectsCount") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) (uint64, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) uint64); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RetrieveObjects provides a mock function with given fields: ctx, pr, nextPageToken, limit -func (_m *PolicyAgent) RetrieveObjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) ([]auth.PolicyRes, string, error) { - ret := _m.Called(ctx, pr, nextPageToken, limit) - - if len(ret) == 0 { - panic("no return value specified for RetrieveObjects") - } - - var r0 []auth.PolicyRes - var r1 string - var r2 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) ([]auth.PolicyRes, string, error)); ok { - return rf(ctx, pr, nextPageToken, limit) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) []auth.PolicyRes); ok { - r0 = rf(ctx, pr, nextPageToken, limit) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]auth.PolicyRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq, string, uint64) string); ok { - r1 = rf(ctx, pr, nextPageToken, limit) - } else { - r1 = ret.Get(1).(string) - } - - if rf, ok := ret.Get(2).(func(context.Context, auth.PolicyReq, string, uint64) error); ok { - r2 = rf(ctx, pr, nextPageToken, limit) - } else { - r2 = ret.Error(2) - } - - return r0, r1, r2 -} - -// RetrievePermissions provides a mock function with given fields: ctx, pr, filterPermission -func (_m *PolicyAgent) RetrievePermissions(ctx context.Context, pr auth.PolicyReq, filterPermission []string) (auth.Permissions, error) { - ret := _m.Called(ctx, pr, filterPermission) - - if len(ret) == 0 { - panic("no return value specified for RetrievePermissions") - } - - var r0 auth.Permissions - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, []string) (auth.Permissions, error)); ok { - return rf(ctx, pr, filterPermission) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, []string) auth.Permissions); ok { - r0 = rf(ctx, pr, filterPermission) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(auth.Permissions) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq, []string) error); ok { - r1 = rf(ctx, pr, filterPermission) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RetrieveSubjects provides a mock function with given fields: ctx, pr, nextPageToken, limit -func (_m *PolicyAgent) RetrieveSubjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) ([]auth.PolicyRes, string, error) { - ret := _m.Called(ctx, pr, nextPageToken, limit) - - if len(ret) == 0 { - panic("no return value specified for RetrieveSubjects") - } - - var r0 []auth.PolicyRes - var r1 string - var r2 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) ([]auth.PolicyRes, string, error)); ok { - return rf(ctx, pr, nextPageToken, limit) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) []auth.PolicyRes); ok { - r0 = rf(ctx, pr, nextPageToken, limit) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]auth.PolicyRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq, string, uint64) string); ok { - r1 = rf(ctx, pr, nextPageToken, limit) - } else { - r1 = ret.Get(1).(string) - } - - if rf, ok := ret.Get(2).(func(context.Context, auth.PolicyReq, string, uint64) error); ok { - r2 = rf(ctx, pr, nextPageToken, limit) - } else { - r2 = ret.Error(2) - } - - return r0, r1, r2 -} - // NewPolicyAgent creates a new instance of PolicyAgent. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewPolicyAgent(t interface { diff --git a/auth/mocks/authz.go b/auth/mocks/authz.go index 0e3991597e..ab15adff93 100644 --- a/auth/mocks/authz.go +++ b/auth/mocks/authz.go @@ -17,42 +17,6 @@ type Authz struct { mock.Mock } -// AddPolicies provides a mock function with given fields: ctx, prs -func (_m *Authz) AddPolicies(ctx context.Context, prs []auth.PolicyReq) error { - ret := _m.Called(ctx, prs) - - if len(ret) == 0 { - panic("no return value specified for AddPolicies") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []auth.PolicyReq) error); ok { - r0 = rf(ctx, prs) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// AddPolicy provides a mock function with given fields: ctx, pr -func (_m *Authz) AddPolicy(ctx context.Context, pr auth.PolicyReq) error { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for AddPolicy") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) error); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // Authorize provides a mock function with given fields: ctx, pr func (_m *Authz) Authorize(ctx context.Context, pr auth.PolicyReq) error { ret := _m.Called(ctx, pr) @@ -71,91 +35,17 @@ func (_m *Authz) Authorize(ctx context.Context, pr auth.PolicyReq) error { return r0 } -// CountObjects provides a mock function with given fields: ctx, pr -func (_m *Authz) CountObjects(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - ret := _m.Called(ctx, pr) +// DeleteUserPolicies provides a mock function with given fields: ctx, id +func (_m *Authz) DeleteUserPolicies(ctx context.Context, id string) error { + ret := _m.Called(ctx, id) if len(ret) == 0 { - panic("no return value specified for CountObjects") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) (uint64, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) uint64); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CountSubjects provides a mock function with given fields: ctx, pr -func (_m *Authz) CountSubjects(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for CountSubjects") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) (uint64, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) uint64); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteEntityPolicies provides a mock function with given fields: ctx, entityType, id -func (_m *Authz) DeleteEntityPolicies(ctx context.Context, entityType string, id string) error { - ret := _m.Called(ctx, entityType, id) - - if len(ret) == 0 { - panic("no return value specified for DeleteEntityPolicies") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { - r0 = rf(ctx, entityType, id) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// DeletePolicies provides a mock function with given fields: ctx, prs -func (_m *Authz) DeletePolicies(ctx context.Context, prs []auth.PolicyReq) error { - ret := _m.Called(ctx, prs) - - if len(ret) == 0 { - panic("no return value specified for DeletePolicies") + panic("no return value specified for DeleteUserPolicies") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []auth.PolicyReq) error); ok { - r0 = rf(ctx, prs) + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, id) } else { r0 = ret.Error(0) } @@ -163,166 +53,6 @@ func (_m *Authz) DeletePolicies(ctx context.Context, prs []auth.PolicyReq) error return r0 } -// DeletePolicyFilter provides a mock function with given fields: ctx, pr -func (_m *Authz) DeletePolicyFilter(ctx context.Context, pr auth.PolicyReq) error { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for DeletePolicyFilter") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) error); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ListAllObjects provides a mock function with given fields: ctx, pr -func (_m *Authz) ListAllObjects(ctx context.Context, pr auth.PolicyReq) (auth.PolicyPage, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for ListAllObjects") - } - - var r0 auth.PolicyPage - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) (auth.PolicyPage, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) auth.PolicyPage); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Get(0).(auth.PolicyPage) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListAllSubjects provides a mock function with given fields: ctx, pr -func (_m *Authz) ListAllSubjects(ctx context.Context, pr auth.PolicyReq) (auth.PolicyPage, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for ListAllSubjects") - } - - var r0 auth.PolicyPage - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) (auth.PolicyPage, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) auth.PolicyPage); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Get(0).(auth.PolicyPage) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListObjects provides a mock function with given fields: ctx, pr, nextPageToken, limit -func (_m *Authz) ListObjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (auth.PolicyPage, error) { - ret := _m.Called(ctx, pr, nextPageToken, limit) - - if len(ret) == 0 { - panic("no return value specified for ListObjects") - } - - var r0 auth.PolicyPage - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) (auth.PolicyPage, error)); ok { - return rf(ctx, pr, nextPageToken, limit) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) auth.PolicyPage); ok { - r0 = rf(ctx, pr, nextPageToken, limit) - } else { - r0 = ret.Get(0).(auth.PolicyPage) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq, string, uint64) error); ok { - r1 = rf(ctx, pr, nextPageToken, limit) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListPermissions provides a mock function with given fields: ctx, pr, filterPermission -func (_m *Authz) ListPermissions(ctx context.Context, pr auth.PolicyReq, filterPermission []string) (auth.Permissions, error) { - ret := _m.Called(ctx, pr, filterPermission) - - if len(ret) == 0 { - panic("no return value specified for ListPermissions") - } - - var r0 auth.Permissions - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, []string) (auth.Permissions, error)); ok { - return rf(ctx, pr, filterPermission) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, []string) auth.Permissions); ok { - r0 = rf(ctx, pr, filterPermission) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(auth.Permissions) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq, []string) error); ok { - r1 = rf(ctx, pr, filterPermission) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListSubjects provides a mock function with given fields: ctx, pr, nextPageToken, limit -func (_m *Authz) ListSubjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (auth.PolicyPage, error) { - ret := _m.Called(ctx, pr, nextPageToken, limit) - - if len(ret) == 0 { - panic("no return value specified for ListSubjects") - } - - var r0 auth.PolicyPage - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) (auth.PolicyPage, error)); ok { - return rf(ctx, pr, nextPageToken, limit) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) auth.PolicyPage); ok { - r0 = rf(ctx, pr, nextPageToken, limit) - } else { - r0 = ret.Get(0).(auth.PolicyPage) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq, string, uint64) error); ok { - r1 = rf(ctx, pr, nextPageToken, limit) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // NewAuthz creates a new instance of Authz. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewAuthz(t interface { diff --git a/auth/mocks/policy_client.go b/auth/mocks/policy_client.go index 5ebe5ac1ed..c15ada5ae3 100644 --- a/auth/mocks/policy_client.go +++ b/auth/mocks/policy_client.go @@ -29,8 +29,8 @@ func (_m *PolicyServiceClient) EXPECT() *PolicyServiceClient_Expecter { return &PolicyServiceClient_Expecter{mock: &_m.Mock} } -// AddPolicies provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) AddPolicies(ctx context.Context, in *magistrala.AddPoliciesReq, opts ...grpc.CallOption) (*magistrala.AddPoliciesRes, error) { +// DeleteUserPolicies provides a mock function with given fields: ctx, in, opts +func (_m *PolicyServiceClient) DeleteUserPolicies(ctx context.Context, in *magistrala.DeleteUserPoliciesReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -41,311 +41,15 @@ func (_m *PolicyServiceClient) AddPolicies(ctx context.Context, in *magistrala.A ret := _m.Called(_ca...) if len(ret) == 0 { - panic("no return value specified for AddPolicies") - } - - var r0 *magistrala.AddPoliciesRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.AddPoliciesReq, ...grpc.CallOption) (*magistrala.AddPoliciesRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.AddPoliciesReq, ...grpc.CallOption) *magistrala.AddPoliciesRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.AddPoliciesRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.AddPoliciesReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_AddPolicies_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddPolicies' -type PolicyServiceClient_AddPolicies_Call struct { - *mock.Call -} - -// AddPolicies is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.AddPoliciesReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) AddPolicies(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_AddPolicies_Call { - return &PolicyServiceClient_AddPolicies_Call{Call: _e.mock.On("AddPolicies", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_AddPolicies_Call) Run(run func(ctx context.Context, in *magistrala.AddPoliciesReq, opts ...grpc.CallOption)) *PolicyServiceClient_AddPolicies_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.AddPoliciesReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_AddPolicies_Call) Return(_a0 *magistrala.AddPoliciesRes, _a1 error) *PolicyServiceClient_AddPolicies_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_AddPolicies_Call) RunAndReturn(run func(context.Context, *magistrala.AddPoliciesReq, ...grpc.CallOption) (*magistrala.AddPoliciesRes, error)) *PolicyServiceClient_AddPolicies_Call { - _c.Call.Return(run) - return _c -} - -// AddPolicy provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) AddPolicy(ctx context.Context, in *magistrala.AddPolicyReq, opts ...grpc.CallOption) (*magistrala.AddPolicyRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for AddPolicy") - } - - var r0 *magistrala.AddPolicyRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.AddPolicyReq, ...grpc.CallOption) (*magistrala.AddPolicyRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.AddPolicyReq, ...grpc.CallOption) *magistrala.AddPolicyRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.AddPolicyRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.AddPolicyReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_AddPolicy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddPolicy' -type PolicyServiceClient_AddPolicy_Call struct { - *mock.Call -} - -// AddPolicy is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.AddPolicyReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) AddPolicy(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_AddPolicy_Call { - return &PolicyServiceClient_AddPolicy_Call{Call: _e.mock.On("AddPolicy", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_AddPolicy_Call) Run(run func(ctx context.Context, in *magistrala.AddPolicyReq, opts ...grpc.CallOption)) *PolicyServiceClient_AddPolicy_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.AddPolicyReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_AddPolicy_Call) Return(_a0 *magistrala.AddPolicyRes, _a1 error) *PolicyServiceClient_AddPolicy_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_AddPolicy_Call) RunAndReturn(run func(context.Context, *magistrala.AddPolicyReq, ...grpc.CallOption) (*magistrala.AddPolicyRes, error)) *PolicyServiceClient_AddPolicy_Call { - _c.Call.Return(run) - return _c -} - -// CountObjects provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) CountObjects(ctx context.Context, in *magistrala.CountObjectsReq, opts ...grpc.CallOption) (*magistrala.CountObjectsRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for CountObjects") - } - - var r0 *magistrala.CountObjectsRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.CountObjectsReq, ...grpc.CallOption) (*magistrala.CountObjectsRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.CountObjectsReq, ...grpc.CallOption) *magistrala.CountObjectsRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.CountObjectsRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.CountObjectsReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_CountObjects_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CountObjects' -type PolicyServiceClient_CountObjects_Call struct { - *mock.Call -} - -// CountObjects is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.CountObjectsReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) CountObjects(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_CountObjects_Call { - return &PolicyServiceClient_CountObjects_Call{Call: _e.mock.On("CountObjects", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_CountObjects_Call) Run(run func(ctx context.Context, in *magistrala.CountObjectsReq, opts ...grpc.CallOption)) *PolicyServiceClient_CountObjects_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.CountObjectsReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_CountObjects_Call) Return(_a0 *magistrala.CountObjectsRes, _a1 error) *PolicyServiceClient_CountObjects_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_CountObjects_Call) RunAndReturn(run func(context.Context, *magistrala.CountObjectsReq, ...grpc.CallOption) (*magistrala.CountObjectsRes, error)) *PolicyServiceClient_CountObjects_Call { - _c.Call.Return(run) - return _c -} - -// CountSubjects provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) CountSubjects(ctx context.Context, in *magistrala.CountSubjectsReq, opts ...grpc.CallOption) (*magistrala.CountSubjectsRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for CountSubjects") - } - - var r0 *magistrala.CountSubjectsRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.CountSubjectsReq, ...grpc.CallOption) (*magistrala.CountSubjectsRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.CountSubjectsReq, ...grpc.CallOption) *magistrala.CountSubjectsRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.CountSubjectsRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.CountSubjectsReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_CountSubjects_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CountSubjects' -type PolicyServiceClient_CountSubjects_Call struct { - *mock.Call -} - -// CountSubjects is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.CountSubjectsReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) CountSubjects(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_CountSubjects_Call { - return &PolicyServiceClient_CountSubjects_Call{Call: _e.mock.On("CountSubjects", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_CountSubjects_Call) Run(run func(ctx context.Context, in *magistrala.CountSubjectsReq, opts ...grpc.CallOption)) *PolicyServiceClient_CountSubjects_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.CountSubjectsReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_CountSubjects_Call) Return(_a0 *magistrala.CountSubjectsRes, _a1 error) *PolicyServiceClient_CountSubjects_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_CountSubjects_Call) RunAndReturn(run func(context.Context, *magistrala.CountSubjectsReq, ...grpc.CallOption) (*magistrala.CountSubjectsRes, error)) *PolicyServiceClient_CountSubjects_Call { - _c.Call.Return(run) - return _c -} - -// DeleteEntityPolicies provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) DeleteEntityPolicies(ctx context.Context, in *magistrala.DeleteEntityPoliciesReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for DeleteEntityPolicies") + panic("no return value specified for DeleteUserPolicies") } var r0 *magistrala.DeletePolicyRes var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeleteEntityPoliciesReq, ...grpc.CallOption) (*magistrala.DeletePolicyRes, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeleteUserPoliciesReq, ...grpc.CallOption) (*magistrala.DeletePolicyRes, error)); ok { return rf(ctx, in, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeleteEntityPoliciesReq, ...grpc.CallOption) *magistrala.DeletePolicyRes); ok { + if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeleteUserPoliciesReq, ...grpc.CallOption) *magistrala.DeletePolicyRes); ok { r0 = rf(ctx, in, opts...) } else { if ret.Get(0) != nil { @@ -353,525 +57,7 @@ func (_m *PolicyServiceClient) DeleteEntityPolicies(ctx context.Context, in *mag } } - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.DeleteEntityPoliciesReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_DeleteEntityPolicies_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteEntityPolicies' -type PolicyServiceClient_DeleteEntityPolicies_Call struct { - *mock.Call -} - -// DeleteEntityPolicies is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.DeleteEntityPoliciesReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) DeleteEntityPolicies(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_DeleteEntityPolicies_Call { - return &PolicyServiceClient_DeleteEntityPolicies_Call{Call: _e.mock.On("DeleteEntityPolicies", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_DeleteEntityPolicies_Call) Run(run func(ctx context.Context, in *magistrala.DeleteEntityPoliciesReq, opts ...grpc.CallOption)) *PolicyServiceClient_DeleteEntityPolicies_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.DeleteEntityPoliciesReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_DeleteEntityPolicies_Call) Return(_a0 *magistrala.DeletePolicyRes, _a1 error) *PolicyServiceClient_DeleteEntityPolicies_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_DeleteEntityPolicies_Call) RunAndReturn(run func(context.Context, *magistrala.DeleteEntityPoliciesReq, ...grpc.CallOption) (*magistrala.DeletePolicyRes, error)) *PolicyServiceClient_DeleteEntityPolicies_Call { - _c.Call.Return(run) - return _c -} - -// DeletePolicies provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) DeletePolicies(ctx context.Context, in *magistrala.DeletePoliciesReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for DeletePolicies") - } - - var r0 *magistrala.DeletePolicyRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeletePoliciesReq, ...grpc.CallOption) (*magistrala.DeletePolicyRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeletePoliciesReq, ...grpc.CallOption) *magistrala.DeletePolicyRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.DeletePolicyRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.DeletePoliciesReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_DeletePolicies_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeletePolicies' -type PolicyServiceClient_DeletePolicies_Call struct { - *mock.Call -} - -// DeletePolicies is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.DeletePoliciesReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) DeletePolicies(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_DeletePolicies_Call { - return &PolicyServiceClient_DeletePolicies_Call{Call: _e.mock.On("DeletePolicies", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_DeletePolicies_Call) Run(run func(ctx context.Context, in *magistrala.DeletePoliciesReq, opts ...grpc.CallOption)) *PolicyServiceClient_DeletePolicies_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.DeletePoliciesReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_DeletePolicies_Call) Return(_a0 *magistrala.DeletePolicyRes, _a1 error) *PolicyServiceClient_DeletePolicies_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_DeletePolicies_Call) RunAndReturn(run func(context.Context, *magistrala.DeletePoliciesReq, ...grpc.CallOption) (*magistrala.DeletePolicyRes, error)) *PolicyServiceClient_DeletePolicies_Call { - _c.Call.Return(run) - return _c -} - -// DeletePolicyFilter provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) DeletePolicyFilter(ctx context.Context, in *magistrala.DeletePolicyFilterReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for DeletePolicyFilter") - } - - var r0 *magistrala.DeletePolicyRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeletePolicyFilterReq, ...grpc.CallOption) (*magistrala.DeletePolicyRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeletePolicyFilterReq, ...grpc.CallOption) *magistrala.DeletePolicyRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.DeletePolicyRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.DeletePolicyFilterReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_DeletePolicyFilter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeletePolicyFilter' -type PolicyServiceClient_DeletePolicyFilter_Call struct { - *mock.Call -} - -// DeletePolicyFilter is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.DeletePolicyFilterReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) DeletePolicyFilter(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_DeletePolicyFilter_Call { - return &PolicyServiceClient_DeletePolicyFilter_Call{Call: _e.mock.On("DeletePolicyFilter", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_DeletePolicyFilter_Call) Run(run func(ctx context.Context, in *magistrala.DeletePolicyFilterReq, opts ...grpc.CallOption)) *PolicyServiceClient_DeletePolicyFilter_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.DeletePolicyFilterReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_DeletePolicyFilter_Call) Return(_a0 *magistrala.DeletePolicyRes, _a1 error) *PolicyServiceClient_DeletePolicyFilter_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_DeletePolicyFilter_Call) RunAndReturn(run func(context.Context, *magistrala.DeletePolicyFilterReq, ...grpc.CallOption) (*magistrala.DeletePolicyRes, error)) *PolicyServiceClient_DeletePolicyFilter_Call { - _c.Call.Return(run) - return _c -} - -// ListAllObjects provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) ListAllObjects(ctx context.Context, in *magistrala.ListObjectsReq, opts ...grpc.CallOption) (*magistrala.ListObjectsRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ListAllObjects") - } - - var r0 *magistrala.ListObjectsRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListObjectsReq, ...grpc.CallOption) (*magistrala.ListObjectsRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListObjectsReq, ...grpc.CallOption) *magistrala.ListObjectsRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.ListObjectsRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.ListObjectsReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_ListAllObjects_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListAllObjects' -type PolicyServiceClient_ListAllObjects_Call struct { - *mock.Call -} - -// ListAllObjects is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.ListObjectsReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) ListAllObjects(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_ListAllObjects_Call { - return &PolicyServiceClient_ListAllObjects_Call{Call: _e.mock.On("ListAllObjects", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_ListAllObjects_Call) Run(run func(ctx context.Context, in *magistrala.ListObjectsReq, opts ...grpc.CallOption)) *PolicyServiceClient_ListAllObjects_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.ListObjectsReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_ListAllObjects_Call) Return(_a0 *magistrala.ListObjectsRes, _a1 error) *PolicyServiceClient_ListAllObjects_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_ListAllObjects_Call) RunAndReturn(run func(context.Context, *magistrala.ListObjectsReq, ...grpc.CallOption) (*magistrala.ListObjectsRes, error)) *PolicyServiceClient_ListAllObjects_Call { - _c.Call.Return(run) - return _c -} - -// ListAllSubjects provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) ListAllSubjects(ctx context.Context, in *magistrala.ListSubjectsReq, opts ...grpc.CallOption) (*magistrala.ListSubjectsRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ListAllSubjects") - } - - var r0 *magistrala.ListSubjectsRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListSubjectsReq, ...grpc.CallOption) (*magistrala.ListSubjectsRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListSubjectsReq, ...grpc.CallOption) *magistrala.ListSubjectsRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.ListSubjectsRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.ListSubjectsReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_ListAllSubjects_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListAllSubjects' -type PolicyServiceClient_ListAllSubjects_Call struct { - *mock.Call -} - -// ListAllSubjects is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.ListSubjectsReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) ListAllSubjects(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_ListAllSubjects_Call { - return &PolicyServiceClient_ListAllSubjects_Call{Call: _e.mock.On("ListAllSubjects", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_ListAllSubjects_Call) Run(run func(ctx context.Context, in *magistrala.ListSubjectsReq, opts ...grpc.CallOption)) *PolicyServiceClient_ListAllSubjects_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.ListSubjectsReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_ListAllSubjects_Call) Return(_a0 *magistrala.ListSubjectsRes, _a1 error) *PolicyServiceClient_ListAllSubjects_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_ListAllSubjects_Call) RunAndReturn(run func(context.Context, *magistrala.ListSubjectsReq, ...grpc.CallOption) (*magistrala.ListSubjectsRes, error)) *PolicyServiceClient_ListAllSubjects_Call { - _c.Call.Return(run) - return _c -} - -// ListObjects provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) ListObjects(ctx context.Context, in *magistrala.ListObjectsReq, opts ...grpc.CallOption) (*magistrala.ListObjectsRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ListObjects") - } - - var r0 *magistrala.ListObjectsRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListObjectsReq, ...grpc.CallOption) (*magistrala.ListObjectsRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListObjectsReq, ...grpc.CallOption) *magistrala.ListObjectsRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.ListObjectsRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.ListObjectsReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_ListObjects_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListObjects' -type PolicyServiceClient_ListObjects_Call struct { - *mock.Call -} - -// ListObjects is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.ListObjectsReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) ListObjects(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_ListObjects_Call { - return &PolicyServiceClient_ListObjects_Call{Call: _e.mock.On("ListObjects", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_ListObjects_Call) Run(run func(ctx context.Context, in *magistrala.ListObjectsReq, opts ...grpc.CallOption)) *PolicyServiceClient_ListObjects_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.ListObjectsReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_ListObjects_Call) Return(_a0 *magistrala.ListObjectsRes, _a1 error) *PolicyServiceClient_ListObjects_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_ListObjects_Call) RunAndReturn(run func(context.Context, *magistrala.ListObjectsReq, ...grpc.CallOption) (*magistrala.ListObjectsRes, error)) *PolicyServiceClient_ListObjects_Call { - _c.Call.Return(run) - return _c -} - -// ListPermissions provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) ListPermissions(ctx context.Context, in *magistrala.ListPermissionsReq, opts ...grpc.CallOption) (*magistrala.ListPermissionsRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ListPermissions") - } - - var r0 *magistrala.ListPermissionsRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListPermissionsReq, ...grpc.CallOption) (*magistrala.ListPermissionsRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListPermissionsReq, ...grpc.CallOption) *magistrala.ListPermissionsRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.ListPermissionsRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.ListPermissionsReq, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PolicyServiceClient_ListPermissions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListPermissions' -type PolicyServiceClient_ListPermissions_Call struct { - *mock.Call -} - -// ListPermissions is a helper method to define mock.On call -// - ctx context.Context -// - in *magistrala.ListPermissionsReq -// - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) ListPermissions(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_ListPermissions_Call { - return &PolicyServiceClient_ListPermissions_Call{Call: _e.mock.On("ListPermissions", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *PolicyServiceClient_ListPermissions_Call) Run(run func(ctx context.Context, in *magistrala.ListPermissionsReq, opts ...grpc.CallOption)) *PolicyServiceClient_ListPermissions_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*magistrala.ListPermissionsReq), variadicArgs...) - }) - return _c -} - -func (_c *PolicyServiceClient_ListPermissions_Call) Return(_a0 *magistrala.ListPermissionsRes, _a1 error) *PolicyServiceClient_ListPermissions_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PolicyServiceClient_ListPermissions_Call) RunAndReturn(run func(context.Context, *magistrala.ListPermissionsReq, ...grpc.CallOption) (*magistrala.ListPermissionsRes, error)) *PolicyServiceClient_ListPermissions_Call { - _c.Call.Return(run) - return _c -} - -// ListSubjects provides a mock function with given fields: ctx, in, opts -func (_m *PolicyServiceClient) ListSubjects(ctx context.Context, in *magistrala.ListSubjectsReq, opts ...grpc.CallOption) (*magistrala.ListSubjectsRes, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ListSubjects") - } - - var r0 *magistrala.ListSubjectsRes - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListSubjectsReq, ...grpc.CallOption) (*magistrala.ListSubjectsRes, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListSubjectsReq, ...grpc.CallOption) *magistrala.ListSubjectsRes); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*magistrala.ListSubjectsRes) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.ListSubjectsReq, ...grpc.CallOption) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *magistrala.DeleteUserPoliciesReq, ...grpc.CallOption) error); ok { r1 = rf(ctx, in, opts...) } else { r1 = ret.Error(1) @@ -880,21 +66,21 @@ func (_m *PolicyServiceClient) ListSubjects(ctx context.Context, in *magistrala. return r0, r1 } -// PolicyServiceClient_ListSubjects_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListSubjects' -type PolicyServiceClient_ListSubjects_Call struct { +// PolicyServiceClient_DeleteUserPolicies_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteUserPolicies' +type PolicyServiceClient_DeleteUserPolicies_Call struct { *mock.Call } -// ListSubjects is a helper method to define mock.On call +// DeleteUserPolicies is a helper method to define mock.On call // - ctx context.Context -// - in *magistrala.ListSubjectsReq +// - in *magistrala.DeleteUserPoliciesReq // - opts ...grpc.CallOption -func (_e *PolicyServiceClient_Expecter) ListSubjects(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_ListSubjects_Call { - return &PolicyServiceClient_ListSubjects_Call{Call: _e.mock.On("ListSubjects", +func (_e *PolicyServiceClient_Expecter) DeleteUserPolicies(ctx interface{}, in interface{}, opts ...interface{}) *PolicyServiceClient_DeleteUserPolicies_Call { + return &PolicyServiceClient_DeleteUserPolicies_Call{Call: _e.mock.On("DeleteUserPolicies", append([]interface{}{ctx, in}, opts...)...)} } -func (_c *PolicyServiceClient_ListSubjects_Call) Run(run func(ctx context.Context, in *magistrala.ListSubjectsReq, opts ...grpc.CallOption)) *PolicyServiceClient_ListSubjects_Call { +func (_c *PolicyServiceClient_DeleteUserPolicies_Call) Run(run func(ctx context.Context, in *magistrala.DeleteUserPoliciesReq, opts ...grpc.CallOption)) *PolicyServiceClient_DeleteUserPolicies_Call { _c.Call.Run(func(args mock.Arguments) { variadicArgs := make([]grpc.CallOption, len(args)-2) for i, a := range args[2:] { @@ -902,17 +88,17 @@ func (_c *PolicyServiceClient_ListSubjects_Call) Run(run func(ctx context.Contex variadicArgs[i] = a.(grpc.CallOption) } } - run(args[0].(context.Context), args[1].(*magistrala.ListSubjectsReq), variadicArgs...) + run(args[0].(context.Context), args[1].(*magistrala.DeleteUserPoliciesReq), variadicArgs...) }) return _c } -func (_c *PolicyServiceClient_ListSubjects_Call) Return(_a0 *magistrala.ListSubjectsRes, _a1 error) *PolicyServiceClient_ListSubjects_Call { +func (_c *PolicyServiceClient_DeleteUserPolicies_Call) Return(_a0 *magistrala.DeletePolicyRes, _a1 error) *PolicyServiceClient_DeleteUserPolicies_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *PolicyServiceClient_ListSubjects_Call) RunAndReturn(run func(context.Context, *magistrala.ListSubjectsReq, ...grpc.CallOption) (*magistrala.ListSubjectsRes, error)) *PolicyServiceClient_ListSubjects_Call { +func (_c *PolicyServiceClient_DeleteUserPolicies_Call) RunAndReturn(run func(context.Context, *magistrala.DeleteUserPoliciesReq, ...grpc.CallOption) (*magistrala.DeletePolicyRes, error)) *PolicyServiceClient_DeleteUserPolicies_Call { _c.Call.Return(run) return _c } diff --git a/auth/mocks/service.go b/auth/mocks/service.go index 45d3b3d7f9..839e5698b1 100644 --- a/auth/mocks/service.go +++ b/auth/mocks/service.go @@ -10,6 +10,8 @@ import ( auth "github.com/absmach/magistrala/auth" mock "github.com/stretchr/testify/mock" + + policy "github.com/absmach/magistrala/pkg/policy" ) // Service is an autogenerated mock type for the Service type @@ -17,42 +19,6 @@ type Service struct { mock.Mock } -// AddPolicies provides a mock function with given fields: ctx, prs -func (_m *Service) AddPolicies(ctx context.Context, prs []auth.PolicyReq) error { - ret := _m.Called(ctx, prs) - - if len(ret) == 0 { - panic("no return value specified for AddPolicies") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []auth.PolicyReq) error); ok { - r0 = rf(ctx, prs) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// AddPolicy provides a mock function with given fields: ctx, pr -func (_m *Service) AddPolicy(ctx context.Context, pr auth.PolicyReq) error { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for AddPolicy") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) error); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // AssignUsers provides a mock function with given fields: ctx, token, id, userIds, relation func (_m *Service) AssignUsers(ctx context.Context, token string, id string, userIds []string, relation string) error { ret := _m.Called(ctx, token, id, userIds, relation) @@ -117,62 +83,6 @@ func (_m *Service) ChangeDomainStatus(ctx context.Context, token string, id stri return r0, r1 } -// CountObjects provides a mock function with given fields: ctx, pr -func (_m *Service) CountObjects(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for CountObjects") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) (uint64, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) uint64); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CountSubjects provides a mock function with given fields: ctx, pr -func (_m *Service) CountSubjects(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for CountSubjects") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) (uint64, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) uint64); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // CreateDomain provides a mock function with given fields: ctx, token, d func (_m *Service) CreateDomain(ctx context.Context, token string, d auth.Domain) (auth.Domain, error) { ret := _m.Called(ctx, token, d) @@ -201,53 +111,17 @@ func (_m *Service) CreateDomain(ctx context.Context, token string, d auth.Domain return r0, r1 } -// DeleteEntityPolicies provides a mock function with given fields: ctx, entityType, id -func (_m *Service) DeleteEntityPolicies(ctx context.Context, entityType string, id string) error { - ret := _m.Called(ctx, entityType, id) - - if len(ret) == 0 { - panic("no return value specified for DeleteEntityPolicies") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { - r0 = rf(ctx, entityType, id) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// DeletePolicies provides a mock function with given fields: ctx, prs -func (_m *Service) DeletePolicies(ctx context.Context, prs []auth.PolicyReq) error { - ret := _m.Called(ctx, prs) - - if len(ret) == 0 { - panic("no return value specified for DeletePolicies") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []auth.PolicyReq) error); ok { - r0 = rf(ctx, prs) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// DeletePolicyFilter provides a mock function with given fields: ctx, pr -func (_m *Service) DeletePolicyFilter(ctx context.Context, pr auth.PolicyReq) error { - ret := _m.Called(ctx, pr) +// DeleteUserPolicies provides a mock function with given fields: ctx, id +func (_m *Service) DeleteUserPolicies(ctx context.Context, id string) error { + ret := _m.Called(ctx, id) if len(ret) == 0 { - panic("no return value specified for DeletePolicyFilter") + panic("no return value specified for DeleteUserPolicies") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) error); ok { - r0 = rf(ctx, pr) + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, id) } else { r0 = ret.Error(0) } @@ -311,62 +185,6 @@ func (_m *Service) Issue(ctx context.Context, token string, key auth.Key) (auth. return r0, r1 } -// ListAllObjects provides a mock function with given fields: ctx, pr -func (_m *Service) ListAllObjects(ctx context.Context, pr auth.PolicyReq) (auth.PolicyPage, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for ListAllObjects") - } - - var r0 auth.PolicyPage - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) (auth.PolicyPage, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) auth.PolicyPage); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Get(0).(auth.PolicyPage) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListAllSubjects provides a mock function with given fields: ctx, pr -func (_m *Service) ListAllSubjects(ctx context.Context, pr auth.PolicyReq) (auth.PolicyPage, error) { - ret := _m.Called(ctx, pr) - - if len(ret) == 0 { - panic("no return value specified for ListAllSubjects") - } - - var r0 auth.PolicyPage - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) (auth.PolicyPage, error)); ok { - return rf(ctx, pr) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq) auth.PolicyPage); ok { - r0 = rf(ctx, pr) - } else { - r0 = ret.Get(0).(auth.PolicyPage) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq) error); ok { - r1 = rf(ctx, pr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // ListDomains provides a mock function with given fields: ctx, token, page func (_m *Service) ListDomains(ctx context.Context, token string, page auth.Page) (auth.DomainsPage, error) { ret := _m.Called(ctx, token, page) @@ -395,92 +213,6 @@ func (_m *Service) ListDomains(ctx context.Context, token string, page auth.Page return r0, r1 } -// ListObjects provides a mock function with given fields: ctx, pr, nextPageToken, limit -func (_m *Service) ListObjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (auth.PolicyPage, error) { - ret := _m.Called(ctx, pr, nextPageToken, limit) - - if len(ret) == 0 { - panic("no return value specified for ListObjects") - } - - var r0 auth.PolicyPage - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) (auth.PolicyPage, error)); ok { - return rf(ctx, pr, nextPageToken, limit) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) auth.PolicyPage); ok { - r0 = rf(ctx, pr, nextPageToken, limit) - } else { - r0 = ret.Get(0).(auth.PolicyPage) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq, string, uint64) error); ok { - r1 = rf(ctx, pr, nextPageToken, limit) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListPermissions provides a mock function with given fields: ctx, pr, filterPermission -func (_m *Service) ListPermissions(ctx context.Context, pr auth.PolicyReq, filterPermission []string) (auth.Permissions, error) { - ret := _m.Called(ctx, pr, filterPermission) - - if len(ret) == 0 { - panic("no return value specified for ListPermissions") - } - - var r0 auth.Permissions - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, []string) (auth.Permissions, error)); ok { - return rf(ctx, pr, filterPermission) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, []string) auth.Permissions); ok { - r0 = rf(ctx, pr, filterPermission) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(auth.Permissions) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq, []string) error); ok { - r1 = rf(ctx, pr, filterPermission) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListSubjects provides a mock function with given fields: ctx, pr, nextPageToken, limit -func (_m *Service) ListSubjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (auth.PolicyPage, error) { - ret := _m.Called(ctx, pr, nextPageToken, limit) - - if len(ret) == 0 { - panic("no return value specified for ListSubjects") - } - - var r0 auth.PolicyPage - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) (auth.PolicyPage, error)); ok { - return rf(ctx, pr, nextPageToken, limit) - } - if rf, ok := ret.Get(0).(func(context.Context, auth.PolicyReq, string, uint64) auth.PolicyPage); ok { - r0 = rf(ctx, pr, nextPageToken, limit) - } else { - r0 = ret.Get(0).(auth.PolicyPage) - } - - if rf, ok := ret.Get(1).(func(context.Context, auth.PolicyReq, string, uint64) error); ok { - r1 = rf(ctx, pr, nextPageToken, limit) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // ListUserDomains provides a mock function with given fields: ctx, token, userID, page func (_m *Service) ListUserDomains(ctx context.Context, token string, userID string, page auth.Page) (auth.DomainsPage, error) { ret := _m.Called(ctx, token, userID, page) @@ -538,23 +270,23 @@ func (_m *Service) RetrieveDomain(ctx context.Context, token string, id string) } // RetrieveDomainPermissions provides a mock function with given fields: ctx, token, id -func (_m *Service) RetrieveDomainPermissions(ctx context.Context, token string, id string) (auth.Permissions, error) { +func (_m *Service) RetrieveDomainPermissions(ctx context.Context, token string, id string) (policy.Permissions, error) { ret := _m.Called(ctx, token, id) if len(ret) == 0 { panic("no return value specified for RetrieveDomainPermissions") } - var r0 auth.Permissions + var r0 policy.Permissions var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, string) (auth.Permissions, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, string, string) (policy.Permissions, error)); ok { return rf(ctx, token, id) } - if rf, ok := ret.Get(0).(func(context.Context, string, string) auth.Permissions); ok { + if rf, ok := ret.Get(0).(func(context.Context, string, string) policy.Permissions); ok { r0 = rf(ctx, token, id) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(auth.Permissions) + r0 = ret.Get(0).(policy.Permissions) } } diff --git a/auth/policies.go b/auth/policies.go index e2e416aed2..66744419ab 100644 --- a/auth/policies.go +++ b/auth/policies.go @@ -134,45 +134,8 @@ type Authz interface { // denied). Authorize(ctx context.Context, pr PolicyReq) error - // AddPolicy creates a policy for the given subject, so that, after - // AddPolicy, `subject` has a `relation` on `object`. Returns a non-nil - // error in case of failures. - AddPolicy(ctx context.Context, pr PolicyReq) error - - // AddPolicies adds new policies for given subjects. This method is - // only allowed to use as an admin. - AddPolicies(ctx context.Context, prs []PolicyReq) error - - // DeletePolicyFilter removes policy for given policy filter request. - DeletePolicyFilter(ctx context.Context, pr PolicyReq) error - - // DeletePolicies deletes policies for given subjects. This method is - // only allowed to use as an admin. - DeletePolicies(ctx context.Context, prs []PolicyReq) error - - // ListObjects lists policies based on the given PolicyReq structure. - ListObjects(ctx context.Context, pr PolicyReq, nextPageToken string, limit uint64) (PolicyPage, error) - - // ListAllObjects lists all policies based on the given PolicyReq structure. - ListAllObjects(ctx context.Context, pr PolicyReq) (PolicyPage, error) - - // CountPolicies count policies based on the given PolicyReq structure. - CountObjects(ctx context.Context, pr PolicyReq) (uint64, error) - - // ListSubjects lists subjects based on the given PolicyReq structure. - ListSubjects(ctx context.Context, pr PolicyReq, nextPageToken string, limit uint64) (PolicyPage, error) - - // ListAllSubjects lists all subjects based on the given PolicyReq structure. - ListAllSubjects(ctx context.Context, pr PolicyReq) (PolicyPage, error) - - // CountSubjects count policies based on the given PolicyReq structure. - CountSubjects(ctx context.Context, pr PolicyReq) (uint64, error) - - // ListPermissions lists permission betweeen given subject and object . - ListPermissions(ctx context.Context, pr PolicyReq, filterPermission []string) (Permissions, error) - - // DeleteEntityPolicies deletes all policies for the given entity. - DeleteEntityPolicies(ctx context.Context, entityType, id string) error + // DeleteUserPolicies deletes all policies for the given user. + DeleteUserPolicies(ctx context.Context, id string) error } // PolicyAgent facilitates the communication to authorization @@ -185,39 +148,4 @@ type PolicyAgent interface { // It returns a non-nil error if the subject has no relation on // the object (which simply means the operation is denied). CheckPolicy(ctx context.Context, pr PolicyReq) error - - // AddPolicy creates a policy for the given subject, so that, after - // AddPolicy, `subject` has a `relation` on `object`. Returns a non-nil - // error in case of failures. - AddPolicy(ctx context.Context, pr PolicyReq) error - - // AddPolicies creates a Bulk Policies for the given request - AddPolicies(ctx context.Context, prs []PolicyReq) error - - // DeletePolicyFilter removes policy for given policy filter request. - DeletePolicyFilter(ctx context.Context, pr PolicyReq) error - - // DeletePolicies removes a bulk policies for the given request. - DeletePolicies(ctx context.Context, pr []PolicyReq) error - - // RetrieveObjects - RetrieveObjects(ctx context.Context, pr PolicyReq, nextPageToken string, limit uint64) ([]PolicyRes, string, error) - - // RetrieveAllObjects - RetrieveAllObjects(ctx context.Context, pr PolicyReq) ([]PolicyRes, error) - - // RetrieveAllObjectsCount - RetrieveAllObjectsCount(ctx context.Context, pr PolicyReq) (uint64, error) - - // RetrieveSubjects - RetrieveSubjects(ctx context.Context, pr PolicyReq, nextPageToken string, limit uint64) ([]PolicyRes, string, error) - - // RetrieveAllSubjects - RetrieveAllSubjects(ctx context.Context, pr PolicyReq) ([]PolicyRes, error) - - // RetrieveAllSubjectsCount - RetrieveAllSubjectsCount(ctx context.Context, pr PolicyReq) (uint64, error) - - // (ctx context.Context, pr PolicyReq, filterPermissions []string) ([]PolicyReq, error) - RetrievePermissions(ctx context.Context, pr PolicyReq, filterPermission []string) (Permissions, error) } diff --git a/auth/service.go b/auth/service.go index 3cf67c44e3..768e8b1e84 100644 --- a/auth/service.go +++ b/auth/service.go @@ -12,6 +12,7 @@ import ( "github.com/absmach/magistrala" "github.com/absmach/magistrala/pkg/errors" svcerr "github.com/absmach/magistrala/pkg/errors/service" + "github.com/absmach/magistrala/pkg/policy" ) const ( @@ -35,42 +36,6 @@ var ( errRollbackPolicy = errors.New("failed to rollback policy") errRemoveLocalPolicy = errors.New("failed to remove from local policy copy") errRemovePolicyEngine = errors.New("failed to remove from policy engine") - // errInvalidEntityType indicates invalid entity type. - errInvalidEntityType = errors.New("invalid entity type") -) - -var ( - defThingsFilterPermissions = []string{ - AdminPermission, - DeletePermission, - EditPermission, - ViewPermission, - SharePermission, - PublishPermission, - SubscribePermission, - } - - defGroupsFilterPermissions = []string{ - AdminPermission, - DeletePermission, - EditPermission, - ViewPermission, - MembershipPermission, - SharePermission, - } - - defDomainsFilterPermissions = []string{ - AdminPermission, - EditPermission, - ViewPermission, - MembershipPermission, - SharePermission, - } - - defPlatformFilterPermissions = []string{ - AdminPermission, - MembershipPermission, - } ) // Authn specifies an API that must be fulfilled by the domain service @@ -114,6 +79,7 @@ type service struct { domains DomainsRepository idProvider magistrala.IDProvider agent PolicyAgent + policy policy.PolicyClient tokenizer Tokenizer loginDuration time.Duration refreshDuration time.Duration @@ -121,13 +87,14 @@ type service struct { } // New instantiates the auth service implementation. -func New(keys KeyRepository, domains DomainsRepository, idp magistrala.IDProvider, tokenizer Tokenizer, policyAgent PolicyAgent, loginDuration, refreshDuration, invitationDuration time.Duration) Service { +func New(keys KeyRepository, domains DomainsRepository, idp magistrala.IDProvider, tokenizer Tokenizer, policyAgent PolicyAgent, policyClient policy.PolicyClient, loginDuration, refreshDuration, invitationDuration time.Duration) Service { return &service{ tokenizer: tokenizer, domains: domains, keys: keys, idProvider: idp, agent: policyAgent, + policy: policyClient, loginDuration: loginDuration, refreshDuration: refreshDuration, invitationDuration: invitationDuration, @@ -287,13 +254,6 @@ func (svc service) checkDomain(ctx context.Context, subjectType, subject, domain return nil } -func (svc service) AddPolicy(ctx context.Context, pr PolicyReq) error { - if err := svc.PolicyValidation(pr); err != nil { - return errors.Wrap(svcerr.ErrInvalidPolicy, err) - } - return svc.agent.AddPolicy(ctx, pr) -} - func (svc service) PolicyValidation(pr PolicyReq) error { if pr.ObjectType == PlatformType && pr.Object != MagistralaObject { return errPlatform @@ -301,115 +261,6 @@ func (svc service) PolicyValidation(pr PolicyReq) error { return nil } -func (svc service) AddPolicies(ctx context.Context, prs []PolicyReq) error { - for _, pr := range prs { - if err := svc.PolicyValidation(pr); err != nil { - return errors.Wrap(svcerr.ErrInvalidPolicy, err) - } - } - return svc.agent.AddPolicies(ctx, prs) -} - -func (svc service) DeletePolicyFilter(ctx context.Context, pr PolicyReq) error { - return svc.agent.DeletePolicyFilter(ctx, pr) -} - -func (svc service) DeletePolicies(ctx context.Context, prs []PolicyReq) error { - for _, pr := range prs { - if err := svc.PolicyValidation(pr); err != nil { - return errors.Wrap(svcerr.ErrInvalidPolicy, err) - } - } - return svc.agent.DeletePolicies(ctx, prs) -} - -func (svc service) ListObjects(ctx context.Context, pr PolicyReq, nextPageToken string, limit uint64) (PolicyPage, error) { - if limit <= 0 { - limit = 100 - } - res, npt, err := svc.agent.RetrieveObjects(ctx, pr, nextPageToken, limit) - if err != nil { - return PolicyPage{}, errors.Wrap(svcerr.ErrViewEntity, err) - } - var page PolicyPage - for _, tuple := range res { - page.Policies = append(page.Policies, tuple.Object) - } - page.NextPageToken = npt - return page, nil -} - -func (svc service) ListAllObjects(ctx context.Context, pr PolicyReq) (PolicyPage, error) { - res, err := svc.agent.RetrieveAllObjects(ctx, pr) - if err != nil { - return PolicyPage{}, errors.Wrap(svcerr.ErrViewEntity, err) - } - var page PolicyPage - for _, tuple := range res { - page.Policies = append(page.Policies, tuple.Object) - } - return page, nil -} - -func (svc service) CountObjects(ctx context.Context, pr PolicyReq) (uint64, error) { - return svc.agent.RetrieveAllObjectsCount(ctx, pr) -} - -func (svc service) ListSubjects(ctx context.Context, pr PolicyReq, nextPageToken string, limit uint64) (PolicyPage, error) { - if limit <= 0 { - limit = 100 - } - res, npt, err := svc.agent.RetrieveSubjects(ctx, pr, nextPageToken, limit) - if err != nil { - return PolicyPage{}, errors.Wrap(svcerr.ErrViewEntity, err) - } - var page PolicyPage - for _, tuple := range res { - page.Policies = append(page.Policies, tuple.Subject) - } - page.NextPageToken = npt - return page, nil -} - -func (svc service) ListAllSubjects(ctx context.Context, pr PolicyReq) (PolicyPage, error) { - res, err := svc.agent.RetrieveAllSubjects(ctx, pr) - if err != nil { - return PolicyPage{}, errors.Wrap(svcerr.ErrViewEntity, err) - } - var page PolicyPage - for _, tuple := range res { - page.Policies = append(page.Policies, tuple.Subject) - } - return page, nil -} - -func (svc service) CountSubjects(ctx context.Context, pr PolicyReq) (uint64, error) { - return svc.agent.RetrieveAllSubjectsCount(ctx, pr) -} - -func (svc service) ListPermissions(ctx context.Context, pr PolicyReq, permissionsFilter []string) (Permissions, error) { - if len(permissionsFilter) == 0 { - switch pr.ObjectType { - case ThingType: - permissionsFilter = defThingsFilterPermissions - case GroupType: - permissionsFilter = defGroupsFilterPermissions - case PlatformType: - permissionsFilter = defPlatformFilterPermissions - case DomainType: - permissionsFilter = defDomainsFilterPermissions - default: - return nil, svcerr.ErrMalformedEntity - } - } - pers, err := svc.agent.RetrievePermissions(ctx, pr, permissionsFilter) - if err != nil { - return []string{}, errors.Wrap(svcerr.ErrViewEntity, err) - } - - return pers, nil -} - func (svc service) tmpKey(duration time.Duration, key Key) (Token, error) { key.ExpiresAt = time.Now().Add(duration) value, err := svc.tokenizer.Issue(key) @@ -646,7 +497,7 @@ func (svc service) RetrieveDomain(ctx context.Context, token, id string) (Domain return domain, nil } -func (svc service) RetrieveDomainPermissions(ctx context.Context, token, id string) (Permissions, error) { +func (svc service) RetrieveDomainPermissions(ctx context.Context, token, id string) (policy.Permissions, error) { res, err := svc.Identify(ctx, token) if err != nil { return []string{}, err @@ -663,7 +514,7 @@ func (svc service) RetrieveDomainPermissions(ctx context.Context, token, id stri return []string{}, err } - lp, err := svc.ListPermissions(ctx, PolicyReq{ + lp, err := svc.policy.ListPermissions(ctx, policy.PolicyReq{ SubjectType: UserType, Subject: res.Subject, Object: id, @@ -810,7 +661,7 @@ func (svc service) UnassignUser(ctx context.Context, token, id, userID string) e } } - if err := svc.DeletePolicyFilter(ctx, PolicyReq{ + if err := svc.policy.DeletePolicyFilter(ctx, policy.PolicyReq{ Subject: EncodeDomainUserID(id, userID), SubjectType: UserType, }); err != nil { @@ -859,11 +710,11 @@ func (svc service) ListUserDomains(ctx context.Context, token, userID string, p } func (svc service) addDomainPolicies(ctx context.Context, domainID, relation string, userIDs ...string) (err error) { - var prs []PolicyReq + var prs []policy.PolicyReq var pcs []Policy for _, userID := range userIDs { - prs = append(prs, PolicyReq{ + prs = append(prs, policy.PolicyReq{ Subject: EncodeDomainUserID(domainID, userID), SubjectType: UserType, SubjectKind: UsersKind, @@ -879,12 +730,12 @@ func (svc service) addDomainPolicies(ctx context.Context, domainID, relation str ObjectID: domainID, }) } - if err := svc.agent.AddPolicies(ctx, prs); err != nil { + if err := svc.policy.AddPolicies(ctx, prs); err != nil { return errors.Wrap(errAddPolicies, err) } defer func() { if err != nil { - if errDel := svc.agent.DeletePolicies(ctx, prs); errDel != nil { + if errDel := svc.policy.DeletePolicies(ctx, prs); errDel != nil { err = errors.Wrap(err, errors.Wrap(errRollbackPolicy, errDel)) } } @@ -897,7 +748,7 @@ func (svc service) addDomainPolicies(ctx context.Context, domainID, relation str } func (svc service) createDomainPolicy(ctx context.Context, userID, domainID, relation string) (err error) { - prs := []PolicyReq{ + prs := []policy.PolicyReq{ { Subject: EncodeDomainUserID(domainID, userID), SubjectType: UserType, @@ -914,12 +765,12 @@ func (svc service) createDomainPolicy(ctx context.Context, userID, domainID, rel ObjectType: DomainType, }, } - if err := svc.agent.AddPolicies(ctx, prs); err != nil { + if err := svc.policy.AddPolicies(ctx, prs); err != nil { return err } defer func() { if err != nil { - if errDel := svc.agent.DeletePolicies(ctx, prs); errDel != nil { + if errDel := svc.policy.DeletePolicies(ctx, prs); errDel != nil { err = errors.Wrap(err, errors.Wrap(errRollbackPolicy, errDel)) } } @@ -939,7 +790,7 @@ func (svc service) createDomainPolicy(ctx context.Context, userID, domainID, rel func (svc service) createDomainPolicyRollback(ctx context.Context, userID, domainID, relation string) error { var err error - prs := []PolicyReq{ + prs := []policy.PolicyReq{ { Subject: EncodeDomainUserID(domainID, userID), SubjectType: UserType, @@ -956,7 +807,7 @@ func (svc service) createDomainPolicyRollback(ctx context.Context, userID, domai ObjectType: DomainType, }, } - if errPolicy := svc.agent.DeletePolicies(ctx, prs); errPolicy != nil { + if errPolicy := svc.policy.DeletePolicies(ctx, prs); errPolicy != nil { err = errors.Wrap(errRemovePolicyEngine, errPolicy) } errPolicyCopy := svc.domains.DeletePolicies(ctx, Policy{ @@ -997,70 +848,44 @@ func DecodeDomainUserID(domainUserID string) (string, string) { } } -func (svc service) DeleteEntityPolicies(ctx context.Context, entityType, id string) (err error) { - switch entityType { - case ThingType: - req := PolicyReq{ - Object: id, - ObjectType: ThingType, - } - - return svc.DeletePolicyFilter(ctx, req) - case UserType: - domainsPage, err := svc.domains.ListDomains(ctx, Page{SubjectID: id, Limit: defLimit}) - if err != nil { - return err - } - - if domainsPage.Total > defLimit { - for i := defLimit; i < int(domainsPage.Total); i += defLimit { - page := Page{SubjectID: id, Offset: uint64(i), Limit: defLimit} - dp, err := svc.domains.ListDomains(ctx, page) - if err != nil { - return err - } - domainsPage.Domains = append(domainsPage.Domains, dp.Domains...) - } - } +func (svc service) DeleteUserPolicies(ctx context.Context, id string) (err error) { + domainsPage, err := svc.domains.ListDomains(ctx, Page{SubjectID: id, Limit: defLimit}) + if err != nil { + return err + } - for _, domain := range domainsPage.Domains { - policy := PolicyReq{ - Subject: EncodeDomainUserID(domain.ID, id), - SubjectType: UserType, - } - if err := svc.agent.DeletePolicyFilter(ctx, policy); err != nil { + if domainsPage.Total > defLimit { + for i := defLimit; i < int(domainsPage.Total); i += defLimit { + page := Page{SubjectID: id, Offset: uint64(i), Limit: defLimit} + dp, err := svc.domains.ListDomains(ctx, page) + if err != nil { return err } + domainsPage.Domains = append(domainsPage.Domains, dp.Domains...) } + } - req := PolicyReq{ - Subject: id, + for _, domain := range domainsPage.Domains { + req := policy.PolicyReq{ + Subject: EncodeDomainUserID(domain.ID, id), SubjectType: UserType, } - if err := svc.agent.DeletePolicyFilter(ctx, req); err != nil { - return err - } - - if err := svc.domains.DeleteUserPolicies(ctx, id); err != nil { + if err := svc.policy.DeletePolicyFilter(ctx, req); err != nil { return err } + } - return nil - case GroupType: - req := PolicyReq{ - SubjectType: GroupType, - Subject: id, - } - if err := svc.DeletePolicyFilter(ctx, req); err != nil { - return err - } + req := policy.PolicyReq{ + Subject: id, + SubjectType: UserType, + } + if err := svc.policy.DeletePolicyFilter(ctx, req); err != nil { + return err + } - req = PolicyReq{ - Object: id, - ObjectType: GroupType, - } - return svc.DeletePolicyFilter(ctx, req) - default: - return errInvalidEntityType + if err := svc.domains.DeleteUserPolicies(ctx, id); err != nil { + return err } + + return nil } diff --git a/auth/service_test.go b/auth/service_test.go index 7547c87db5..4aa6f9579e 100644 --- a/auth/service_test.go +++ b/auth/service_test.go @@ -15,18 +15,19 @@ import ( "github.com/absmach/magistrala/pkg/errors" repoerr "github.com/absmach/magistrala/pkg/errors/repository" svcerr "github.com/absmach/magistrala/pkg/errors/service" + policysvc "github.com/absmach/magistrala/pkg/policy" + policymocks "github.com/absmach/magistrala/pkg/policy/mocks" "github.com/absmach/magistrala/pkg/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) const ( - secret = "secret" - email = "test@example.com" - id = "testID" - groupName = "mgx" - description = "Description" - + secret = "secret" + email = "test@example.com" + id = "testID" + groupName = "mgx" + description = "Description" memberRelation = "member" authoritiesObj = "authorities" loginDuration = 30 * time.Minute @@ -58,15 +59,17 @@ var ( ) var ( - krepo *mocks.KeyRepository - prepo *mocks.PolicyAgent - drepo *mocks.DomainsRepository + krepo *mocks.KeyRepository + prepo *mocks.PolicyAgent + drepo *mocks.DomainsRepository + policy *policymocks.PolicyClient ) func newService() (auth.Service, string) { krepo = new(mocks.KeyRepository) prepo = new(mocks.PolicyAgent) drepo = new(mocks.DomainsRepository) + policy = new(policymocks.PolicyClient) idProvider := uuid.NewMock() t := jwt.New([]byte(secret)) @@ -80,7 +83,7 @@ func newService() (auth.Service, string) { } token, _ := t.Issue(key) - return auth.New(krepo, drepo, idProvider, t, prepo, loginDuration, refreshDuration, invalidDuration), token + return auth.New(krepo, drepo, idProvider, t, prepo, policy, loginDuration, refreshDuration, invalidDuration), token } func TestIssue(t *testing.T) { @@ -1197,468 +1200,6 @@ func TestAuthorize(t *testing.T) { } } -func TestAddPolicy(t *testing.T) { - svc, _ := newService() - - cases := []struct { - desc string - pr auth.PolicyReq - err error - }{ - { - desc: "add policy successfully", - pr: auth.PolicyReq{ - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - err: nil, - }, - { - desc: "add policy with invalid object", - pr: auth.PolicyReq{ - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: inValid, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - err: svcerr.ErrInvalidPolicy, - }, - } - - for _, tc := range cases { - repocall := prepo.On("AddPolicy", mock.Anything, mock.Anything).Return(tc.err) - err := svc.AddPolicy(context.Background(), tc.pr) - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.err, err)) - repocall.Unset() - } -} - -func TestAddPolicies(t *testing.T) { - svc, _ := newService() - - cases := []struct { - desc string - pr []auth.PolicyReq - err error - }{ - { - desc: "add policy successfully", - pr: []auth.PolicyReq{ - { - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - { - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - }, - err: nil, - }, - { - desc: "add policy with invalid object", - pr: []auth.PolicyReq{ - { - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: inValid, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - { - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - }, - err: svcerr.ErrInvalidPolicy, - }, - } - - for _, tc := range cases { - repocall := prepo.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.err) - err := svc.AddPolicies(context.Background(), tc.pr) - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.err, err)) - repocall.Unset() - } -} - -func TestDeletePolicy(t *testing.T) { - svc, _ := newService() - - cases := []struct { - desc string - pr auth.PolicyReq - err error - }{ - { - desc: "delete policy successfully", - pr: auth.PolicyReq{ - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - err: nil, - }, - { - desc: "delete policy with invalid object", - pr: auth.PolicyReq{ - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: inValid, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - err: svcerr.ErrInvalidPolicy, - }, - } - - for _, tc := range cases { - repocall := prepo.On("DeletePolicyFilter", context.Background(), mock.Anything).Return(tc.err) - err := svc.DeletePolicyFilter(context.Background(), tc.pr) - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.err, err)) - repocall.Unset() - } -} - -func TestDeletePolicies(t *testing.T) { - svc, _ := newService() - - cases := []struct { - desc string - pr []auth.PolicyReq - err error - }{ - { - desc: "delete policy successfully", - pr: []auth.PolicyReq{ - { - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - { - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - }, - err: nil, - }, - { - desc: "delete policy with invalid object", - pr: []auth.PolicyReq{ - { - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: inValid, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - { - Subject: id, - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - Permission: auth.AdminPermission, - }, - }, - err: svcerr.ErrInvalidPolicy, - }, - } - - for _, tc := range cases { - repocall := prepo.On("DeletePolicies", context.Background(), mock.Anything).Return(tc.err) - err := svc.DeletePolicies(context.Background(), tc.pr) - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.err, err)) - repocall.Unset() - } -} - -func TestListObjects(t *testing.T) { - svc, accessToken := newService() - - pageLen := 15 - expectedPolicies := make([]auth.PolicyRes, pageLen) - - cases := []struct { - desc string - pr auth.PolicyReq - nextPageToken string - limit uint64 - err error - }{ - { - desc: "list objects successfully", - pr: auth.PolicyReq{ - Subject: id, - SubjectType: auth.UserType, - Relation: auth.ContributorRelation, - ObjectType: auth.ThingType, - ObjectKind: auth.ThingsKind, - Object: "", - }, - nextPageToken: accessToken, - limit: 10, - err: nil, - }, - { - desc: "list objects with invalid request", - pr: auth.PolicyReq{ - Subject: inValid, - SubjectType: inValid, - Relation: auth.ContributorRelation, - ObjectType: auth.ThingType, - ObjectKind: auth.ThingsKind, - Object: inValid, - }, - nextPageToken: accessToken, - limit: 10, - err: svcerr.ErrInvalidPolicy, - }, - } - for _, tc := range cases { - repocall2 := prepo.On("RetrieveObjects", context.Background(), mock.Anything, mock.Anything, mock.Anything).Return(expectedPolicies, mock.Anything, tc.err) - page, err := svc.ListObjects(context.Background(), tc.pr, tc.nextPageToken, tc.limit) - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("listing policies expected to succeed: %s", err)) - if err == nil { - assert.Equal(t, pageLen, len(page.Policies), fmt.Sprintf("unexpected listing page size, expected %d, got %d: %v", pageLen, len(page.Policies), err)) - } - repocall2.Unset() - } -} - -func TestListAllObjects(t *testing.T) { - svc, accessToken := newService() - - pageLen := 15 - expectedPolicies := make([]auth.PolicyRes, pageLen) - - cases := []struct { - desc string - pr auth.PolicyReq - nextPageToken string - limit int32 - err error - }{ - { - desc: "list all objects successfully", - pr: auth.PolicyReq{ - Subject: id, - SubjectType: auth.UserType, - Relation: auth.ContributorRelation, - ObjectType: auth.ThingType, - ObjectKind: auth.ThingsKind, - Object: "", - }, - nextPageToken: accessToken, - limit: 10, - err: nil, - }, - { - desc: "list all objects with invalid request", - pr: auth.PolicyReq{ - Subject: inValid, - SubjectType: inValid, - Relation: auth.ContributorRelation, - ObjectType: auth.ThingType, - ObjectKind: auth.ThingsKind, - Object: inValid, - }, - nextPageToken: accessToken, - limit: 10, - err: svcerr.ErrInvalidPolicy, - }, - } - for _, tc := range cases { - repocall2 := prepo.On("RetrieveAllObjects", context.Background(), mock.Anything).Return(expectedPolicies, tc.err) - page, err := svc.ListAllObjects(context.Background(), tc.pr) - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("listing policies expected to succeed: %s", err)) - if err == nil { - assert.Equal(t, pageLen, len(page.Policies), fmt.Sprintf("unexpected listing page size, expected %d, got %d: %v", pageLen, len(page.Policies), err)) - } - repocall2.Unset() - } -} - -func TestCountObjects(t *testing.T) { - svc, _ := newService() - - pageLen := uint64(15) - - repocall2 := prepo.On("RetrieveAllObjectsCount", context.Background(), mock.Anything, mock.Anything).Return(pageLen, nil) - count, err := svc.CountObjects(context.Background(), auth.PolicyReq{Subject: id, SubjectType: auth.UserType, ObjectType: auth.ThingType, Permission: auth.ViewPermission}) - assert.Nil(t, err, fmt.Sprintf("counting policies expected to succeed: %s", err)) - assert.Equal(t, pageLen, count, fmt.Sprintf("unexpected listing page size, expected %d, got %d: %v", pageLen, count, err)) - repocall2.Unset() -} - -func TestListSubjects(t *testing.T) { - svc, accessToken := newService() - - pageLen := 15 - expectedPolicies := make([]auth.PolicyRes, pageLen) - - cases := []struct { - desc string - pr auth.PolicyReq - nextPageToken string - limit uint64 - err error - }{ - { - desc: "list subjects successfully", - pr: auth.PolicyReq{ - Subject: id, - SubjectType: auth.UserType, - Relation: auth.ContributorRelation, - ObjectType: auth.ThingType, - ObjectKind: auth.ThingsKind, - Object: "", - }, - nextPageToken: accessToken, - limit: 10, - err: nil, - }, - { - desc: "list subjects with invalid request", - pr: auth.PolicyReq{ - Subject: inValid, - SubjectType: inValid, - Relation: auth.ContributorRelation, - ObjectType: auth.ThingType, - ObjectKind: auth.ThingsKind, - Object: inValid, - }, - nextPageToken: accessToken, - limit: 10, - err: svcerr.ErrInvalidPolicy, - }, - } - for _, tc := range cases { - repocall := prepo.On("RetrieveSubjects", context.Background(), mock.Anything, mock.Anything, mock.Anything).Return(expectedPolicies, mock.Anything, tc.err) - page, err := svc.ListSubjects(context.Background(), tc.pr, tc.nextPageToken, tc.limit) - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("listing policies expected to succeed: %s", err)) - if err == nil { - assert.Equal(t, pageLen, len(page.Policies), fmt.Sprintf("unexpected listing page size, expected %d, got %d: %v", pageLen, len(page.Policies), err)) - } - repocall.Unset() - } -} - -func TestListAllSubjects(t *testing.T) { - svc, accessToken := newService() - - pageLen := 15 - expectedPolicies := make([]auth.PolicyRes, pageLen) - - cases := []struct { - desc string - pr auth.PolicyReq - nextPageToken string - limit int32 - err error - }{ - { - desc: "list all subjects successfully", - pr: auth.PolicyReq{ - Subject: id, - SubjectType: auth.UserType, - Relation: auth.ContributorRelation, - ObjectType: auth.ThingType, - ObjectKind: auth.ThingsKind, - Object: "", - }, - nextPageToken: accessToken, - limit: 10, - err: nil, - }, - { - desc: "list all subjects with invalid request", - pr: auth.PolicyReq{ - Subject: inValid, - SubjectType: inValid, - Relation: auth.ContributorRelation, - ObjectType: auth.ThingType, - ObjectKind: auth.ThingsKind, - Object: inValid, - }, - nextPageToken: accessToken, - limit: 10, - err: svcerr.ErrInvalidPolicy, - }, - } - for _, tc := range cases { - repocall := prepo.On("RetrieveAllSubjects", context.Background(), mock.Anything).Return(expectedPolicies, tc.err) - page, err := svc.ListAllSubjects(context.Background(), tc.pr) - assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("listing policies expected to succeed: %s", err)) - if err == nil { - assert.Equal(t, pageLen, len(page.Policies), fmt.Sprintf("unexpected listing page size, expected %d, got %d: %v", pageLen, len(page.Policies), err)) - } - repocall.Unset() - } -} - -func TestCountSubjects(t *testing.T) { - svc, _ := newService() - pageLen := uint64(15) - - repocall := prepo.On("RetrieveAllSubjectsCount", mock.Anything, mock.Anything, mock.Anything).Return(pageLen, nil) - count, err := svc.CountSubjects(context.Background(), auth.PolicyReq{Object: id, ObjectType: auth.ThingType, Permission: auth.ViewPermission}) - assert.Nil(t, err, fmt.Sprintf("counting policies expected to succeed: %s", err)) - assert.Equal(t, pageLen, count, fmt.Sprintf("unexpected listing page size, expected %d, got %d: %v", pageLen, count, err)) - repocall.Unset() -} - -func TestListPermissions(t *testing.T) { - svc, _ := newService() - - pr := auth.PolicyReq{ - Subject: id, - SubjectType: auth.UserType, - Relation: auth.ContributorRelation, - ObjectType: auth.ThingType, - ObjectKind: auth.ThingsKind, - Object: "", - } - filterPermisions := []string{auth.ViewPermission, auth.AdminPermission} - - repoCall := prepo.On("RetrievePermissions", context.Background(), pr, filterPermisions).Return(auth.Permissions{}, nil) - _, err := svc.ListPermissions(context.Background(), pr, filterPermisions) - assert.Nil(t, err, fmt.Sprintf("listing policies expected to succeed: %s", err)) - repoCall.Unset() -} - func TestSwitchToPermission(t *testing.T) { cases := []struct { desc string @@ -1812,9 +1353,9 @@ func TestCreateDomain(t *testing.T) { } for _, tc := range cases { - repoCall := prepo.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.addPolicyErr) + repoCall := policy.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.addPolicyErr) repoCall1 := drepo.On("SavePolicies", mock.Anything, mock.Anything).Return(tc.savePolicyErr) - repoCall2 := prepo.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePoliciesErr) + repoCall2 := policy.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePoliciesErr) repoCall3 := drepo.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deleteDomainErr) repoCall4 := drepo.On("Save", mock.Anything, mock.Anything).Return(auth.Domain{}, tc.saveDomainErr) _, err := svc.CreateDomain(context.Background(), tc.token, tc.d) @@ -1935,7 +1476,7 @@ func TestRetrieveDomainPermissions(t *testing.T) { } for _, tc := range cases { - repoCall := prepo.On("RetrievePermissions", mock.Anything, mock.Anything, mock.Anything).Return(auth.Permissions{}, tc.retreivePermissionsErr) + repoCall := policy.On("ListPermissions", mock.Anything, mock.Anything, mock.Anything).Return(policysvc.Permissions{}, tc.retreivePermissionsErr) repoCall1 := drepo.On("RetrieveByID", mock.Anything, mock.Anything).Return(auth.Domain{}, tc.retreiveByIDErr) repoCall2 := prepo.On("CheckPolicy", mock.Anything, mock.Anything).Return(tc.checkPolicyErr) _, err := svc.RetrieveDomainPermissions(context.Background(), tc.token, tc.domainID) @@ -2470,9 +2011,9 @@ func TestAssignUsers(t *testing.T) { repoCall2 := prepo.On("CheckPolicy", mock.Anything, tc.checkAdminPolicyReq).Return(tc.checkPolicyErr1) repoCall3 := prepo.On("CheckPolicy", mock.Anything, tc.checkDomainPolicyReq).Return(tc.checkPolicyErr2) repoCall4 := prepo.On("CheckPolicy", mock.Anything, tc.checkPolicyReq33).Return(tc.checkPolicyErr2) - repoCall5 := prepo.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.addPoliciesErr) + repoCall5 := policy.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.addPoliciesErr) repoCall6 := drepo.On("SavePolicies", mock.Anything, mock.Anything, mock.Anything).Return(tc.savePoliciesErr) - repoCall7 := prepo.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePoliciesErr) + repoCall7 := policy.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePoliciesErr) err := svc.AssignUsers(context.Background(), tc.token, tc.domainID, tc.userIDs, tc.relation) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.err, err)) repoCall.Unset() @@ -2700,7 +2241,7 @@ func TestUnassignUser(t *testing.T) { repoCall1 := prepo.On("CheckPolicy", mock.Anything, tc.checkPolicyReq).Return(tc.checkPolicyErr) repoCall2 := prepo.On("CheckPolicy", mock.Anything, tc.checkAdminPolicyReq).Return(tc.checkPolicyErr1) repoCall3 := prepo.On("CheckPolicy", mock.Anything, tc.checkDomainPolicyReq).Return(tc.checkPolicyErr1) - repoCall4 := prepo.On("DeletePolicyFilter", mock.Anything, mock.Anything).Return(tc.deletePolicyFilterErr) + repoCall4 := policy.On("DeletePolicyFilter", mock.Anything, mock.Anything).Return(tc.deletePolicyFilterErr) repoCall5 := drepo.On("DeletePolicies", mock.Anything, mock.Anything, mock.Anything).Return(tc.deletePoliciesErr) err := svc.UnassignUser(context.Background(), tc.token, tc.domainID, tc.userID) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s got %s\n", tc.desc, tc.err, err)) diff --git a/auth/spicedb/policies.go b/auth/spicedb/policies.go index 7ac2ba4a2c..74003b26b6 100644 --- a/auth/spicedb/policies.go +++ b/auth/spicedb/policies.go @@ -6,7 +6,6 @@ package spicedb import ( "context" "fmt" - "io" "log/slog" "github.com/absmach/magistrala/auth" @@ -15,21 +14,11 @@ import ( svcerr "github.com/absmach/magistrala/pkg/errors/service" v1 "github.com/authzed/authzed-go/proto/authzed/api/v1" "github.com/authzed/authzed-go/v1" - gstatus "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) -const defRetrieveAllLimit = 1000 - -var ( - errInvalidSubject = errors.New("invalid subject kind") - errAddPolicies = errors.New("failed to add policies") - errRetrievePolicies = errors.New("failed to retrieve policies") - errRemovePolicies = errors.New("failed to remove the policies") - errNoPolicies = errors.New("no policies provided") - errInternal = errors.New("spicedb internal error") -) +var errInternal = errors.New("spicedb internal error") type policyAgent struct { client *authzed.ClientWithExperimental @@ -80,706 +69,6 @@ func (pa *policyAgent) CheckPolicy(ctx context.Context, pr auth.PolicyReq) error return svcerr.ErrAuthorization } -func (pa *policyAgent) AddPolicies(ctx context.Context, prs []auth.PolicyReq) error { - updates := []*v1.RelationshipUpdate{} - var preconds []*v1.Precondition - for _, pr := range prs { - precond, err := pa.addPolicyPreCondition(ctx, pr) - if err != nil { - return err - } - preconds = append(preconds, precond...) - updates = append(updates, &v1.RelationshipUpdate{ - Operation: v1.RelationshipUpdate_OPERATION_CREATE, - Relationship: &v1.Relationship{ - Resource: &v1.ObjectReference{ObjectType: pr.ObjectType, ObjectId: pr.Object}, - Relation: pr.Relation, - Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, - }, - }) - } - if len(updates) == 0 { - return errors.Wrap(errors.ErrMalformedEntity, errNoPolicies) - } - _, err := pa.permissionClient.WriteRelationships(ctx, &v1.WriteRelationshipsRequest{Updates: updates, OptionalPreconditions: preconds}) - if err != nil { - return errors.Wrap(errAddPolicies, handleSpicedbError(err)) - } - return nil -} - -func (pa *policyAgent) AddPolicy(ctx context.Context, pr auth.PolicyReq) error { - precond, err := pa.addPolicyPreCondition(ctx, pr) - if err != nil { - return err - } - - updates := []*v1.RelationshipUpdate{ - { - Operation: v1.RelationshipUpdate_OPERATION_CREATE, - Relationship: &v1.Relationship{ - Resource: &v1.ObjectReference{ObjectType: pr.ObjectType, ObjectId: pr.Object}, - Relation: pr.Relation, - Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, - }, - }, - } - _, err = pa.permissionClient.WriteRelationships(ctx, &v1.WriteRelationshipsRequest{Updates: updates, OptionalPreconditions: precond}) - if err != nil { - return errors.Wrap(errAddPolicies, handleSpicedbError(err)) - } - return nil -} - -func (pa *policyAgent) DeletePolicies(ctx context.Context, prs []auth.PolicyReq) error { - updates := []*v1.RelationshipUpdate{} - for _, pr := range prs { - updates = append(updates, &v1.RelationshipUpdate{ - Operation: v1.RelationshipUpdate_OPERATION_DELETE, - Relationship: &v1.Relationship{ - Resource: &v1.ObjectReference{ObjectType: pr.ObjectType, ObjectId: pr.Object}, - Relation: pr.Relation, - Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, - }, - }) - } - if len(updates) == 0 { - return errors.Wrap(errors.ErrMalformedEntity, errNoPolicies) - } - _, err := pa.permissionClient.WriteRelationships(ctx, &v1.WriteRelationshipsRequest{Updates: updates}) - if err != nil { - return errors.Wrap(errRemovePolicies, handleSpicedbError(err)) - } - return nil -} - -func (pa *policyAgent) DeletePolicyFilter(ctx context.Context, pr auth.PolicyReq) error { - req := &v1.DeleteRelationshipsRequest{ - RelationshipFilter: &v1.RelationshipFilter{ - ResourceType: pr.ObjectType, - OptionalResourceId: pr.Object, - }, - } - - if pr.Relation != "" { - req.RelationshipFilter.OptionalRelation = pr.Relation - } - - if pr.SubjectType != "" { - req.RelationshipFilter.OptionalSubjectFilter = &v1.SubjectFilter{ - SubjectType: pr.SubjectType, - } - if pr.Subject != "" { - req.RelationshipFilter.OptionalSubjectFilter.OptionalSubjectId = pr.Subject - } - if pr.SubjectRelation != "" { - req.RelationshipFilter.OptionalSubjectFilter.OptionalRelation = &v1.SubjectFilter_RelationFilter{ - Relation: pr.SubjectRelation, - } - } - } - - if _, err := pa.permissionClient.DeleteRelationships(ctx, req); err != nil { - return errors.Wrap(errRemovePolicies, handleSpicedbError(err)) - } - return nil -} - -// RetrieveObjects - Listing of things. -func (pa *policyAgent) RetrieveObjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) ([]auth.PolicyRes, string, error) { - resourceReq := &v1.LookupResourcesRequest{ - Consistency: &v1.Consistency{ - Requirement: &v1.Consistency_FullyConsistent{ - FullyConsistent: true, - }, - }, - ResourceObjectType: pr.ObjectType, - Permission: pr.Permission, - Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, - OptionalLimit: uint32(limit), - } - if nextPageToken != "" { - resourceReq.OptionalCursor = &v1.Cursor{Token: nextPageToken} - } - stream, err := pa.permissionClient.LookupResources(ctx, resourceReq) - if err != nil { - return nil, "", errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) - } - resources := []*v1.LookupResourcesResponse{} - var token string - for { - resp, err := stream.Recv() - switch err { - case nil: - resources = append(resources, resp) - case io.EOF: - if len(resources) > 0 && resources[len(resources)-1].AfterResultCursor != nil { - token = resources[len(resources)-1].AfterResultCursor.Token - } - return objectsToAuthPolicies(resources), token, nil - default: - if len(resources) > 0 && resources[len(resources)-1].AfterResultCursor != nil { - token = resources[len(resources)-1].AfterResultCursor.Token - } - return []auth.PolicyRes{}, token, errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) - } - } -} - -func (pa *policyAgent) RetrieveAllObjects(ctx context.Context, pr auth.PolicyReq) ([]auth.PolicyRes, error) { - resourceReq := &v1.LookupResourcesRequest{ - Consistency: &v1.Consistency{ - Requirement: &v1.Consistency_FullyConsistent{ - FullyConsistent: true, - }, - }, - ResourceObjectType: pr.ObjectType, - Permission: pr.Permission, - Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, - } - stream, err := pa.permissionClient.LookupResources(ctx, resourceReq) - if err != nil { - return nil, errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) - } - tuples := []auth.PolicyRes{} - for { - resp, err := stream.Recv() - switch { - case errors.Contains(err, io.EOF): - return tuples, nil - case err != nil: - return tuples, errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) - default: - tuples = append(tuples, auth.PolicyRes{Object: resp.ResourceObjectId}) - } - } -} - -func (pa *policyAgent) RetrieveAllObjectsCount(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - var count uint64 - nextPageToken := "" - for { - relationTuples, npt, err := pa.RetrieveObjects(ctx, pr, nextPageToken, defRetrieveAllLimit) - if err != nil { - return count, err - } - count = count + uint64(len(relationTuples)) - if npt == "" { - break - } - nextPageToken = npt - } - return count, nil -} - -func (pa *policyAgent) RetrieveSubjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) ([]auth.PolicyRes, string, error) { - subjectsReq := v1.LookupSubjectsRequest{ - Consistency: &v1.Consistency{ - Requirement: &v1.Consistency_FullyConsistent{ - FullyConsistent: true, - }, - }, - Resource: &v1.ObjectReference{ObjectType: pr.ObjectType, ObjectId: pr.Object}, - Permission: pr.Permission, - SubjectObjectType: pr.SubjectType, - OptionalSubjectRelation: pr.SubjectRelation, - OptionalConcreteLimit: uint32(limit), - WildcardOption: v1.LookupSubjectsRequest_WILDCARD_OPTION_INCLUDE_WILDCARDS, - } - if nextPageToken != "" { - subjectsReq.OptionalCursor = &v1.Cursor{Token: nextPageToken} - } - stream, err := pa.permissionClient.LookupSubjects(ctx, &subjectsReq) - if err != nil { - return nil, "", errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) - } - subjects := []*v1.LookupSubjectsResponse{} - var token string - for { - resp, err := stream.Recv() - - switch err { - case nil: - subjects = append(subjects, resp) - case io.EOF: - if len(subjects) > 0 && subjects[len(subjects)-1].AfterResultCursor != nil { - token = subjects[len(subjects)-1].AfterResultCursor.Token - } - return subjectsToAuthPolicies(subjects), token, nil - default: - if len(subjects) > 0 && subjects[len(subjects)-1].AfterResultCursor != nil { - token = subjects[len(subjects)-1].AfterResultCursor.Token - } - return []auth.PolicyRes{}, token, errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) - } - } -} - -func (pa *policyAgent) RetrieveAllSubjects(ctx context.Context, pr auth.PolicyReq) ([]auth.PolicyRes, error) { - var tuples []auth.PolicyRes - nextPageToken := "" - for i := 0; ; i++ { - relationTuples, npt, err := pa.RetrieveSubjects(ctx, pr, nextPageToken, defRetrieveAllLimit) - if err != nil { - return tuples, err - } - tuples = append(tuples, relationTuples...) - if npt == "" || (len(tuples) < defRetrieveAllLimit) { - break - } - nextPageToken = npt - } - return tuples, nil -} - -func (pa *policyAgent) RetrieveAllSubjectsCount(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - var count uint64 - nextPageToken := "" - for { - relationTuples, npt, err := pa.RetrieveSubjects(ctx, pr, nextPageToken, defRetrieveAllLimit) - if err != nil { - return count, err - } - count = count + uint64(len(relationTuples)) - if npt == "" { - break - } - nextPageToken = npt - } - return count, nil -} - -func (pa *policyAgent) RetrievePermissions(ctx context.Context, pr auth.PolicyReq, filterPermission []string) (auth.Permissions, error) { - var permissionChecks []*v1.CheckBulkPermissionsRequestItem - for _, fp := range filterPermission { - permissionChecks = append(permissionChecks, &v1.CheckBulkPermissionsRequestItem{ - Resource: &v1.ObjectReference{ - ObjectType: pr.ObjectType, - ObjectId: pr.Object, - }, - Permission: fp, - Subject: &v1.SubjectReference{ - Object: &v1.ObjectReference{ - ObjectType: pr.SubjectType, - ObjectId: pr.Subject, - }, - OptionalRelation: pr.SubjectRelation, - }, - }) - } - resp, err := pa.client.PermissionsServiceClient.CheckBulkPermissions(ctx, &v1.CheckBulkPermissionsRequest{ - Consistency: &v1.Consistency{ - Requirement: &v1.Consistency_FullyConsistent{ - FullyConsistent: true, - }, - }, - Items: permissionChecks, - }) - if err != nil { - return auth.Permissions{}, errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) - } - - permissions := []string{} - for _, pair := range resp.Pairs { - if pair.GetError() != nil { - s := pair.GetError() - return auth.Permissions{}, errors.Wrap(errRetrievePolicies, convertGRPCStatusToError(convertToGrpcStatus(s))) - } - item := pair.GetItem() - req := pair.GetRequest() - if item != nil && req != nil && item.Permissionship == v1.CheckPermissionResponse_PERMISSIONSHIP_HAS_PERMISSION { - permissions = append(permissions, req.GetPermission()) - } - } - return permissions, nil -} - -func objectsToAuthPolicies(objects []*v1.LookupResourcesResponse) []auth.PolicyRes { - var policies []auth.PolicyRes - for _, obj := range objects { - policies = append(policies, auth.PolicyRes{ - Object: obj.GetResourceObjectId(), - }) - } - return policies -} - -func subjectsToAuthPolicies(subjects []*v1.LookupSubjectsResponse) []auth.PolicyRes { - var policies []auth.PolicyRes - for _, sub := range subjects { - policies = append(policies, auth.PolicyRes{ - Subject: sub.Subject.GetSubjectObjectId(), - }) - } - return policies -} - -func (pa *policyAgent) Watch(ctx context.Context, continueToken string) { - stream, err := pa.client.WatchServiceClient.Watch(ctx, &v1.WatchRequest{ - OptionalObjectTypes: []string{}, - OptionalStartCursor: &v1.ZedToken{Token: continueToken}, - }) - if err != nil { - pa.logger.Error(fmt.Sprintf("got error while watching: %s", err.Error())) - } - for { - watchResp, err := stream.Recv() - switch err { - case nil: - pa.publishToStream(watchResp) - case io.EOF: - pa.logger.Info("got EOF while watch streaming") - return - default: - pa.logger.Error(fmt.Sprintf("got error while watch streaming : %s", err.Error())) - return - } - } -} - -func (pa *policyAgent) publishToStream(resp *v1.WatchResponse) { - pa.logger.Info(fmt.Sprintf("Publish next token %s", resp.ChangesThrough.Token)) - - for _, update := range resp.Updates { - operation := v1.RelationshipUpdate_Operation_name[int32(update.Operation)] - objectType := update.Relationship.Resource.ObjectType - objectID := update.Relationship.Resource.ObjectId - relation := update.Relationship.Relation - subjectType := update.Relationship.Subject.Object.ObjectType - subjectRelation := update.Relationship.Subject.OptionalRelation - subjectID := update.Relationship.Subject.Object.ObjectId - - pa.logger.Info(fmt.Sprintf(` - Operation : %s object_type: %s object_id: %s relation: %s subject_type: %s subject_relation: %s subject_id: %s - `, operation, objectType, objectID, relation, subjectType, subjectRelation, subjectID)) - } -} - -func (pa *policyAgent) addPolicyPreCondition(ctx context.Context, pr auth.PolicyReq) ([]*v1.Precondition, error) { - // Checks are required for following ( -> means adding) - // 1.) user -> group (both user groups and channels) - // 2.) user -> thing - // 3.) group -> group (both for adding parent_group and channels) - // 4.) group (channel) -> thing - // 5.) user -> domain - - switch { - // 1.) user -> group (both user groups and channels) - // Checks : - // - USER with ANY RELATION to DOMAIN - // - GROUP with DOMAIN RELATION to DOMAIN - case pr.SubjectType == auth.UserType && pr.ObjectType == auth.GroupType: - return pa.userGroupPreConditions(ctx, pr) - - // 2.) user -> thing - // Checks : - // - USER with ANY RELATION to DOMAIN - // - THING with DOMAIN RELATION to DOMAIN - case pr.SubjectType == auth.UserType && pr.ObjectType == auth.ThingType: - return pa.userThingPreConditions(ctx, pr) - - // 3.) group -> group (both for adding parent_group and channels) - // Checks : - // - CHILD_GROUP with out PARENT_GROUP RELATION with any GROUP - case pr.SubjectType == auth.GroupType && pr.ObjectType == auth.GroupType: - return groupPreConditions(pr) - - // 4.) group (channel) -> thing - // Checks : - // - GROUP (channel) with DOMAIN RELATION to DOMAIN - // - NO GROUP should not have PARENT_GROUP RELATION with GROUP (channel) - // - THING with DOMAIN RELATION to DOMAIN - case pr.SubjectType == auth.GroupType && pr.ObjectType == auth.ThingType: - return channelThingPreCondition(pr) - - // 5.) user -> domain - // Checks : - // - User doesn't have any relation with domain - case pr.SubjectType == auth.UserType && pr.ObjectType == auth.DomainType: - return pa.userDomainPreConditions(ctx, pr) - - // Check thing and group not belongs to other domain before adding to domain - case pr.SubjectType == auth.DomainType && pr.Relation == auth.DomainRelation && (pr.ObjectType == auth.ThingType || pr.ObjectType == auth.GroupType): - preconds := []*v1.Precondition{ - { - Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: pr.ObjectType, - OptionalResourceId: pr.Object, - OptionalRelation: auth.DomainRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.DomainType, - }, - }, - }, - } - return preconds, nil - } - return nil, nil -} - -func (pa *policyAgent) userGroupPreConditions(ctx context.Context, pr auth.PolicyReq) ([]*v1.Precondition, error) { - var preconds []*v1.Precondition - - // user should not have any relation with group - preconds = append(preconds, &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.GroupType, - OptionalResourceId: pr.Object, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.UserType, - OptionalSubjectId: pr.Subject, - }, - }, - }) - isSuperAdmin := false - if err := pa.CheckPolicy(ctx, auth.PolicyReq{ - Subject: pr.Subject, - SubjectType: pr.SubjectType, - Permission: auth.AdminPermission, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - }); err == nil { - isSuperAdmin = true - } - - if !isSuperAdmin { - preconds = append(preconds, &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.DomainType, - OptionalResourceId: pr.Domain, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.UserType, - OptionalSubjectId: pr.Subject, - }, - }, - }) - } - switch { - case pr.ObjectKind == auth.NewGroupKind || pr.ObjectKind == auth.NewChannelKind: - preconds = append(preconds, - &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.GroupType, - OptionalResourceId: pr.Object, - OptionalRelation: auth.DomainRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.DomainType, - }, - }, - }, - ) - default: - preconds = append(preconds, - &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.GroupType, - OptionalResourceId: pr.Object, - OptionalRelation: auth.DomainRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.DomainType, - OptionalSubjectId: pr.Domain, - }, - }, - }, - ) - } - return preconds, nil -} - -func (pa *policyAgent) userThingPreConditions(ctx context.Context, pr auth.PolicyReq) ([]*v1.Precondition, error) { - var preconds []*v1.Precondition - - // user should not have any relation with thing - preconds = append(preconds, &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.ThingType, - OptionalResourceId: pr.Object, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.UserType, - OptionalSubjectId: pr.Subject, - }, - }, - }) - - isSuperAdmin := false - if err := pa.CheckPolicy(ctx, auth.PolicyReq{ - Subject: pr.Subject, - SubjectType: pr.SubjectType, - Permission: auth.AdminPermission, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - }); err == nil { - isSuperAdmin = true - } - - if !isSuperAdmin { - preconds = append(preconds, &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.DomainType, - OptionalResourceId: pr.Domain, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.UserType, - OptionalSubjectId: pr.Subject, - }, - }, - }) - } - switch { - // For New thing - // - THING without DOMAIN RELATION to ANY DOMAIN - case pr.ObjectKind == auth.NewThingKind: - preconds = append(preconds, - &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.ThingType, - OptionalResourceId: pr.Object, - OptionalRelation: auth.DomainRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.DomainType, - }, - }, - }, - ) - default: - // For existing thing - // - THING without DOMAIN RELATION to ANY DOMAIN - preconds = append(preconds, - &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.ThingType, - OptionalResourceId: pr.Object, - OptionalRelation: auth.DomainRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.DomainType, - OptionalSubjectId: pr.Domain, - }, - }, - }, - ) - } - return preconds, nil -} - -func groupPreConditions(pr auth.PolicyReq) ([]*v1.Precondition, error) { - // - PARENT_GROUP (subject) with DOMAIN RELATION to DOMAIN - precond := []*v1.Precondition{ - { - Operation: v1.Precondition_OPERATION_MUST_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.GroupType, - OptionalResourceId: pr.Subject, - OptionalRelation: auth.DomainRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.DomainType, - OptionalSubjectId: pr.Domain, - }, - }, - }, - } - if pr.ObjectKind != auth.ChannelsKind { - precond = append(precond, - &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.GroupType, - OptionalResourceId: pr.Object, - OptionalRelation: auth.ParentGroupRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.GroupType, - }, - }, - }, - ) - } - switch { - // - NEW CHILD_GROUP (object) with out DOMAIN RELATION to ANY DOMAIN - case pr.ObjectType == auth.GroupType && pr.ObjectKind == auth.NewGroupKind: - precond = append(precond, - &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.GroupType, - OptionalResourceId: pr.Object, - OptionalRelation: auth.DomainRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.DomainType, - }, - }, - }, - ) - default: - // - CHILD_GROUP (object) with DOMAIN RELATION to DOMAIN - precond = append(precond, - &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.GroupType, - OptionalResourceId: pr.Object, - OptionalRelation: auth.DomainRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.DomainType, - OptionalSubjectId: pr.Domain, - }, - }, - }, - ) - } - return precond, nil -} - -func channelThingPreCondition(pr auth.PolicyReq) ([]*v1.Precondition, error) { - if pr.SubjectKind != auth.ChannelsKind { - return nil, errors.Wrap(errors.ErrMalformedEntity, errInvalidSubject) - } - precond := []*v1.Precondition{ - { - Operation: v1.Precondition_OPERATION_MUST_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.GroupType, - OptionalResourceId: pr.Subject, - OptionalRelation: auth.DomainRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.DomainType, - OptionalSubjectId: pr.Domain, - }, - }, - }, - { - Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.GroupType, - OptionalRelation: auth.ParentGroupRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.GroupType, - OptionalSubjectId: pr.Subject, - }, - }, - }, - { - Operation: v1.Precondition_OPERATION_MUST_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.ThingType, - OptionalResourceId: pr.Object, - OptionalRelation: auth.DomainRelation, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.DomainType, - OptionalSubjectId: pr.Domain, - }, - }, - }, - } - return precond, nil -} - func handleSpicedbError(err error) error { if st, ok := status.FromError(err); ok { return convertGRPCStatusToError(st) @@ -787,11 +76,6 @@ func handleSpicedbError(err error) error { return err } -func convertToGrpcStatus(gst *gstatus.Status) *status.Status { - st := status.New(codes.Code(gst.Code), gst.GetMessage()) - return st -} - func convertGRPCStatusToError(st *status.Status) error { switch st.Code() { case codes.NotFound: @@ -817,32 +101,3 @@ func convertGRPCStatusToError(st *status.Status) error { return errors.Wrap(fmt.Errorf("unexpected gRPC status: %s (status code:%v)", st.Code().String(), st.Code()), errors.New(st.Message())) } } - -func (pa *policyAgent) userDomainPreConditions(ctx context.Context, pr auth.PolicyReq) ([]*v1.Precondition, error) { - var preconds []*v1.Precondition - - if err := pa.CheckPolicy(ctx, auth.PolicyReq{ - Subject: pr.Subject, - SubjectType: pr.SubjectType, - Permission: auth.AdminPermission, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, - }); err == nil { - return preconds, fmt.Errorf("use already exists in domain") - } - - // user should not have any relation with domain. - preconds = append(preconds, &v1.Precondition{ - Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, - Filter: &v1.RelationshipFilter{ - ResourceType: auth.DomainType, - OptionalResourceId: pr.Object, - OptionalSubjectFilter: &v1.SubjectFilter{ - SubjectType: auth.UserType, - OptionalSubjectId: pr.Subject, - }, - }, - }) - - return preconds, nil -} diff --git a/auth/tracing/tracing.go b/auth/tracing/tracing.go index fe58626b04..ae359ac94e 100644 --- a/auth/tracing/tracing.go +++ b/auth/tracing/tracing.go @@ -8,6 +8,7 @@ import ( "fmt" "github.com/absmach/magistrala/auth" + "github.com/absmach/magistrala/pkg/policy" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) @@ -74,163 +75,6 @@ func (tm *tracingMiddleware) Authorize(ctx context.Context, pr auth.PolicyReq) e return tm.svc.Authorize(ctx, pr) } -func (tm *tracingMiddleware) AddPolicy(ctx context.Context, pr auth.PolicyReq) error { - ctx, span := tm.tracer.Start(ctx, "add_policy", trace.WithAttributes( - attribute.String("subject", pr.Subject), - attribute.String("subject_type", pr.SubjectType), - attribute.String("subject_relation", pr.SubjectRelation), - attribute.String("object", pr.Object), - attribute.String("object_type", pr.ObjectType), - attribute.String("relation", pr.Relation), - attribute.String("permission", pr.Permission), - )) - defer span.End() - - return tm.svc.AddPolicy(ctx, pr) -} - -func (tm *tracingMiddleware) AddPolicies(ctx context.Context, prs []auth.PolicyReq) error { - ctx, span := tm.tracer.Start(ctx, "add_policies", trace.WithAttributes()) - defer span.End() - - return tm.svc.AddPolicies(ctx, prs) -} - -func (tm *tracingMiddleware) DeletePolicyFilter(ctx context.Context, pr auth.PolicyReq) error { - ctx, span := tm.tracer.Start(ctx, "delete_policy", trace.WithAttributes( - attribute.String("subject", pr.Subject), - attribute.String("subject_type", pr.SubjectType), - attribute.String("subject_relation", pr.SubjectRelation), - attribute.String("object", pr.Object), - attribute.String("object_type", pr.ObjectType), - attribute.String("relation", pr.Relation), - attribute.String("permission", pr.Permission), - )) - defer span.End() - - return tm.svc.DeletePolicyFilter(ctx, pr) -} - -func (tm *tracingMiddleware) DeletePolicies(ctx context.Context, prs []auth.PolicyReq) error { - ctx, span := tm.tracer.Start(ctx, "delete_policies", trace.WithAttributes()) - defer span.End() - - return tm.svc.DeletePolicies(ctx, prs) -} - -func (tm *tracingMiddleware) ListObjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (auth.PolicyPage, error) { - ctx, span := tm.tracer.Start(ctx, "list_objects", trace.WithAttributes( - attribute.String("subject", pr.Subject), - attribute.String("subject_type", pr.SubjectType), - attribute.String("subject_kind", pr.SubjectKind), - attribute.String("subject_relation", pr.SubjectRelation), - attribute.String("object", pr.Object), - attribute.String("object_type", pr.ObjectType), - attribute.String("relation", pr.Relation), - attribute.String("permission", pr.Permission), - )) - defer span.End() - - return tm.svc.ListObjects(ctx, pr, nextPageToken, limit) -} - -func (tm *tracingMiddleware) ListAllObjects(ctx context.Context, pr auth.PolicyReq) (auth.PolicyPage, error) { - ctx, span := tm.tracer.Start(ctx, "list_all_objects", trace.WithAttributes( - attribute.String("subject", pr.Subject), - attribute.String("subject_type", pr.SubjectType), - attribute.String("subject_kind", pr.SubjectKind), - attribute.String("subject_relation", pr.SubjectRelation), - attribute.String("object", pr.Object), - attribute.String("object_type", pr.ObjectType), - attribute.String("relation", pr.Relation), - attribute.String("permission", pr.Permission), - )) - defer span.End() - - return tm.svc.ListAllObjects(ctx, pr) -} - -func (tm *tracingMiddleware) CountObjects(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - ctx, span := tm.tracer.Start(ctx, "count_objects", trace.WithAttributes( - attribute.String("subject", pr.Subject), - attribute.String("subject_type", pr.SubjectType), - attribute.String("subject_kind", pr.SubjectKind), - attribute.String("subject_relation", pr.SubjectRelation), - attribute.String("object", pr.Object), - attribute.String("object_type", pr.ObjectType), - attribute.String("relation", pr.Relation), - attribute.String("permission", pr.Permission), - )) - defer span.End() - - return tm.svc.CountObjects(ctx, pr) -} - -func (tm *tracingMiddleware) ListSubjects(ctx context.Context, pr auth.PolicyReq, nextPageToken string, limit uint64) (auth.PolicyPage, error) { - ctx, span := tm.tracer.Start(ctx, "list_subjects", trace.WithAttributes( - attribute.String("subject", pr.Subject), - attribute.String("subject_type", pr.SubjectType), - attribute.String("subject_kind", pr.SubjectKind), - attribute.String("subject_relation", pr.SubjectRelation), - attribute.String("object", pr.Object), - attribute.String("object_type", pr.ObjectType), - attribute.String("relation", pr.Relation), - attribute.String("permission", pr.Permission), - )) - defer span.End() - - return tm.svc.ListSubjects(ctx, pr, nextPageToken, limit) -} - -func (tm *tracingMiddleware) ListAllSubjects(ctx context.Context, pr auth.PolicyReq) (auth.PolicyPage, error) { - ctx, span := tm.tracer.Start(ctx, "list_all_subjects", trace.WithAttributes( - attribute.String("subject", pr.Subject), - attribute.String("subject_type", pr.SubjectType), - attribute.String("subject_kind", pr.SubjectKind), - attribute.String("subject_relation", pr.SubjectRelation), - attribute.String("object", pr.Object), - attribute.String("object_type", pr.ObjectType), - attribute.String("relation", pr.Relation), - attribute.String("permission", pr.Permission), - )) - defer span.End() - - return tm.svc.ListAllSubjects(ctx, pr) -} - -func (tm *tracingMiddleware) CountSubjects(ctx context.Context, pr auth.PolicyReq) (uint64, error) { - ctx, span := tm.tracer.Start(ctx, "count_subjects", trace.WithAttributes( - attribute.String("subject", pr.Subject), - attribute.String("subject_type", pr.SubjectType), - attribute.String("subject_kind", pr.SubjectKind), - attribute.String("subject_relation", pr.SubjectRelation), - attribute.String("object", pr.Object), - attribute.String("object_type", pr.ObjectType), - attribute.String("relation", pr.Relation), - attribute.String("permission", pr.Permission), - )) - defer span.End() - - return tm.svc.CountSubjects(ctx, pr) -} - -func (tm *tracingMiddleware) ListPermissions(ctx context.Context, pr auth.PolicyReq, filterPermissions []string) (auth.Permissions, error) { - ctx, span := tm.tracer.Start(ctx, "list_permissions", trace.WithAttributes( - attribute.String("subject", pr.Subject), - attribute.String("subject_type", pr.SubjectType), - attribute.String("subject_kind", pr.SubjectKind), - attribute.String("subject_relation", pr.SubjectRelation), - attribute.String("object", pr.Object), - attribute.String("object_type", pr.ObjectType), - attribute.String("relation", pr.Relation), - attribute.String("permission", pr.Permission), - attribute.StringSlice("filter_permissions", filterPermissions), - )) - defer span.End() - - return tm.svc.ListPermissions(ctx, pr, filterPermissions) -} - func (tm *tracingMiddleware) CreateDomain(ctx context.Context, token string, d auth.Domain) (auth.Domain, error) { ctx, span := tm.tracer.Start(ctx, "create_domain", trace.WithAttributes( attribute.String("name", d.Name), @@ -247,7 +91,7 @@ func (tm *tracingMiddleware) RetrieveDomain(ctx context.Context, token, id strin return tm.svc.RetrieveDomain(ctx, token, id) } -func (tm *tracingMiddleware) RetrieveDomainPermissions(ctx context.Context, token, id string) (auth.Permissions, error) { +func (tm *tracingMiddleware) RetrieveDomainPermissions(ctx context.Context, token, id string) (policy.Permissions, error) { ctx, span := tm.tracer.Start(ctx, "view_domain_permissions", trace.WithAttributes( attribute.String("id", id), )) @@ -304,11 +148,10 @@ func (tm *tracingMiddleware) ListUserDomains(ctx context.Context, token, userID return tm.svc.ListUserDomains(ctx, token, userID, p) } -func (tm *tracingMiddleware) DeleteEntityPolicies(ctx context.Context, entityType, id string) error { +func (tm *tracingMiddleware) DeleteUserPolicies(ctx context.Context, id string) error { ctx, span := tm.tracer.Start(ctx, "delete_entity_policies", trace.WithAttributes( - attribute.String("entity_type", entityType), attribute.String("id", id), )) defer span.End() - return tm.svc.DeleteEntityPolicies(ctx, entityType, id) + return tm.svc.DeleteUserPolicies(ctx, id) } diff --git a/auth_grpc.pb.go b/auth_grpc.pb.go index cac9ebe723..9abd2b0589 100644 --- a/auth_grpc.pb.go +++ b/auth_grpc.pb.go @@ -296,18 +296,7 @@ var AuthnService_ServiceDesc = grpc.ServiceDesc{ } const ( - PolicyService_AddPolicy_FullMethodName = "/magistrala.PolicyService/AddPolicy" - PolicyService_AddPolicies_FullMethodName = "/magistrala.PolicyService/AddPolicies" - PolicyService_DeletePolicyFilter_FullMethodName = "/magistrala.PolicyService/DeletePolicyFilter" - PolicyService_DeletePolicies_FullMethodName = "/magistrala.PolicyService/DeletePolicies" - PolicyService_ListObjects_FullMethodName = "/magistrala.PolicyService/ListObjects" - PolicyService_ListAllObjects_FullMethodName = "/magistrala.PolicyService/ListAllObjects" - PolicyService_CountObjects_FullMethodName = "/magistrala.PolicyService/CountObjects" - PolicyService_ListSubjects_FullMethodName = "/magistrala.PolicyService/ListSubjects" - PolicyService_ListAllSubjects_FullMethodName = "/magistrala.PolicyService/ListAllSubjects" - PolicyService_CountSubjects_FullMethodName = "/magistrala.PolicyService/CountSubjects" - PolicyService_ListPermissions_FullMethodName = "/magistrala.PolicyService/ListPermissions" - PolicyService_DeleteEntityPolicies_FullMethodName = "/magistrala.PolicyService/DeleteEntityPolicies" + PolicyService_DeleteUserPolicies_FullMethodName = "/magistrala.PolicyService/DeleteUserPolicies" ) // PolicyServiceClient is the client API for PolicyService service. @@ -317,18 +306,7 @@ const ( // PolicyService is a service that provides policy CRUD // functionalities for magistrala services. type PolicyServiceClient interface { - AddPolicy(ctx context.Context, in *AddPolicyReq, opts ...grpc.CallOption) (*AddPolicyRes, error) - AddPolicies(ctx context.Context, in *AddPoliciesReq, opts ...grpc.CallOption) (*AddPoliciesRes, error) - DeletePolicyFilter(ctx context.Context, in *DeletePolicyFilterReq, opts ...grpc.CallOption) (*DeletePolicyRes, error) - DeletePolicies(ctx context.Context, in *DeletePoliciesReq, opts ...grpc.CallOption) (*DeletePolicyRes, error) - ListObjects(ctx context.Context, in *ListObjectsReq, opts ...grpc.CallOption) (*ListObjectsRes, error) - ListAllObjects(ctx context.Context, in *ListObjectsReq, opts ...grpc.CallOption) (*ListObjectsRes, error) - CountObjects(ctx context.Context, in *CountObjectsReq, opts ...grpc.CallOption) (*CountObjectsRes, error) - ListSubjects(ctx context.Context, in *ListSubjectsReq, opts ...grpc.CallOption) (*ListSubjectsRes, error) - ListAllSubjects(ctx context.Context, in *ListSubjectsReq, opts ...grpc.CallOption) (*ListSubjectsRes, error) - CountSubjects(ctx context.Context, in *CountSubjectsReq, opts ...grpc.CallOption) (*CountSubjectsRes, error) - ListPermissions(ctx context.Context, in *ListPermissionsReq, opts ...grpc.CallOption) (*ListPermissionsRes, error) - DeleteEntityPolicies(ctx context.Context, in *DeleteEntityPoliciesReq, opts ...grpc.CallOption) (*DeletePolicyRes, error) + DeleteUserPolicies(ctx context.Context, in *DeleteUserPoliciesReq, opts ...grpc.CallOption) (*DeletePolicyRes, error) } type policyServiceClient struct { @@ -339,120 +317,10 @@ func NewPolicyServiceClient(cc grpc.ClientConnInterface) PolicyServiceClient { return &policyServiceClient{cc} } -func (c *policyServiceClient) AddPolicy(ctx context.Context, in *AddPolicyReq, opts ...grpc.CallOption) (*AddPolicyRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(AddPolicyRes) - err := c.cc.Invoke(ctx, PolicyService_AddPolicy_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) AddPolicies(ctx context.Context, in *AddPoliciesReq, opts ...grpc.CallOption) (*AddPoliciesRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(AddPoliciesRes) - err := c.cc.Invoke(ctx, PolicyService_AddPolicies_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) DeletePolicyFilter(ctx context.Context, in *DeletePolicyFilterReq, opts ...grpc.CallOption) (*DeletePolicyRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(DeletePolicyRes) - err := c.cc.Invoke(ctx, PolicyService_DeletePolicyFilter_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) DeletePolicies(ctx context.Context, in *DeletePoliciesReq, opts ...grpc.CallOption) (*DeletePolicyRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(DeletePolicyRes) - err := c.cc.Invoke(ctx, PolicyService_DeletePolicies_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) ListObjects(ctx context.Context, in *ListObjectsReq, opts ...grpc.CallOption) (*ListObjectsRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ListObjectsRes) - err := c.cc.Invoke(ctx, PolicyService_ListObjects_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) ListAllObjects(ctx context.Context, in *ListObjectsReq, opts ...grpc.CallOption) (*ListObjectsRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ListObjectsRes) - err := c.cc.Invoke(ctx, PolicyService_ListAllObjects_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) CountObjects(ctx context.Context, in *CountObjectsReq, opts ...grpc.CallOption) (*CountObjectsRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(CountObjectsRes) - err := c.cc.Invoke(ctx, PolicyService_CountObjects_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) ListSubjects(ctx context.Context, in *ListSubjectsReq, opts ...grpc.CallOption) (*ListSubjectsRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ListSubjectsRes) - err := c.cc.Invoke(ctx, PolicyService_ListSubjects_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) ListAllSubjects(ctx context.Context, in *ListSubjectsReq, opts ...grpc.CallOption) (*ListSubjectsRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ListSubjectsRes) - err := c.cc.Invoke(ctx, PolicyService_ListAllSubjects_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) CountSubjects(ctx context.Context, in *CountSubjectsReq, opts ...grpc.CallOption) (*CountSubjectsRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(CountSubjectsRes) - err := c.cc.Invoke(ctx, PolicyService_CountSubjects_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) ListPermissions(ctx context.Context, in *ListPermissionsReq, opts ...grpc.CallOption) (*ListPermissionsRes, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ListPermissionsRes) - err := c.cc.Invoke(ctx, PolicyService_ListPermissions_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *policyServiceClient) DeleteEntityPolicies(ctx context.Context, in *DeleteEntityPoliciesReq, opts ...grpc.CallOption) (*DeletePolicyRes, error) { +func (c *policyServiceClient) DeleteUserPolicies(ctx context.Context, in *DeleteUserPoliciesReq, opts ...grpc.CallOption) (*DeletePolicyRes, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(DeletePolicyRes) - err := c.cc.Invoke(ctx, PolicyService_DeleteEntityPolicies_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, PolicyService_DeleteUserPolicies_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -466,18 +334,7 @@ func (c *policyServiceClient) DeleteEntityPolicies(ctx context.Context, in *Dele // PolicyService is a service that provides policy CRUD // functionalities for magistrala services. type PolicyServiceServer interface { - AddPolicy(context.Context, *AddPolicyReq) (*AddPolicyRes, error) - AddPolicies(context.Context, *AddPoliciesReq) (*AddPoliciesRes, error) - DeletePolicyFilter(context.Context, *DeletePolicyFilterReq) (*DeletePolicyRes, error) - DeletePolicies(context.Context, *DeletePoliciesReq) (*DeletePolicyRes, error) - ListObjects(context.Context, *ListObjectsReq) (*ListObjectsRes, error) - ListAllObjects(context.Context, *ListObjectsReq) (*ListObjectsRes, error) - CountObjects(context.Context, *CountObjectsReq) (*CountObjectsRes, error) - ListSubjects(context.Context, *ListSubjectsReq) (*ListSubjectsRes, error) - ListAllSubjects(context.Context, *ListSubjectsReq) (*ListSubjectsRes, error) - CountSubjects(context.Context, *CountSubjectsReq) (*CountSubjectsRes, error) - ListPermissions(context.Context, *ListPermissionsReq) (*ListPermissionsRes, error) - DeleteEntityPolicies(context.Context, *DeleteEntityPoliciesReq) (*DeletePolicyRes, error) + DeleteUserPolicies(context.Context, *DeleteUserPoliciesReq) (*DeletePolicyRes, error) mustEmbedUnimplementedPolicyServiceServer() } @@ -485,41 +342,8 @@ type PolicyServiceServer interface { type UnimplementedPolicyServiceServer struct { } -func (UnimplementedPolicyServiceServer) AddPolicy(context.Context, *AddPolicyReq) (*AddPolicyRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddPolicy not implemented") -} -func (UnimplementedPolicyServiceServer) AddPolicies(context.Context, *AddPoliciesReq) (*AddPoliciesRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddPolicies not implemented") -} -func (UnimplementedPolicyServiceServer) DeletePolicyFilter(context.Context, *DeletePolicyFilterReq) (*DeletePolicyRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeletePolicyFilter not implemented") -} -func (UnimplementedPolicyServiceServer) DeletePolicies(context.Context, *DeletePoliciesReq) (*DeletePolicyRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeletePolicies not implemented") -} -func (UnimplementedPolicyServiceServer) ListObjects(context.Context, *ListObjectsReq) (*ListObjectsRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListObjects not implemented") -} -func (UnimplementedPolicyServiceServer) ListAllObjects(context.Context, *ListObjectsReq) (*ListObjectsRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListAllObjects not implemented") -} -func (UnimplementedPolicyServiceServer) CountObjects(context.Context, *CountObjectsReq) (*CountObjectsRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method CountObjects not implemented") -} -func (UnimplementedPolicyServiceServer) ListSubjects(context.Context, *ListSubjectsReq) (*ListSubjectsRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListSubjects not implemented") -} -func (UnimplementedPolicyServiceServer) ListAllSubjects(context.Context, *ListSubjectsReq) (*ListSubjectsRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListAllSubjects not implemented") -} -func (UnimplementedPolicyServiceServer) CountSubjects(context.Context, *CountSubjectsReq) (*CountSubjectsRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method CountSubjects not implemented") -} -func (UnimplementedPolicyServiceServer) ListPermissions(context.Context, *ListPermissionsReq) (*ListPermissionsRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListPermissions not implemented") -} -func (UnimplementedPolicyServiceServer) DeleteEntityPolicies(context.Context, *DeleteEntityPoliciesReq) (*DeletePolicyRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeleteEntityPolicies not implemented") +func (UnimplementedPolicyServiceServer) DeleteUserPolicies(context.Context, *DeleteUserPoliciesReq) (*DeletePolicyRes, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteUserPolicies not implemented") } func (UnimplementedPolicyServiceServer) mustEmbedUnimplementedPolicyServiceServer() {} @@ -534,218 +358,20 @@ func RegisterPolicyServiceServer(s grpc.ServiceRegistrar, srv PolicyServiceServe s.RegisterService(&PolicyService_ServiceDesc, srv) } -func _PolicyService_AddPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AddPolicyReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).AddPolicy(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_AddPolicy_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).AddPolicy(ctx, req.(*AddPolicyReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_AddPolicies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AddPoliciesReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).AddPolicies(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_AddPolicies_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).AddPolicies(ctx, req.(*AddPoliciesReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_DeletePolicyFilter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeletePolicyFilterReq) +func _PolicyService_DeleteUserPolicies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteUserPoliciesReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(PolicyServiceServer).DeletePolicyFilter(ctx, in) + return srv.(PolicyServiceServer).DeleteUserPolicies(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: PolicyService_DeletePolicyFilter_FullMethodName, + FullMethod: PolicyService_DeleteUserPolicies_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).DeletePolicyFilter(ctx, req.(*DeletePolicyFilterReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_DeletePolicies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeletePoliciesReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).DeletePolicies(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_DeletePolicies_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).DeletePolicies(ctx, req.(*DeletePoliciesReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_ListObjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListObjectsReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).ListObjects(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_ListObjects_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).ListObjects(ctx, req.(*ListObjectsReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_ListAllObjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListObjectsReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).ListAllObjects(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_ListAllObjects_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).ListAllObjects(ctx, req.(*ListObjectsReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_CountObjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CountObjectsReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).CountObjects(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_CountObjects_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).CountObjects(ctx, req.(*CountObjectsReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_ListSubjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListSubjectsReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).ListSubjects(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_ListSubjects_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).ListSubjects(ctx, req.(*ListSubjectsReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_ListAllSubjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListSubjectsReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).ListAllSubjects(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_ListAllSubjects_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).ListAllSubjects(ctx, req.(*ListSubjectsReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_CountSubjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CountSubjectsReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).CountSubjects(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_CountSubjects_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).CountSubjects(ctx, req.(*CountSubjectsReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_ListPermissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListPermissionsReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).ListPermissions(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_ListPermissions_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).ListPermissions(ctx, req.(*ListPermissionsReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _PolicyService_DeleteEntityPolicies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteEntityPoliciesReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyServiceServer).DeleteEntityPolicies(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyService_DeleteEntityPolicies_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyServiceServer).DeleteEntityPolicies(ctx, req.(*DeleteEntityPoliciesReq)) + return srv.(PolicyServiceServer).DeleteUserPolicies(ctx, req.(*DeleteUserPoliciesReq)) } return interceptor(ctx, in, info, handler) } @@ -758,52 +384,8 @@ var PolicyService_ServiceDesc = grpc.ServiceDesc{ HandlerType: (*PolicyServiceServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "AddPolicy", - Handler: _PolicyService_AddPolicy_Handler, - }, - { - MethodName: "AddPolicies", - Handler: _PolicyService_AddPolicies_Handler, - }, - { - MethodName: "DeletePolicyFilter", - Handler: _PolicyService_DeletePolicyFilter_Handler, - }, - { - MethodName: "DeletePolicies", - Handler: _PolicyService_DeletePolicies_Handler, - }, - { - MethodName: "ListObjects", - Handler: _PolicyService_ListObjects_Handler, - }, - { - MethodName: "ListAllObjects", - Handler: _PolicyService_ListAllObjects_Handler, - }, - { - MethodName: "CountObjects", - Handler: _PolicyService_CountObjects_Handler, - }, - { - MethodName: "ListSubjects", - Handler: _PolicyService_ListSubjects_Handler, - }, - { - MethodName: "ListAllSubjects", - Handler: _PolicyService_ListAllSubjects_Handler, - }, - { - MethodName: "CountSubjects", - Handler: _PolicyService_CountSubjects_Handler, - }, - { - MethodName: "ListPermissions", - Handler: _PolicyService_ListPermissions_Handler, - }, - { - MethodName: "DeleteEntityPolicies", - Handler: _PolicyService_DeleteEntityPolicies_Handler, + MethodName: "DeleteUserPolicies", + Handler: _PolicyService_DeleteUserPolicies_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/bootstrap/events/producer/streams_test.go b/bootstrap/events/producer/streams_test.go index cf7625e007..042efcfb07 100644 --- a/bootstrap/events/producer/streams_test.go +++ b/bootstrap/events/producer/streams_test.go @@ -12,7 +12,6 @@ import ( "time" "github.com/absmach/magistrala" - authsvc "github.com/absmach/magistrala/auth" authmocks "github.com/absmach/magistrala/auth/mocks" "github.com/absmach/magistrala/bootstrap" "github.com/absmach/magistrala/bootstrap/events/producer" @@ -21,6 +20,7 @@ import ( "github.com/absmach/magistrala/pkg/errors" svcerr "github.com/absmach/magistrala/pkg/errors/service" "github.com/absmach/magistrala/pkg/events/store" + policysvc "github.com/absmach/magistrala/pkg/policy" policymocks "github.com/absmach/magistrala/pkg/policy/mocks" mgsdk "github.com/absmach/magistrala/pkg/sdk/go" sdkmocks "github.com/absmach/magistrala/pkg/sdk/mocks" @@ -89,14 +89,14 @@ type testVariable struct { svc bootstrap.Service boot *mocks.ConfigRepository auth *authmocks.AuthServiceClient - policy *policymocks.PolicyService + policy *policymocks.PolicyClient sdk *sdkmocks.SDK } func newTestVariable(t *testing.T, redisURL string) testVariable { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -815,7 +815,7 @@ func TestList(t *testing.T) { identifyErr error superAdminAuthRes *magistrala.AuthorizeRes domainAdminAuthRes *magistrala.AuthorizeRes - listObjectsResponse []string + listObjectsResponse policysvc.PolicyPage listObjectsErr error superAdmiAuthErr error domainAdmiAuthErr error @@ -838,7 +838,7 @@ func TestList(t *testing.T) { filter: bootstrap.Filter{}, offset: 0, limit: 10, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, err: nil, event: map[string]interface{}{ "thing_id": c.ThingID, @@ -867,7 +867,7 @@ func TestList(t *testing.T) { filter: bootstrap.Filter{}, offset: 0, limit: 10, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, err: nil, event: map[string]interface{}{ "thing_id": c.ThingID, @@ -896,7 +896,7 @@ func TestList(t *testing.T) { filter: bootstrap.Filter{}, offset: 0, limit: 10, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, err: nil, event: map[string]interface{}{ "thing_id": c.ThingID, @@ -927,7 +927,7 @@ func TestList(t *testing.T) { filter: bootstrap.Filter{}, offset: 0, limit: 10, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, superAdmiAuthErr: svcerr.ErrAuthorization, err: nil, @@ -941,7 +941,7 @@ func TestList(t *testing.T) { filter: bootstrap.Filter{}, offset: 0, limit: 10, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, superAdmiAuthErr: svcerr.ErrAuthorization, @@ -957,7 +957,7 @@ func TestList(t *testing.T) { filter: bootstrap.Filter{}, offset: 0, limit: 10, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, listObjectsErr: svcerr.ErrNotFound, @@ -973,7 +973,7 @@ func TestList(t *testing.T) { filter: bootstrap.Filter{}, offset: 0, limit: 10, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, retrieveErr: nil, err: nil, @@ -987,7 +987,7 @@ func TestList(t *testing.T) { filter: bootstrap.Filter{}, offset: 0, limit: 10, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, retrieveErr: nil, @@ -1002,7 +1002,7 @@ func TestList(t *testing.T) { filter: bootstrap.Filter{}, offset: 0, limit: 10, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, retrieveErr: nil, @@ -1015,25 +1015,25 @@ func TestList(t *testing.T) { for _, tc := range cases { authCall := tv.auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: tc.userID, DomainId: tc.domainID}, tc.identifyErr) authCall1 := tv.auth.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, + SubjectType: policysvc.UserType, Subject: tc.userID, - Permission: authsvc.AdminPermission, - ObjectType: authsvc.PlatformType, - Object: authsvc.MagistralaObject, + Permission: policysvc.AdminPermission, + ObjectType: policysvc.PlatformType, + Object: policysvc.MagistralaObject, }).Return(tc.superAdminAuthRes, tc.superAdmiAuthErr) authCall2 := tv.auth.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.userID, - Permission: authsvc.AdminPermission, - ObjectType: authsvc.DomainType, + Permission: policysvc.AdminPermission, + ObjectType: policysvc.DomainType, Object: tc.domainID, }).Return(tc.domainAdminAuthRes, tc.domainAdmiAuthErr) - authCall3 := tv.policy.On("ListAllObjects", mock.Anything, &magistrala.ListObjectsReq{ - SubjectType: authsvc.UserType, + authCall3 := tv.policy.On("ListAllObjects", mock.Anything, policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Subject: tc.userID, - Permission: authsvc.ViewPermission, - ObjectType: authsvc.ThingType, + Permission: policysvc.ViewPermission, + ObjectType: policysvc.ThingType, }).Return(tc.listObjectsResponse, tc.listObjectsErr) repoCall := tv.boot.On("RetrieveAll", context.Background(), mock.Anything, mock.Anything, tc.filter, tc.offset, tc.limit).Return(tc.config, tc.retrieveErr) diff --git a/bootstrap/service.go b/bootstrap/service.go index cf8d1c76dc..e91306e3a9 100644 --- a/bootstrap/service.go +++ b/bootstrap/service.go @@ -122,7 +122,7 @@ type ConfigReader interface { type bootstrapService struct { auth grpcclient.AuthServiceClient - policy policy.PolicyService + policy policy.PolicyClient configs ConfigRepository sdk mgsdk.SDK encKey []byte @@ -130,12 +130,12 @@ type bootstrapService struct { } // New returns new Bootstrap service. -func New(auth grpcclient.AuthServiceClient, policyService policy.PolicyService, configs ConfigRepository, sdk mgsdk.SDK, encKey []byte, idp magistrala.IDProvider) Service { +func New(authClient grpcclient.AuthServiceClient, policyClient policy.PolicyClient, configs ConfigRepository, sdk mgsdk.SDK, encKey []byte, idp magistrala.IDProvider) Service { return &bootstrapService{ configs: configs, sdk: sdk, - auth: auth, - policy: policyService, + auth: authClient, + policy: policyClient, encKey: encKey, idProvider: idp, } @@ -306,7 +306,7 @@ func (bs bootstrapService) UpdateConnections(ctx context.Context, token, id stri } func (bs bootstrapService) listClientIDs(ctx context.Context, userID string) ([]string, error) { - tids, err := bs.policy.ListAllObjects(ctx, &magistrala.ListObjectsReq{ + tids, err := bs.policy.ListAllObjects(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Permission: auth.ViewPermission, @@ -315,7 +315,7 @@ func (bs bootstrapService) listClientIDs(ctx context.Context, userID string) ([] if err != nil { return nil, errors.Wrap(svcerr.ErrNotFound, err) } - return tids, nil + return tids.Policies, nil } func (bs bootstrapService) checkSuperAdmin(ctx context.Context, userID string) error { diff --git a/bootstrap/service_test.go b/bootstrap/service_test.go index d98f59d90a..2ea7d2881d 100644 --- a/bootstrap/service_test.go +++ b/bootstrap/service_test.go @@ -15,13 +15,13 @@ import ( "testing" "github.com/absmach/magistrala" - authsvc "github.com/absmach/magistrala/auth" authmocks "github.com/absmach/magistrala/auth/mocks" "github.com/absmach/magistrala/bootstrap" "github.com/absmach/magistrala/bootstrap/mocks" "github.com/absmach/magistrala/internal/testsutil" "github.com/absmach/magistrala/pkg/errors" svcerr "github.com/absmach/magistrala/pkg/errors/service" + policysvc "github.com/absmach/magistrala/pkg/policy" policymocks "github.com/absmach/magistrala/pkg/policy/mocks" mgsdk "github.com/absmach/magistrala/pkg/sdk/go" sdkmocks "github.com/absmach/magistrala/pkg/sdk/mocks" @@ -78,7 +78,7 @@ func enc(in []byte) ([]byte, error) { func TestAdd(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -214,7 +214,7 @@ func TestAdd(t *testing.T) { func TestView(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -313,7 +313,7 @@ func TestView(t *testing.T) { func TestUpdate(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -405,7 +405,7 @@ func TestUpdate(t *testing.T) { func TestUpdateCert(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -521,7 +521,7 @@ func TestUpdateCert(t *testing.T) { func TestUpdateConnections(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -641,7 +641,7 @@ func TestUpdateConnections(t *testing.T) { func TestList(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -671,7 +671,7 @@ func TestList(t *testing.T) { domainAdminAuthRes *magistrala.AuthorizeRes superAdmiAuthErr error domainAdmiAuthErr error - listObjectsResponse []string + listObjectsResponse policysvc.PolicyPage authorizeErr error identifyErr error listObjectsErr error @@ -691,7 +691,7 @@ func TestList(t *testing.T) { userID: validID, domainID: domainID, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, offset: 0, limit: 10, err: nil, @@ -704,7 +704,7 @@ func TestList(t *testing.T) { userID: validID, domainID: domainID, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, offset: 0, limit: 10, err: nil, @@ -723,7 +723,7 @@ func TestList(t *testing.T) { domainID: domainID, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, offset: 0, limit: 10, err: nil, @@ -737,7 +737,7 @@ func TestList(t *testing.T) { domainID: domainID, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, offset: 0, limit: 10, err: nil, @@ -756,7 +756,7 @@ func TestList(t *testing.T) { domainID: domainID, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, - listObjectsResponse: []string{"test", "test"}, + listObjectsResponse: policysvc.PolicyPage{Policies: []string{"test", "test"}}, offset: 0, limit: 10, err: nil, @@ -810,7 +810,7 @@ func TestList(t *testing.T) { domainID: domainID, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, - listObjectsResponse: []string{"test", "test"}, + listObjectsResponse: policysvc.PolicyPage{Policies: []string{"test", "test"}}, offset: 0, limit: 100, err: nil, @@ -891,7 +891,7 @@ func TestList(t *testing.T) { domainID: domainID, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, - listObjectsResponse: []string{"test", "test"}, + listObjectsResponse: policysvc.PolicyPage{Policies: []string{"test", "test"}}, offset: 95, limit: 10, err: nil, @@ -946,7 +946,7 @@ func TestList(t *testing.T) { domainID: domainID, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, - listObjectsResponse: []string{"test", "test"}, + listObjectsResponse: policysvc.PolicyPage{Policies: []string{"test", "test"}}, offset: 35, limit: 20, err: nil, @@ -962,7 +962,7 @@ func TestList(t *testing.T) { domainID: domainID, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, domainAdminAuthRes: &magistrala.AuthorizeRes{Authorized: false}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, listObjectsErr: svcerr.ErrNotFound, err: svcerr.ErrNotFound, }, @@ -971,25 +971,25 @@ func TestList(t *testing.T) { for _, tc := range cases { authCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: tc.userID, DomainId: tc.domainID}, tc.identifyErr) authCall1 := auth.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, + SubjectType: policysvc.UserType, Subject: tc.userID, - Permission: authsvc.AdminPermission, - ObjectType: authsvc.PlatformType, - Object: authsvc.MagistralaObject, + Permission: policysvc.AdminPermission, + ObjectType: policysvc.PlatformType, + Object: policysvc.MagistralaObject, }).Return(tc.superAdminAuthRes, tc.superAdmiAuthErr) authCall2 := auth.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.userID, - Permission: authsvc.AdminPermission, - ObjectType: authsvc.DomainType, + Permission: policysvc.AdminPermission, + ObjectType: policysvc.DomainType, Object: tc.domainID, }).Return(tc.domainAdminAuthRes, tc.domainAdmiAuthErr) - authCall3 := policy.On("ListAllObjects", mock.Anything, &magistrala.ListObjectsReq{ - SubjectType: authsvc.UserType, + authCall3 := policy.On("ListAllObjects", mock.Anything, policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Subject: tc.userID, - Permission: authsvc.ViewPermission, - ObjectType: authsvc.ThingType, + Permission: policysvc.ViewPermission, + ObjectType: policysvc.ThingType, }).Return(tc.listObjectsResponse, tc.listObjectsErr) repoCall := boot.On("RetrieveAll", context.Background(), mock.Anything, mock.Anything, tc.filter, tc.offset, tc.limit).Return(tc.config, tc.retrieveErr) @@ -1008,7 +1008,7 @@ func TestList(t *testing.T) { func TestRemove(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -1097,7 +1097,7 @@ func TestRemove(t *testing.T) { func TestBootstrap(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -1170,7 +1170,7 @@ func TestBootstrap(t *testing.T) { func TestChangeState(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -1276,7 +1276,7 @@ func TestChangeState(t *testing.T) { func TestUpdateChannelHandler(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -1315,7 +1315,7 @@ func TestUpdateChannelHandler(t *testing.T) { func TestRemoveChannelHandler(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -1348,7 +1348,7 @@ func TestRemoveChannelHandler(t *testing.T) { func TestRemoveConfigHandler(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -1381,7 +1381,7 @@ func TestRemoveConfigHandler(t *testing.T) { func TestConnectThingsHandler(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) @@ -1417,7 +1417,7 @@ func TestConnectThingsHandler(t *testing.T) { func TestDisconnectThingsHandler(t *testing.T) { boot := new(mocks.ConfigRepository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) sdk := new(sdkmocks.SDK) idp := uuid.NewMock() svc := bootstrap.New(auth, policy, boot, sdk, encKey, idp) diff --git a/cmd/auth/main.go b/cmd/auth/main.go index d4074d920c..f0856f9baf 100644 --- a/cmd/auth/main.go +++ b/cmd/auth/main.go @@ -23,6 +23,7 @@ import ( apostgres "github.com/absmach/magistrala/auth/postgres" "github.com/absmach/magistrala/auth/spicedb" "github.com/absmach/magistrala/auth/tracing" + mgpolicy "github.com/absmach/magistrala/internal/policy" mglog "github.com/absmach/magistrala/logger" "github.com/absmach/magistrala/pkg/jaeger" "github.com/absmach/magistrala/pkg/postgres" @@ -212,9 +213,11 @@ func newService(ctx context.Context, db *sqlx.DB, tracer trace.Tracer, cfg confi pa := spicedb.NewPolicyAgent(spicedbClient, logger) idProvider := uuid.New() + policyClient := mgpolicy.NewPolicyClient(spicedbClient, logger) + t := jwt.New([]byte(cfg.SecretKey)) - svc := auth.New(keysRepo, domainsRepo, idProvider, t, pa, cfg.AccessDuration, cfg.RefreshDuration, cfg.InvitationDuration) + svc := auth.New(keysRepo, domainsRepo, idProvider, t, pa, policyClient, cfg.AccessDuration, cfg.RefreshDuration, cfg.InvitationDuration) svc, err := events.NewEventStoreMiddleware(ctx, svc, cfg.ESURL) if err != nil { logger.Error(fmt.Sprintf("failed to init event store middleware : %s", err)) diff --git a/cmd/bootstrap/main.go b/cmd/bootstrap/main.go index edc88e36a7..b59363e9c3 100644 --- a/cmd/bootstrap/main.go +++ b/cmd/bootstrap/main.go @@ -27,6 +27,7 @@ import ( "github.com/absmach/magistrala/pkg/events/store" "github.com/absmach/magistrala/pkg/grpcclient" "github.com/absmach/magistrala/pkg/jaeger" + "github.com/absmach/magistrala/pkg/policy" "github.com/absmach/magistrala/pkg/postgres" pgclient "github.com/absmach/magistrala/pkg/postgres" "github.com/absmach/magistrala/pkg/prometheus" @@ -34,10 +35,14 @@ import ( "github.com/absmach/magistrala/pkg/server" httpserver "github.com/absmach/magistrala/pkg/server/http" "github.com/absmach/magistrala/pkg/uuid" + "github.com/authzed/authzed-go/v1" + "github.com/authzed/grpcutil" "github.com/caarlos0/env/v10" "github.com/jmoiron/sqlx" "go.opentelemetry.io/otel/trace" "golang.org/x/sync/errgroup" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) const ( @@ -53,15 +58,19 @@ const ( ) type config struct { - LogLevel string `env:"MG_BOOTSTRAP_LOG_LEVEL" envDefault:"info"` - EncKey string `env:"MG_BOOTSTRAP_ENCRYPT_KEY" envDefault:"12345678910111213141516171819202"` - ESConsumerName string `env:"MG_BOOTSTRAP_EVENT_CONSUMER" envDefault:"bootstrap"` - ThingsURL string `env:"MG_THINGS_URL" envDefault:"http://localhost:9000"` - JaegerURL url.URL `env:"MG_JAEGER_URL" envDefault:"http://localhost:4318/v1/traces"` - SendTelemetry bool `env:"MG_SEND_TELEMETRY" envDefault:"true"` - InstanceID string `env:"MG_BOOTSTRAP_INSTANCE_ID" envDefault:""` - ESURL string `env:"MG_ES_URL" envDefault:"nats://localhost:4222"` - TraceRatio float64 `env:"MG_JAEGER_TRACE_RATIO" envDefault:"1.0"` + LogLevel string `env:"MG_BOOTSTRAP_LOG_LEVEL" envDefault:"info"` + EncKey string `env:"MG_BOOTSTRAP_ENCRYPT_KEY" envDefault:"12345678910111213141516171819202"` + ESConsumerName string `env:"MG_BOOTSTRAP_EVENT_CONSUMER" envDefault:"bootstrap"` + ThingsURL string `env:"MG_THINGS_URL" envDefault:"http://localhost:9000"` + JaegerURL url.URL `env:"MG_JAEGER_URL" envDefault:"http://localhost:4318/v1/traces"` + SendTelemetry bool `env:"MG_SEND_TELEMETRY" envDefault:"true"` + InstanceID string `env:"MG_BOOTSTRAP_INSTANCE_ID" envDefault:""` + ESURL string `env:"MG_ES_URL" envDefault:"nats://localhost:4222"` + TraceRatio float64 `env:"MG_JAEGER_TRACE_RATIO" envDefault:"1.0"` + SpicedbHost string `env:"MG_SPICEDB_HOST" envDefault:"localhost"` + SpicedbPort string `env:"MG_SPICEDB_PORT" envDefault:"50051"` + SpicedbSchemaFile string `env:"MG_SPICEDB_SCHEMA_FILE" envDefault:"./docker/spicedb/schema.zed"` + SpicedbPreSharedKey string `env:"MG_SPICEDB_PRE_SHARED_KEY" envDefault:"12345678"` } func main() { @@ -118,14 +127,13 @@ func main() { defer authHandler.Close() logger.Info("AuthService gRPC client successfully connected to auth gRPC server " + authHandler.Secure()) - policyClient, policyHandler, err := grpcclient.SetupPolicyClient(ctx, clientConfig) + policyClient, err := newPolicyClient(cfg, logger) if err != nil { logger.Error(err.Error()) exitCode = 1 return } - defer policyHandler.Close() - logger.Info("PolicyService gRPC client successfully connected to auth gRPC server " + policyHandler.Secure()) + logger.Info("Policy client successfully connected to spicedb gRPC server") tp, err := jaeger.NewProvider(ctx, svcName, cfg.JaegerURL, cfg.InstanceID, cfg.TraceRatio) if err != nil { @@ -182,7 +190,7 @@ func main() { } } -func newService(ctx context.Context, authClient authclient.AuthServiceClient, policyClient magistrala.PolicyServiceClient, db *sqlx.DB, tracer trace.Tracer, logger *slog.Logger, cfg config, dbConfig pgclient.Config) (bootstrap.Service, error) { +func newService(ctx context.Context, authClient authclient.AuthServiceClient, policyClient policy.PolicyClient, db *sqlx.DB, tracer trace.Tracer, logger *slog.Logger, cfg config, dbConfig pgclient.Config) (bootstrap.Service, error) { database := postgres.NewDatabase(db, dbConfig, tracer) repoConfig := bootstrappg.NewConfigRepository(database, logger) @@ -194,9 +202,7 @@ func newService(ctx context.Context, authClient authclient.AuthServiceClient, po sdk := mgsdk.NewSDK(config) idp := uuid.New() - policyService := mgpolicy.NewService(policyClient) - - svc := bootstrap.New(authClient, policyService, repoConfig, sdk, []byte(cfg.EncKey), idp) + svc := bootstrap.New(authClient, policyClient, repoConfig, sdk, []byte(cfg.EncKey), idp) publisher, err := store.NewPublisher(ctx, cfg.ESURL, streamID) if err != nil { @@ -225,3 +231,17 @@ func subscribeToThingsES(ctx context.Context, svc bootstrap.Service, cfg config, } return subscriber.Subscribe(ctx, subConfig) } + +func newPolicyClient(cfg config, logger *slog.Logger) (policy.PolicyClient, error) { + client, err := authzed.NewClientWithExperimentalAPIs( + fmt.Sprintf("%s:%s", cfg.SpicedbHost, cfg.SpicedbPort), + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpcutil.WithInsecureBearerToken(cfg.SpicedbPreSharedKey), + ) + if err != nil { + return nil, err + } + policyClient := mgpolicy.NewPolicyClient(client, logger) + + return policyClient, nil +} diff --git a/cmd/things/main.go b/cmd/things/main.go index 5b630da6fb..8d7b3ee4f9 100644 --- a/cmd/things/main.go +++ b/cmd/things/main.go @@ -27,6 +27,7 @@ import ( "github.com/absmach/magistrala/pkg/groups" "github.com/absmach/magistrala/pkg/grpcclient" jaegerclient "github.com/absmach/magistrala/pkg/jaeger" + "github.com/absmach/magistrala/pkg/policy" "github.com/absmach/magistrala/pkg/postgres" pgclient "github.com/absmach/magistrala/pkg/postgres" "github.com/absmach/magistrala/pkg/prometheus" @@ -43,6 +44,8 @@ import ( thingspg "github.com/absmach/magistrala/things/postgres" localusers "github.com/absmach/magistrala/things/standalone" ctracing "github.com/absmach/magistrala/things/tracing" + "github.com/authzed/authzed-go/v1" + "github.com/authzed/grpcutil" "github.com/caarlos0/env/v10" "github.com/go-chi/chi/v5" "github.com/go-redis/redis/v8" @@ -50,6 +53,7 @@ import ( "go.opentelemetry.io/otel/trace" "golang.org/x/sync/errgroup" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/reflection" ) @@ -67,16 +71,20 @@ const ( ) type config struct { - LogLevel string `env:"MG_THINGS_LOG_LEVEL" envDefault:"info"` - StandaloneID string `env:"MG_THINGS_STANDALONE_ID" envDefault:""` - StandaloneToken string `env:"MG_THINGS_STANDALONE_TOKEN" envDefault:""` - JaegerURL url.URL `env:"MG_JAEGER_URL" envDefault:"http://localhost:4318/v1/traces"` - CacheKeyDuration time.Duration `env:"MG_THINGS_CACHE_KEY_DURATION" envDefault:"10m"` - SendTelemetry bool `env:"MG_SEND_TELEMETRY" envDefault:"true"` - InstanceID string `env:"MG_THINGS_INSTANCE_ID" envDefault:""` - ESURL string `env:"MG_ES_URL" envDefault:"nats://localhost:4222"` - CacheURL string `env:"MG_THINGS_CACHE_URL" envDefault:"redis://localhost:6379/0"` - TraceRatio float64 `env:"MG_JAEGER_TRACE_RATIO" envDefault:"1.0"` + LogLevel string `env:"MG_THINGS_LOG_LEVEL" envDefault:"info"` + StandaloneID string `env:"MG_THINGS_STANDALONE_ID" envDefault:""` + StandaloneToken string `env:"MG_THINGS_STANDALONE_TOKEN" envDefault:""` + JaegerURL url.URL `env:"MG_JAEGER_URL" envDefault:"http://localhost:4318/v1/traces"` + CacheKeyDuration time.Duration `env:"MG_THINGS_CACHE_KEY_DURATION" envDefault:"10m"` + SendTelemetry bool `env:"MG_SEND_TELEMETRY" envDefault:"true"` + InstanceID string `env:"MG_THINGS_INSTANCE_ID" envDefault:""` + ESURL string `env:"MG_ES_URL" envDefault:"nats://localhost:4222"` + CacheURL string `env:"MG_THINGS_CACHE_URL" envDefault:"redis://localhost:6379/0"` + TraceRatio float64 `env:"MG_JAEGER_TRACE_RATIO" envDefault:"1.0"` + SpicedbHost string `env:"MG_SPICEDB_HOST" envDefault:"localhost"` + SpicedbPort string `env:"MG_SPICEDB_PORT" envDefault:"50051"` + SpicedbSchemaFile string `env:"MG_SPICEDB_SCHEMA_FILE" envDefault:"./docker/spicedb/schema.zed"` + SpicedbPreSharedKey string `env:"MG_SPICEDB_PRE_SHARED_KEY" envDefault:"12345678"` } func main() { @@ -148,12 +156,12 @@ func main() { var ( authClient authclient.AuthServiceClient - policyClient magistrala.PolicyServiceClient + policyClient policy.PolicyClient ) switch cfg.StandaloneID != "" && cfg.StandaloneToken != "" { case true: - authClient = localusers.NewAuthService(cfg.StandaloneID, cfg.StandaloneToken) - policyClient = localusers.NewPolicyService(cfg.StandaloneID, cfg.StandaloneToken) + authClient = localusers.NewAuthClient(cfg.StandaloneID, cfg.StandaloneToken) + policyClient = localusers.NewPolicyClient(cfg.StandaloneID, cfg.StandaloneToken) logger.Info("Using standalone auth service") default: clientConfig := grpcclient.Config{} @@ -173,15 +181,13 @@ func main() { authClient = authServiceClient logger.Info("AuthService gRPC client successfully connected to auth gRPC server " + authHandler.Secure()) - policyServiceClient, policyHandler, err := grpcclient.SetupPolicyClient(ctx, clientConfig) + policyClient, err = newPolicyClient(cfg, logger) if err != nil { logger.Error(err.Error()) exitCode = 1 return } - defer policyHandler.Close() - policyClient = policyServiceClient - logger.Info("PolicyService gRPC client successfully connected to auth gRPC server " + policyHandler.Secure()) + logger.Info("Policy client successfully connected to spicedb gRPC server") } csvc, gsvc, err := newService(ctx, db, dbConfig, authClient, policyClient, cacheclient, cfg.CacheKeyDuration, cfg.ESURL, tracer, logger) @@ -235,7 +241,7 @@ func main() { } } -func newService(ctx context.Context, db *sqlx.DB, dbConfig pgclient.Config, authClient authclient.AuthServiceClient, policyClient magistrala.PolicyServiceClient, cacheClient *redis.Client, keyDuration time.Duration, esURL string, tracer trace.Tracer, logger *slog.Logger) (things.Service, groups.Service, error) { +func newService(ctx context.Context, db *sqlx.DB, dbConfig pgclient.Config, authClient authclient.AuthServiceClient, policyClient policy.PolicyClient, cacheClient *redis.Client, keyDuration time.Duration, esURL string, tracer trace.Tracer, logger *slog.Logger) (things.Service, groups.Service, error) { database := postgres.NewDatabase(db, dbConfig, tracer) cRepo := thingspg.NewRepository(database) gRepo := gpostgres.New(database) @@ -244,10 +250,8 @@ func newService(ctx context.Context, db *sqlx.DB, dbConfig pgclient.Config, auth thingCache := thcache.NewCache(cacheClient, keyDuration) - policyService := mgpolicy.NewService(policyClient) - - csvc := things.NewService(authClient, policyService, cRepo, gRepo, thingCache, idp) - gsvc := mggroups.NewService(gRepo, idp, authClient, policyService) + csvc := things.NewService(authClient, policyClient, cRepo, gRepo, thingCache, idp) + gsvc := mggroups.NewService(gRepo, idp, authClient, policyClient) csvc, err := thevents.NewEventStoreMiddleware(ctx, csvc, esURL) if err != nil { @@ -271,3 +275,17 @@ func newService(ctx context.Context, db *sqlx.DB, dbConfig pgclient.Config, auth return csvc, gsvc, err } + +func newPolicyClient(cfg config, logger *slog.Logger) (policy.PolicyClient, error) { + client, err := authzed.NewClientWithExperimentalAPIs( + fmt.Sprintf("%s:%s", cfg.SpicedbHost, cfg.SpicedbPort), + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpcutil.WithInsecureBearerToken(cfg.SpicedbPreSharedKey), + ) + if err != nil { + return nil, err + } + policyClient := mgpolicy.NewPolicyClient(client, logger) + + return policyClient, nil +} diff --git a/cmd/users/main.go b/cmd/users/main.go index 2b907c4efb..7a6b0de1c5 100644 --- a/cmd/users/main.go +++ b/cmd/users/main.go @@ -27,7 +27,6 @@ import ( mgpolicy "github.com/absmach/magistrala/internal/policy" mglog "github.com/absmach/magistrala/logger" mgclients "github.com/absmach/magistrala/pkg/clients" - svcerr "github.com/absmach/magistrala/pkg/errors/service" "github.com/absmach/magistrala/pkg/groups" "github.com/absmach/magistrala/pkg/grpcclient" jaegerclient "github.com/absmach/magistrala/pkg/jaeger" @@ -47,11 +46,15 @@ import ( "github.com/absmach/magistrala/users/hasher" clientspg "github.com/absmach/magistrala/users/postgres" ctracing "github.com/absmach/magistrala/users/tracing" + "github.com/authzed/authzed-go/v1" + "github.com/authzed/grpcutil" "github.com/caarlos0/env/v10" "github.com/go-chi/chi/v5" "github.com/jmoiron/sqlx" "go.opentelemetry.io/otel/trace" "golang.org/x/sync/errgroup" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) const ( @@ -67,22 +70,26 @@ const ( ) type config struct { - LogLevel string `env:"MG_USERS_LOG_LEVEL" envDefault:"info"` - AdminEmail string `env:"MG_USERS_ADMIN_EMAIL" envDefault:"admin@example.com"` - AdminPassword string `env:"MG_USERS_ADMIN_PASSWORD" envDefault:"12345678"` - PassRegexText string `env:"MG_USERS_PASS_REGEX" envDefault:"^.{8,}$"` - ResetURL string `env:"MG_TOKEN_RESET_ENDPOINT" envDefault:"/reset-request"` - JaegerURL url.URL `env:"MG_JAEGER_URL" envDefault:"http://localhost:4318/v1/traces"` - SendTelemetry bool `env:"MG_SEND_TELEMETRY" envDefault:"true"` - InstanceID string `env:"MG_USERS_INSTANCE_ID" envDefault:""` - ESURL string `env:"MG_ES_URL" envDefault:"nats://localhost:4222"` - TraceRatio float64 `env:"MG_JAEGER_TRACE_RATIO" envDefault:"1.0"` - SelfRegister bool `env:"MG_USERS_ALLOW_SELF_REGISTER" envDefault:"false"` - OAuthUIRedirectURL string `env:"MG_OAUTH_UI_REDIRECT_URL" envDefault:"http://localhost:9095/domains"` - OAuthUIErrorURL string `env:"MG_OAUTH_UI_ERROR_URL" envDefault:"http://localhost:9095/error"` - DeleteInterval time.Duration `env:"MG_USERS_DELETE_INTERVAL" envDefault:"24h"` - DeleteAfter time.Duration `env:"MG_USERS_DELETE_AFTER" envDefault:"720h"` - PassRegex *regexp.Regexp + LogLevel string `env:"MG_USERS_LOG_LEVEL" envDefault:"info"` + AdminEmail string `env:"MG_USERS_ADMIN_EMAIL" envDefault:"admin@example.com"` + AdminPassword string `env:"MG_USERS_ADMIN_PASSWORD" envDefault:"12345678"` + PassRegexText string `env:"MG_USERS_PASS_REGEX" envDefault:"^.{8,}$"` + ResetURL string `env:"MG_TOKEN_RESET_ENDPOINT" envDefault:"/reset-request"` + JaegerURL url.URL `env:"MG_JAEGER_URL" envDefault:"http://localhost:4318/v1/traces"` + SendTelemetry bool `env:"MG_SEND_TELEMETRY" envDefault:"true"` + InstanceID string `env:"MG_USERS_INSTANCE_ID" envDefault:""` + ESURL string `env:"MG_ES_URL" envDefault:"nats://localhost:4222"` + TraceRatio float64 `env:"MG_JAEGER_TRACE_RATIO" envDefault:"1.0"` + SelfRegister bool `env:"MG_USERS_ALLOW_SELF_REGISTER" envDefault:"false"` + OAuthUIRedirectURL string `env:"MG_OAUTH_UI_REDIRECT_URL" envDefault:"http://localhost:9095/domains"` + OAuthUIErrorURL string `env:"MG_OAUTH_UI_ERROR_URL" envDefault:"http://localhost:9095/error"` + DeleteInterval time.Duration `env:"MG_USERS_DELETE_INTERVAL" envDefault:"24h"` + DeleteAfter time.Duration `env:"MG_USERS_DELETE_AFTER" envDefault:"720h"` + SpicedbHost string `env:"MG_SPICEDB_HOST" envDefault:"localhost"` + SpicedbPort string `env:"MG_SPICEDB_PORT" envDefault:"50051"` + SpicedbSchemaFile string `env:"MG_SPICEDB_SCHEMA_FILE" envDefault:"./docker/spicedb/schema.zed"` + SpicedbPreSharedKey string `env:"MG_SPICEDB_PRE_SHARED_KEY" envDefault:"12345678"` + PassRegex *regexp.Regexp } func main() { @@ -168,16 +175,24 @@ func main() { defer authHandler.Close() logger.Info("AuthService gRPC client successfully connected to auth gRPC server " + authHandler.Secure()) - policyClient, policyHandler, err := grpcclient.SetupPolicyClient(ctx, clientConfig) + authPolicyClient, authPolicyHandler, err := grpcclient.SetupPolicyClient(ctx, clientConfig) if err != nil { logger.Error(err.Error()) exitCode = 1 return } - defer policyHandler.Close() - logger.Info("PolicyService gRPC client successfully connected to auth gRPC server " + policyHandler.Secure()) + defer authPolicyHandler.Close() + logger.Info("PolicyService gRPC client successfully connected to auth gRPC server " + authPolicyHandler.Secure()) - csvc, gsvc, err := newService(ctx, authClient, policyClient, db, dbConfig, tracer, cfg, ec, logger) + policyClient, err := newPolicyClient(cfg, logger) + if err != nil { + logger.Error(err.Error()) + exitCode = 1 + return + } + logger.Info("Policy client successfully connected to spicedb gRPC server") + + csvc, gsvc, err := newService(ctx, authClient, authPolicyClient, policyClient, db, dbConfig, tracer, cfg, ec, logger) if err != nil { logger.Error(fmt.Sprintf("failed to setup service: %s", err)) exitCode = 1 @@ -220,7 +235,7 @@ func main() { } } -func newService(ctx context.Context, authClient authclient.AuthServiceClient, policyClient magistrala.PolicyServiceClient, db *sqlx.DB, dbConfig pgclient.Config, tracer trace.Tracer, c config, ec email.Config, logger *slog.Logger) (users.Service, groups.Service, error) { +func newService(ctx context.Context, authClient authclient.AuthServiceClient, authPolicyClient magistrala.PolicyServiceClient, policyClient policy.PolicyClient, db *sqlx.DB, dbConfig pgclient.Config, tracer trace.Tracer, c config, ec email.Config, logger *slog.Logger) (users.Service, groups.Service, error) { database := postgres.NewDatabase(db, dbConfig, tracer) cRepo := clientspg.NewRepository(database) gRepo := gpostgres.New(database) @@ -233,10 +248,8 @@ func newService(ctx context.Context, authClient authclient.AuthServiceClient, po logger.Error(fmt.Sprintf("failed to configure e-mailing util: %s", err.Error())) } - policyService := mgpolicy.NewService(policyClient) - - csvc := users.NewService(cRepo, authClient, policyService, emailerClient, hsr, idp, c.SelfRegister) - gsvc := mggroups.NewService(gRepo, idp, authClient, policyService) + csvc := users.NewService(cRepo, authClient, policyClient, emailerClient, hsr, idp, c.SelfRegister) + gsvc := mggroups.NewService(gRepo, idp, authClient, policyClient) csvc, err = uevents.NewEventStoreMiddleware(ctx, csvc, c.ESURL) if err != nil { @@ -261,11 +274,11 @@ func newService(ctx context.Context, authClient authclient.AuthServiceClient, po if err != nil { logger.Error(fmt.Sprintf("failed to create admin client: %s", err)) } - if err := createAdminPolicy(ctx, clientID, authClient, policyService); err != nil { + if err := createAdminPolicy(ctx, clientID, authClient, policyClient); err != nil { return nil, nil, err } - users.NewDeleteHandler(ctx, cRepo, policyService, c.DeleteInterval, c.DeleteAfter, logger) + users.NewDeleteHandler(ctx, cRepo, authPolicyClient, c.DeleteInterval, c.DeleteAfter, logger) return csvc, gsvc, err } @@ -310,7 +323,7 @@ func createAdmin(ctx context.Context, c config, crepo clientspg.Repository, hsr return client.ID, nil } -func createAdminPolicy(ctx context.Context, clientID string, authClient authclient.AuthServiceClient, policyService policy.PolicyService) error { +func createAdminPolicy(ctx context.Context, clientID string, authClient authclient.AuthServiceClient, policyService policy.PolicyClient) error { res, err := authClient.Authorize(ctx, &magistrala.AuthorizeReq{ SubjectType: authSvc.UserType, Subject: clientID, @@ -319,7 +332,7 @@ func createAdminPolicy(ctx context.Context, clientID string, authClient authclie ObjectType: authSvc.PlatformType, }) if err != nil || !res.Authorized { - addPolicyRes, err := policyService.AddPolicy(ctx, &magistrala.AddPolicyReq{ + err := policyService.AddPolicy(ctx, policy.PolicyReq{ SubjectType: authSvc.UserType, Subject: clientID, Relation: authSvc.AdministratorRelation, @@ -329,9 +342,20 @@ func createAdminPolicy(ctx context.Context, clientID string, authClient authclie if err != nil { return err } - if !addPolicyRes { - return svcerr.ErrAuthorization - } } return nil } + +func newPolicyClient(cfg config, logger *slog.Logger) (policy.PolicyClient, error) { + client, err := authzed.NewClientWithExperimentalAPIs( + fmt.Sprintf("%s:%s", cfg.SpicedbHost, cfg.SpicedbPort), + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpcutil.WithInsecureBearerToken(cfg.SpicedbPreSharedKey), + ) + if err != nil { + return nil, err + } + policyClient := mgpolicy.NewPolicyClient(client, logger) + + return policyClient, nil +} diff --git a/docker/addons/bootstrap/docker-compose.yml b/docker/addons/bootstrap/docker-compose.yml index 9792972712..8d5328c94f 100644 --- a/docker/addons/bootstrap/docker-compose.yml +++ b/docker/addons/bootstrap/docker-compose.yml @@ -12,7 +12,6 @@ networks: volumes: magistrala-bootstrap-db-volume: - services: bootstrap-db: image: postgres:16.2-alpine @@ -63,6 +62,10 @@ services: MG_JAEGER_TRACE_RATIO: ${MG_JAEGER_TRACE_RATIO} MG_SEND_TELEMETRY: ${MG_SEND_TELEMETRY} MG_BOOTSTRAP_INSTANCE_ID: ${MG_BOOTSTRAP_INSTANCE_ID} + MG_SPICEDB_SCHEMA_FILE: ${MG_SPICEDB_SCHEMA_FILE} + MG_SPICEDB_PRE_SHARED_KEY: ${MG_SPICEDB_PRE_SHARED_KEY} + MG_SPICEDB_HOST: ${MG_SPICEDB_HOST} + MG_SPICEDB_PORT: ${MG_SPICEDB_PORT} networks: - magistrala-base-net volumes: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index c206e7529c..4f1a0fc0ac 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -335,6 +335,10 @@ services: MG_JAEGER_URL: ${MG_JAEGER_URL} MG_JAEGER_TRACE_RATIO: ${MG_JAEGER_TRACE_RATIO} MG_SEND_TELEMETRY: ${MG_SEND_TELEMETRY} + MG_SPICEDB_SCHEMA_FILE: ${MG_SPICEDB_SCHEMA_FILE} + MG_SPICEDB_PRE_SHARED_KEY: ${MG_SPICEDB_PRE_SHARED_KEY} + MG_SPICEDB_HOST: ${MG_SPICEDB_HOST} + MG_SPICEDB_PORT: ${MG_SPICEDB_PORT} ports: - ${MG_THINGS_HTTP_PORT}:${MG_THINGS_HTTP_PORT} - ${MG_THINGS_AUTH_GRPC_PORT}:${MG_THINGS_AUTH_GRPC_PORT} @@ -451,6 +455,10 @@ services: MG_OAUTH_UI_ERROR_URL: ${MG_OAUTH_UI_ERROR_URL} MG_USERS_DELETE_INTERVAL: ${MG_USERS_DELETE_INTERVAL} MG_USERS_DELETE_AFTER: ${MG_USERS_DELETE_AFTER} + MG_SPICEDB_SCHEMA_FILE: ${MG_SPICEDB_SCHEMA_FILE} + MG_SPICEDB_PRE_SHARED_KEY: ${MG_SPICEDB_PRE_SHARED_KEY} + MG_SPICEDB_HOST: ${MG_SPICEDB_HOST} + MG_SPICEDB_PORT: ${MG_SPICEDB_PORT} ports: - ${MG_USERS_HTTP_PORT}:${MG_USERS_HTTP_PORT} networks: diff --git a/internal/groups/service.go b/internal/groups/service.go index 477791f671..512c567e92 100644 --- a/internal/groups/service.go +++ b/internal/groups/service.go @@ -29,17 +29,17 @@ var ( type service struct { groups groups.Repository auth grpcclient.AuthServiceClient - policy policy.PolicyService + policy policy.PolicyClient idProvider magistrala.IDProvider } // NewService returns a new Clients service implementation. -func NewService(g groups.Repository, idp magistrala.IDProvider, authClient grpcclient.AuthServiceClient, policyService policy.PolicyService) groups.Service { +func NewService(g groups.Repository, idp magistrala.IDProvider, authClient grpcclient.AuthServiceClient, policyClient policy.PolicyClient) groups.Service { return service{ groups: g, idProvider: idp, auth: authClient, - policy: policyService, + policy: policyClient, } } @@ -70,12 +70,14 @@ func (svc service) CreateGroup(ctx context.Context, token, kind string, g groups } } - if err := svc.addGroupPolicy(ctx, res.GetId(), res.GetDomainId(), g.ID, g.Parent, kind); err != nil { + policies, err := svc.addGroupPolicy(ctx, res.GetId(), res.GetDomainId(), g.ID, g.Parent, kind) + if err != nil { return groups.Group{}, err } + defer func() { if err != nil { - if errRollback := svc.addGroupPolicyRollback(ctx, res.GetId(), res.GetDomainId(), g.ID, g.Parent, kind); errRollback != nil { + if errRollback := svc.policy.DeletePolicies(ctx, policies); errRollback != nil { err = errors.Wrap(errors.Wrap(errors.ErrRollbackTx, errRollback), err) } } @@ -123,7 +125,7 @@ func (svc service) ListGroups(ctx context.Context, token, memberKind, memberID s if _, err := svc.authorizeKind(ctx, res.GetDomainId(), auth.UserType, auth.UsersKind, res.GetId(), auth.ViewPermission, auth.ThingType, memberID); err != nil { return groups.Page{}, err } - cids, err := svc.policy.ListAllSubjects(ctx, &magistrala.ListSubjectsReq{ + cids, err := svc.policy.ListAllSubjects(ctx, policy.PolicyReq{ SubjectType: auth.GroupType, Permission: auth.GroupRelation, ObjectType: auth.ThingType, @@ -132,7 +134,7 @@ func (svc service) ListGroups(ctx context.Context, token, memberKind, memberID s if err != nil { return groups.Page{}, err } - ids, err = svc.filterAllowedGroupIDsOfUserID(ctx, res.GetId(), gm.Permission, cids) + ids, err = svc.filterAllowedGroupIDsOfUserID(ctx, res.GetId(), gm.Permission, cids.Policies) if err != nil { return groups.Page{}, err } @@ -141,7 +143,7 @@ func (svc service) ListGroups(ctx context.Context, token, memberKind, memberID s return groups.Page{}, err } - gids, err := svc.policy.ListAllObjects(ctx, &magistrala.ListObjectsReq{ + gids, err := svc.policy.ListAllObjects(ctx, policy.PolicyReq{ SubjectType: auth.GroupType, Subject: memberID, Permission: auth.ParentGroupRelation, @@ -150,7 +152,7 @@ func (svc service) ListGroups(ctx context.Context, token, memberKind, memberID s if err != nil { return groups.Page{}, err } - ids, err = svc.filterAllowedGroupIDsOfUserID(ctx, res.GetId(), gm.Permission, gids) + ids, err = svc.filterAllowedGroupIDsOfUserID(ctx, res.GetId(), gm.Permission, gids.Policies) if err != nil { return groups.Page{}, err } @@ -158,7 +160,7 @@ func (svc service) ListGroups(ctx context.Context, token, memberKind, memberID s if _, err := svc.authorizeKind(ctx, res.GetDomainId(), auth.UserType, auth.UsersKind, res.GetId(), auth.ViewPermission, auth.GroupType, memberID); err != nil { return groups.Page{}, err } - gids, err := svc.policy.ListAllSubjects(ctx, &magistrala.ListSubjectsReq{ + gids, err := svc.policy.ListAllSubjects(ctx, policy.PolicyReq{ SubjectType: auth.GroupType, Permission: auth.ParentGroupRelation, ObjectType: auth.GroupType, @@ -168,7 +170,7 @@ func (svc service) ListGroups(ctx context.Context, token, memberKind, memberID s return groups.Page{}, err } - ids, err = svc.filterAllowedGroupIDsOfUserID(ctx, res.GetId(), gm.Permission, gids) + ids, err = svc.filterAllowedGroupIDsOfUserID(ctx, res.GetId(), gm.Permission, gids.Policies) if err != nil { return groups.Page{}, err } @@ -178,7 +180,7 @@ func (svc service) ListGroups(ctx context.Context, token, memberKind, memberID s if _, err := svc.authorizeKind(ctx, res.GetDomainId(), auth.UserType, auth.UsersKind, res.GetId(), auth.AdminPermission, auth.DomainType, res.GetDomainId()); err != nil { return groups.Page{}, err } - gids, err := svc.policy.ListAllObjects(ctx, &magistrala.ListObjectsReq{ + gids, err := svc.policy.ListAllObjects(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Subject: auth.EncodeDomainUserID(res.GetDomainId(), memberID), Permission: gm.Permission, @@ -187,7 +189,7 @@ func (svc service) ListGroups(ctx context.Context, token, memberKind, memberID s if err != nil { return groups.Page{}, err } - ids, err = svc.filterAllowedGroupIDsOfUserID(ctx, res.GetId(), gm.Permission, gids) + ids, err = svc.filterAllowedGroupIDsOfUserID(ctx, res.GetId(), gm.Permission, gids.Policies) if err != nil { return groups.Page{}, err } @@ -243,12 +245,12 @@ func (svc service) retrievePermissions(ctx context.Context, userID string, group } func (svc service) listUserGroupPermission(ctx context.Context, userID, groupID string) ([]string, error) { - permissions, err := svc.policy.ListPermissions(ctx, &magistrala.ListPermissionsReq{ + permissions, err := svc.policy.ListPermissions(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Object: groupID, ObjectType: auth.GroupType, - }) + }, []string{}) if err != nil { return []string{}, err } @@ -283,7 +285,7 @@ func (svc service) ListMembers(ctx context.Context, token, groupID, permission, } switch memberKind { case auth.ThingsKind: - tids, err := svc.policy.ListAllObjects(ctx, &magistrala.ListObjectsReq{ + tids, err := svc.policy.ListAllObjects(ctx, policy.PolicyReq{ SubjectType: auth.GroupType, Subject: groupID, Relation: auth.GroupRelation, @@ -295,7 +297,7 @@ func (svc service) ListMembers(ctx context.Context, token, groupID, permission, members := []groups.Member{} - for _, id := range tids { + for _, id := range tids.Policies { members = append(members, groups.Member{ ID: id, Type: auth.ThingType, @@ -308,7 +310,7 @@ func (svc service) ListMembers(ctx context.Context, token, groupID, permission, Members: members, }, nil case auth.UsersKind: - uids, err := svc.policy.ListAllSubjects(ctx, &magistrala.ListSubjectsReq{ + uids, err := svc.policy.ListAllSubjects(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Permission: permission, Object: groupID, @@ -320,7 +322,7 @@ func (svc service) ListMembers(ctx context.Context, token, groupID, permission, members := []groups.Member{} - for _, id := range uids { + for _, id := range uids.Policies { members = append(members, groups.Member{ ID: id, Type: auth.UserType, @@ -384,11 +386,11 @@ func (svc service) Assign(ctx context.Context, token, groupID, relation, memberK return err } - policies := magistrala.AddPoliciesReq{} + policies := []policy.PolicyReq{} switch memberKind { case auth.ThingsKind: for _, memberID := range memberIDs { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: res.GetDomainId(), SubjectType: auth.GroupType, SubjectKind: auth.ChannelsKind, @@ -400,7 +402,7 @@ func (svc service) Assign(ctx context.Context, token, groupID, relation, memberK } case auth.ChannelsKind: for _, memberID := range memberIDs { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: res.GetDomainId(), SubjectType: auth.GroupType, Subject: memberID, @@ -414,7 +416,7 @@ func (svc service) Assign(ctx context.Context, token, groupID, relation, memberK case auth.UsersKind: for _, memberID := range memberIDs { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: res.GetDomainId(), SubjectType: auth.UserType, Subject: auth.EncodeDomainUserID(res.GetDomainId(), memberID), @@ -427,7 +429,7 @@ func (svc service) Assign(ctx context.Context, token, groupID, relation, memberK return errMemberKind } - if _, err := svc.policy.AddPolicies(ctx, &policies); err != nil { + if err := svc.policy.AddPolicies(ctx, policies); err != nil { return errors.Wrap(svcerr.ErrAddPolicies, err) } @@ -442,21 +444,13 @@ func (svc service) assignParentGroup(ctx context.Context, domain, parentGroupID if len(groupsPage.Groups) == 0 { return errGroupIDs } - var addPolicies magistrala.AddPoliciesReq - var deletePolicies magistrala.DeletePoliciesReq + + policies := []policy.PolicyReq{} for _, group := range groupsPage.Groups { if group.Parent != "" { return errors.Wrap(svcerr.ErrConflict, fmt.Errorf("%s group already have parent", group.ID)) } - addPolicies.AddPoliciesReq = append(addPolicies.AddPoliciesReq, &magistrala.AddPolicyReq{ - Domain: domain, - SubjectType: auth.GroupType, - Subject: parentGroupID, - Relation: auth.ParentGroupRelation, - ObjectType: auth.GroupType, - Object: group.ID, - }) - deletePolicies.DeletePoliciesReq = append(deletePolicies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: domain, SubjectType: auth.GroupType, Subject: parentGroupID, @@ -466,12 +460,12 @@ func (svc service) assignParentGroup(ctx context.Context, domain, parentGroupID }) } - if _, err := svc.policy.AddPolicies(ctx, &addPolicies); err != nil { + if err := svc.policy.AddPolicies(ctx, policies); err != nil { return errors.Wrap(svcerr.ErrAddPolicies, err) } defer func() { if err != nil { - if _, errRollback := svc.policy.DeletePolicies(ctx, &deletePolicies); errRollback != nil { + if errRollback := svc.policy.DeletePolicies(ctx, policies); errRollback != nil { err = errors.Wrap(err, errors.Wrap(apiutil.ErrRollbackTx, errRollback)) } } @@ -488,21 +482,13 @@ func (svc service) unassignParentGroup(ctx context.Context, domain, parentGroupI if len(groupsPage.Groups) == 0 { return errGroupIDs } - var addPolicies magistrala.AddPoliciesReq - var deletePolicies magistrala.DeletePoliciesReq + + policies := []policy.PolicyReq{} for _, group := range groupsPage.Groups { if group.Parent != "" && group.Parent != parentGroupID { return errors.Wrap(svcerr.ErrConflict, fmt.Errorf("%s group doesn't have same parent", group.ID)) } - addPolicies.AddPoliciesReq = append(addPolicies.AddPoliciesReq, &magistrala.AddPolicyReq{ - Domain: domain, - SubjectType: auth.GroupType, - Subject: parentGroupID, - Relation: auth.ParentGroupRelation, - ObjectType: auth.GroupType, - Object: group.ID, - }) - deletePolicies.DeletePoliciesReq = append(deletePolicies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: domain, SubjectType: auth.GroupType, Subject: parentGroupID, @@ -512,12 +498,12 @@ func (svc service) unassignParentGroup(ctx context.Context, domain, parentGroupI }) } - if _, err := svc.policy.DeletePolicies(ctx, &deletePolicies); err != nil { + if err := svc.policy.DeletePolicies(ctx, policies); err != nil { return errors.Wrap(svcerr.ErrDeletePolicies, err) } defer func() { if err != nil { - if _, errRollback := svc.policy.AddPolicies(ctx, &addPolicies); errRollback != nil { + if errRollback := svc.policy.AddPolicies(ctx, policies); errRollback != nil { err = errors.Wrap(err, errors.Wrap(apiutil.ErrRollbackTx, errRollback)) } } @@ -535,12 +521,12 @@ func (svc service) Unassign(ctx context.Context, token, groupID, relation, membe return err } - policies := magistrala.DeletePoliciesReq{} + policies := []policy.PolicyReq{} switch memberKind { case auth.ThingsKind: for _, memberID := range memberIDs { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: res.GetDomainId(), SubjectType: auth.GroupType, SubjectKind: auth.ChannelsKind, @@ -552,7 +538,7 @@ func (svc service) Unassign(ctx context.Context, token, groupID, relation, membe } case auth.ChannelsKind: for _, memberID := range memberIDs { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: res.GetDomainId(), SubjectType: auth.GroupType, Subject: memberID, @@ -565,7 +551,7 @@ func (svc service) Unassign(ctx context.Context, token, groupID, relation, membe return svc.unassignParentGroup(ctx, res.GetDomainId(), groupID, memberIDs) case auth.UsersKind: for _, memberID := range memberIDs { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: res.GetDomainId(), SubjectType: auth.UserType, Subject: auth.EncodeDomainUserID(res.GetDomainId(), memberID), @@ -578,7 +564,7 @@ func (svc service) Unassign(ctx context.Context, token, groupID, relation, membe return errMemberKind } - if _, err := svc.policy.DeletePolicies(ctx, &policies); err != nil { + if err := svc.policy.DeletePolicies(ctx, policies); err != nil { return errors.Wrap(svcerr.ErrDeletePolicies, err) } return nil @@ -593,15 +579,21 @@ func (svc service) DeleteGroup(ctx context.Context, token, id string) error { return err } - deleteRes, err := svc.policy.DeleteEntityPolicies(ctx, &magistrala.DeleteEntityPoliciesReq{ - EntityType: auth.GroupType, - Id: id, - }) - if err != nil { + req := policy.PolicyReq{ + SubjectType: policy.GroupType, + Subject: id, + } + if err := svc.policy.DeletePolicyFilter(ctx, req); err != nil { return errors.Wrap(svcerr.ErrDeletePolicies, err) } - if !deleteRes { - return svcerr.ErrAuthorization + + req = policy.PolicyReq{ + Object: id, + ObjectType: policy.GroupType, + } + + if err := svc.policy.DeletePolicyFilter(ctx, req); err != nil { + return errors.Wrap(svcerr.ErrDeletePolicies, err) } if err := svc.groups.Delete(ctx, id); err != nil { @@ -629,7 +621,7 @@ func (svc service) filterAllowedGroupIDsOfUserID(ctx context.Context, userID, pe } func (svc service) listAllGroupsOfUserID(ctx context.Context, userID, permission string) ([]string, error) { - allowedIDs, err := svc.policy.ListAllObjects(ctx, &magistrala.ListObjectsReq{ + allowedIDs, err := svc.policy.ListAllObjects(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Permission: permission, @@ -638,7 +630,7 @@ func (svc service) listAllGroupsOfUserID(ctx context.Context, userID, permission if err != nil { return []string{}, err } - return allowedIDs, nil + return allowedIDs.Policies, nil } func (svc service) changeGroupStatus(ctx context.Context, token string, group groups.Group) (groups.Group, error) { @@ -708,46 +700,9 @@ func (svc service) authorizeKind(ctx context.Context, domainID, subjectType, sub return res.GetId(), nil } -func (svc service) addGroupPolicy(ctx context.Context, userID, domainID, id, parentID, kind string) error { - policies := magistrala.AddPoliciesReq{} - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ - Domain: domainID, - SubjectType: auth.UserType, - Subject: userID, - Relation: auth.AdministratorRelation, - ObjectKind: kind, - ObjectType: auth.GroupType, - Object: id, - }) - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ - Domain: domainID, - SubjectType: auth.DomainType, - Subject: domainID, - Relation: auth.DomainRelation, - ObjectType: auth.GroupType, - Object: id, - }) - if parentID != "" { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ - Domain: domainID, - SubjectType: auth.GroupType, - Subject: parentID, - Relation: auth.ParentGroupRelation, - ObjectKind: kind, - ObjectType: auth.GroupType, - Object: id, - }) - } - if _, err := svc.policy.AddPolicies(ctx, &policies); err != nil { - return errors.Wrap(svcerr.ErrAddPolicies, err) - } - - return nil -} - -func (svc service) addGroupPolicyRollback(ctx context.Context, userID, domainID, id, parentID, kind string) error { - policies := magistrala.DeletePoliciesReq{} - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ +func (svc service) addGroupPolicy(ctx context.Context, userID, domainID, id, parentID, kind string) ([]policy.PolicyReq, error) { + policies := []policy.PolicyReq{} + policies = append(policies, policy.PolicyReq{ Domain: domainID, SubjectType: auth.UserType, Subject: userID, @@ -756,7 +711,7 @@ func (svc service) addGroupPolicyRollback(ctx context.Context, userID, domainID, ObjectType: auth.GroupType, Object: id, }) - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: domainID, SubjectType: auth.DomainType, Subject: domainID, @@ -765,7 +720,7 @@ func (svc service) addGroupPolicyRollback(ctx context.Context, userID, domainID, Object: id, }) if parentID != "" { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: domainID, SubjectType: auth.GroupType, Subject: parentID, @@ -775,9 +730,9 @@ func (svc service) addGroupPolicyRollback(ctx context.Context, userID, domainID, Object: id, }) } - if _, err := svc.policy.DeletePolicies(ctx, &policies); err != nil { - return errors.Wrap(svcerr.ErrDeletePolicies, err) + if err := svc.policy.AddPolicies(ctx, policies); err != nil { + return policies, errors.Wrap(svcerr.ErrAddPolicies, err) } - return nil + return []policy.PolicyReq{}, nil } diff --git a/internal/groups/service_test.go b/internal/groups/service_test.go index f001d896a2..ced9d3ab1a 100644 --- a/internal/groups/service_test.go +++ b/internal/groups/service_test.go @@ -22,6 +22,7 @@ import ( svcerr "github.com/absmach/magistrala/pkg/errors/service" mggroups "github.com/absmach/magistrala/pkg/groups" "github.com/absmach/magistrala/pkg/groups/mocks" + policysvc "github.com/absmach/magistrala/pkg/policy" policymocks "github.com/absmach/magistrala/pkg/policy/mocks" "github.com/absmach/magistrala/pkg/uuid" "github.com/stretchr/testify/assert" @@ -50,32 +51,30 @@ var ( func TestCreateGroup(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { - desc string - token string - kind string - group mggroups.Group - idResp *magistrala.IdentityRes - idErr error - authzResp *magistrala.AuthorizeRes - authzErr error - authzTknResp *magistrala.AuthorizeRes - authzTknErr error - repoResp mggroups.Group - repoErr error - addPolResp bool - addPolErr error - deletePolResp bool - deletePolErr error - err error + desc string + token string + kind string + group mggroups.Group + idResp *magistrala.IdentityRes + idErr error + authzResp *magistrala.AuthorizeRes + authzErr error + authzTknResp *magistrala.AuthorizeRes + authzTknErr error + repoResp mggroups.Group + repoErr error + addPolErr error + deletePolErr error + err error }{ { desc: "successfully", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: validGroup, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -92,12 +91,11 @@ func TestCreateGroup(t *testing.T) { CreatedAt: time.Now(), Domain: testsutil.GenerateUUID(t), }, - addPolResp: true, }, { desc: "with invalid token", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: validGroup, idResp: &magistrala.IdentityRes{}, idErr: svcerr.ErrAuthentication, @@ -106,7 +104,7 @@ func TestCreateGroup(t *testing.T) { { desc: "with empty id or domain id but with no grpc error", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: validGroup, idResp: &magistrala.IdentityRes{}, idErr: nil, @@ -115,7 +113,7 @@ func TestCreateGroup(t *testing.T) { { desc: "with failed to authorize domain membership", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: validGroup, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -129,7 +127,7 @@ func TestCreateGroup(t *testing.T) { { desc: "with failed to authorize domain membership with grpc error", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: validGroup, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -144,7 +142,7 @@ func TestCreateGroup(t *testing.T) { { desc: "with invalid status", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: mggroups.Group{ Name: namegen.Generate(), Description: namegen.Generate(), @@ -162,7 +160,7 @@ func TestCreateGroup(t *testing.T) { { desc: "successfully with parent", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: mggroups.Group{ Name: namegen.Generate(), Description: namegen.Generate(), @@ -185,12 +183,11 @@ func TestCreateGroup(t *testing.T) { Domain: testsutil.GenerateUUID(t), Parent: testsutil.GenerateUUID(t), }, - addPolResp: true, }, { desc: "unsuccessfully with parent due to authorization error", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: mggroups.Group{ Name: namegen.Generate(), Description: namegen.Generate(), @@ -210,13 +207,12 @@ func TestCreateGroup(t *testing.T) { ID: testsutil.GenerateUUID(t), Parent: testsutil.GenerateUUID(t), }, - addPolResp: true, - err: svcerr.ErrAuthorization, + err: svcerr.ErrAuthorization, }, { desc: "with repo error", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: validGroup, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -235,7 +231,7 @@ func TestCreateGroup(t *testing.T) { { desc: "with failed to add policies", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: validGroup, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -250,14 +246,13 @@ func TestCreateGroup(t *testing.T) { repoResp: mggroups.Group{ ID: testsutil.GenerateUUID(t), }, - addPolResp: false, - addPolErr: svcerr.ErrAuthorization, - err: svcerr.ErrAuthorization, + addPolErr: svcerr.ErrAuthorization, + err: svcerr.ErrAuthorization, }, { desc: "with failed to delete policies response", token: token, - kind: auth.NewGroupKind, + kind: policysvc.NewGroupKind, group: mggroups.Group{ Name: namegen.Generate(), Description: namegen.Generate(), @@ -275,7 +270,6 @@ func TestCreateGroup(t *testing.T) { Authorized: true, }, repoErr: errors.ErrMalformedEntity, - addPolResp: true, deletePolErr: svcerr.ErrAuthorization, err: errors.ErrMalformedEntity, }, @@ -285,24 +279,24 @@ func TestCreateGroup(t *testing.T) { t.Run(tc.desc, func(t *testing.T) { authCall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr) authCall1 := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.idResp.GetId(), - Permission: auth.CreatePermission, + Permission: policysvc.CreatePermission, Object: tc.idResp.GetDomainId(), - ObjectType: auth.DomainType, + ObjectType: policysvc.DomainType, }).Return(tc.authzResp, tc.authzErr) authCall2 := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: auth.UserType, - SubjectKind: auth.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: tc.token, - Permission: auth.EditPermission, + Permission: policysvc.EditPermission, Object: tc.group.Parent, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzTknResp, tc.authzTknErr) repoCall := repo.On("Save", context.Background(), mock.Anything).Return(tc.repoResp, tc.repoErr) - authCall3 := policy.On("AddPolicies", context.Background(), mock.Anything).Return(tc.addPolResp, tc.addPolErr) - authCall4 := policy.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePolResp, tc.deletePolErr) + policyCall := policy.On("AddPolicies", context.Background(), mock.Anything).Return(tc.addPolErr) + policyCall1 := policy.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePolErr) got, err := svc.CreateGroup(context.Background(), tc.token, tc.kind, tc.group) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err)) if err == nil { @@ -317,8 +311,8 @@ func TestCreateGroup(t *testing.T) { authCall1.Unset() authCall2.Unset() repoCall.Unset() - authCall3.Unset() - authCall4.Unset() + policyCall.Unset() + policyCall1.Unset() }) } } @@ -326,7 +320,7 @@ func TestCreateGroup(t *testing.T) { func TestViewGroup(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { @@ -373,12 +367,12 @@ func TestViewGroup(t *testing.T) { for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { authCall := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: auth.UserType, - SubjectKind: auth.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: tc.token, - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, Object: tc.id, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzResp, tc.authzErr) repoCall := repo.On("RetrieveByID", context.Background(), tc.id).Return(tc.repoResp, tc.repoErr) got, err := svc.ViewGroup(context.Background(), tc.token, tc.id) @@ -397,7 +391,7 @@ func TestViewGroup(t *testing.T) { func TestViewGroupPerms(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { @@ -406,7 +400,7 @@ func TestViewGroupPerms(t *testing.T) { id string idResp *magistrala.IdentityRes idErr error - listResp []string + listResp policysvc.Permissions listErr error err error }{ @@ -419,8 +413,8 @@ func TestViewGroupPerms(t *testing.T) { DomainId: testsutil.GenerateUUID(t), }, listResp: []string{ - auth.ViewPermission, - auth.EditPermission, + policysvc.ViewPermission, + policysvc.EditPermission, }, }, { @@ -458,19 +452,19 @@ func TestViewGroupPerms(t *testing.T) { for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { authCall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr) - authCall1 := policy.On("ListPermissions", context.Background(), &magistrala.ListPermissionsReq{ - SubjectType: auth.UserType, + policyCall := policy.On("ListPermissions", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Subject: tc.idResp.GetId(), Object: tc.id, - ObjectType: auth.GroupType, - }).Return(tc.listResp, tc.listErr) + ObjectType: policysvc.GroupType, + }, []string{}).Return(tc.listResp, tc.listErr) got, err := svc.ViewGroupPerms(context.Background(), tc.token, tc.id) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err)) if err == nil { - assert.Equal(t, tc.listResp, got) + assert.ElementsMatch(t, tc.listResp, got) } authCall.Unset() - authCall1.Unset() + policyCall.Unset() }) } } @@ -478,7 +472,7 @@ func TestViewGroupPerms(t *testing.T) { func TestUpdateGroup(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { @@ -534,12 +528,12 @@ func TestUpdateGroup(t *testing.T) { for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { authCall := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: auth.UserType, - SubjectKind: auth.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: tc.token, - Permission: auth.EditPermission, + Permission: policysvc.EditPermission, Object: tc.group.ID, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzResp, tc.authzErr) repoCall := repo.On("Update", context.Background(), mock.Anything).Return(tc.repoResp, tc.repoErr) got, err := svc.UpdateGroup(context.Background(), tc.token, tc.group) @@ -558,7 +552,7 @@ func TestUpdateGroup(t *testing.T) { func TestEnableGroup(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { @@ -633,12 +627,12 @@ func TestEnableGroup(t *testing.T) { for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { authCall := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: auth.UserType, - SubjectKind: auth.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: tc.token, - Permission: auth.EditPermission, + Permission: policysvc.EditPermission, Object: tc.id, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzResp, tc.authzErr) repoCall := repo.On("RetrieveByID", context.Background(), tc.id).Return(tc.retrieveResp, tc.retrieveErr) repoCall1 := repo.On("ChangeStatus", context.Background(), mock.Anything).Return(tc.changeResp, tc.changeErr) @@ -659,7 +653,7 @@ func TestEnableGroup(t *testing.T) { func TestDisableGroup(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { @@ -734,12 +728,12 @@ func TestDisableGroup(t *testing.T) { for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { authCall := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: auth.UserType, - SubjectKind: auth.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: tc.token, - Permission: auth.EditPermission, + Permission: policysvc.EditPermission, Object: tc.id, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzResp, tc.authzErr) repoCall := repo.On("RetrieveByID", context.Background(), tc.id).Return(tc.retrieveResp, tc.retrieveErr) repoCall1 := repo.On("ChangeStatus", context.Background(), mock.Anything).Return(tc.changeResp, tc.changeErr) @@ -760,7 +754,7 @@ func TestDisableGroup(t *testing.T) { func TestListMembers(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { @@ -771,9 +765,9 @@ func TestListMembers(t *testing.T) { memberKind string authzResp *magistrala.AuthorizeRes authzErr error - listSubjectResp []string + listSubjectResp policysvc.PolicyPage listSubjectErr error - listObjectResp []string + listObjectResp policysvc.PolicyPage listObjectErr error err error }{ @@ -781,37 +775,41 @@ func TestListMembers(t *testing.T) { desc: "successfully with things kind", token: token, groupID: testsutil.GenerateUUID(t), - memberKind: auth.ThingsKind, + memberKind: policysvc.ThingsKind, authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listObjectResp: []string{ - testsutil.GenerateUUID(t), - testsutil.GenerateUUID(t), - testsutil.GenerateUUID(t), + listObjectResp: policysvc.PolicyPage{ + Policies: []string{ + testsutil.GenerateUUID(t), + testsutil.GenerateUUID(t), + testsutil.GenerateUUID(t), + }, }, }, { desc: "successfully with users kind", token: token, groupID: testsutil.GenerateUUID(t), - memberKind: auth.UsersKind, - permission: auth.ViewPermission, + memberKind: policysvc.UsersKind, + permission: policysvc.ViewPermission, authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listSubjectResp: []string{ - testsutil.GenerateUUID(t), - testsutil.GenerateUUID(t), - testsutil.GenerateUUID(t), + listSubjectResp: policysvc.PolicyPage{ + Policies: []string{ + testsutil.GenerateUUID(t), + testsutil.GenerateUUID(t), + testsutil.GenerateUUID(t), + }, }, }, { desc: "with invalid kind", token: token, groupID: testsutil.GenerateUUID(t), - memberKind: auth.GroupsKind, - permission: auth.ViewPermission, + memberKind: policysvc.GroupsKind, + permission: policysvc.ViewPermission, authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, @@ -829,11 +827,11 @@ func TestListMembers(t *testing.T) { desc: "failed to list objects with things kind", token: token, groupID: testsutil.GenerateUUID(t), - memberKind: auth.ThingsKind, + memberKind: policysvc.ThingsKind, authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listObjectResp: []string{}, + listObjectResp: policysvc.PolicyPage{}, listObjectErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -841,12 +839,12 @@ func TestListMembers(t *testing.T) { desc: "failed to list subjects with users kind", token: token, groupID: testsutil.GenerateUUID(t), - memberKind: auth.UsersKind, - permission: auth.ViewPermission, + memberKind: policysvc.UsersKind, + permission: policysvc.ViewPermission, authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listSubjectResp: []string{}, + listSubjectResp: policysvc.PolicyPage{}, listSubjectErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -855,24 +853,24 @@ func TestListMembers(t *testing.T) { for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { authCall := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: auth.UserType, - SubjectKind: auth.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: tc.token, - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, Object: tc.groupID, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzResp, tc.authzErr) - authCall1 := policy.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{ - SubjectType: auth.GroupType, + policyCall := policy.On("ListAllObjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.GroupType, Subject: tc.groupID, - Relation: auth.GroupRelation, - ObjectType: auth.ThingType, + Relation: policysvc.GroupRelation, + ObjectType: policysvc.ThingType, }).Return(tc.listObjectResp, tc.listObjectErr) - authCall2 := policy.On("ListAllSubjects", context.Background(), &magistrala.ListSubjectsReq{ - SubjectType: auth.UserType, + policyCall1 := policy.On("ListAllSubjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: tc.permission, Object: tc.groupID, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.listSubjectResp, tc.listSubjectErr) got, err := svc.ListMembers(context.Background(), tc.token, tc.groupID, tc.permission, tc.memberKind) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err)) @@ -880,8 +878,8 @@ func TestListMembers(t *testing.T) { assert.NotEmpty(t, got) } authCall.Unset() - authCall1.Unset() - authCall2.Unset() + policyCall.Unset() + policyCall1.Unset() }) } } @@ -889,7 +887,7 @@ func TestListMembers(t *testing.T) { func TestListGroups(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { @@ -902,17 +900,17 @@ func TestListGroups(t *testing.T) { idErr error authzResp *magistrala.AuthorizeRes authzErr error - listSubjectResp []string + listSubjectResp policysvc.PolicyPage listSubjectErr error - listObjectResp []string + listObjectResp policysvc.PolicyPage listObjectErr error - listObjectFilterResp []string + listObjectFilterResp policysvc.PolicyPage listObjectFilterErr error authSuperAdminResp *magistrala.AuthorizeRes authSuperAdminErr error repoResp mggroups.Page repoErr error - listPermResp []string + listPermResp policysvc.Permissions listPermErr error err error }{ @@ -920,9 +918,9 @@ func TestListGroups(t *testing.T) { desc: "successfully with things kind", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ThingsKind, + memberKind: policysvc.ThingsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -932,8 +930,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listSubjectResp: allowedIDs, - listObjectFilterResp: allowedIDs, + listSubjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{Policies: allowedIDs}, repoResp: mggroups.Page{ Groups: []mggroups.Group{ validGroup, @@ -942,17 +940,17 @@ func TestListGroups(t *testing.T) { }, }, listPermResp: []string{ - auth.ViewPermission, - auth.EditPermission, + policysvc.ViewPermission, + policysvc.EditPermission, }, }, { desc: "successfully with groups kind", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.GroupsKind, + memberKind: policysvc.GroupsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -962,8 +960,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listObjectResp: allowedIDs, - listObjectFilterResp: allowedIDs, + listObjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{Policies: allowedIDs}, repoResp: mggroups.Page{ Groups: []mggroups.Group{ validGroup, @@ -972,17 +970,17 @@ func TestListGroups(t *testing.T) { }, }, listPermResp: []string{ - auth.ViewPermission, - auth.EditPermission, + policysvc.ViewPermission, + policysvc.EditPermission, }, }, { desc: "successfully with channels kind", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ChannelsKind, + memberKind: policysvc.ChannelsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -992,8 +990,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listSubjectResp: allowedIDs, - listObjectFilterResp: allowedIDs, + listSubjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{Policies: allowedIDs}, repoResp: mggroups.Page{ Groups: []mggroups.Group{ validGroup, @@ -1002,17 +1000,17 @@ func TestListGroups(t *testing.T) { }, }, listPermResp: []string{ - auth.ViewPermission, - auth.EditPermission, + policysvc.ViewPermission, + policysvc.EditPermission, }, }, { desc: "successfully with users kind non admin", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.UsersKind, + memberKind: policysvc.UsersKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1022,8 +1020,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listObjectResp: allowedIDs, - listObjectFilterResp: allowedIDs, + listObjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{Policies: allowedIDs}, repoResp: mggroups.Page{ Groups: []mggroups.Group{ validGroup, @@ -1032,16 +1030,16 @@ func TestListGroups(t *testing.T) { }, }, listPermResp: []string{ - auth.ViewPermission, - auth.EditPermission, + policysvc.ViewPermission, + policysvc.EditPermission, }, }, { desc: "successfully with users kind admin", token: token, - memberKind: auth.UsersKind, + memberKind: policysvc.UsersKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1052,9 +1050,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listObjectResp: allowedIDs, - - listObjectFilterResp: allowedIDs, + listObjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{Policies: allowedIDs}, repoResp: mggroups.Page{ Groups: []mggroups.Group{ validGroup, @@ -1063,16 +1060,16 @@ func TestListGroups(t *testing.T) { }, }, listPermResp: []string{ - auth.ViewPermission, - auth.EditPermission, + policysvc.ViewPermission, + policysvc.EditPermission, }, }, { desc: "unsuccessfully with users kind admin", token: token, - memberKind: auth.UsersKind, + memberKind: policysvc.UsersKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1089,9 +1086,9 @@ func TestListGroups(t *testing.T) { { desc: "unsuccessfully with users kind admin with nil error", token: token, - memberKind: auth.UsersKind, + memberKind: policysvc.UsersKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1108,9 +1105,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with things kind due to failed to authorize", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ThingsKind, + memberKind: policysvc.ThingsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1127,9 +1124,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with things kind due to failed to list subjects", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ThingsKind, + memberKind: policysvc.ThingsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1139,7 +1136,7 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listSubjectResp: []string{}, + listSubjectResp: policysvc.PolicyPage{}, listSubjectErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -1147,9 +1144,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with things kind due to failed to list filtered objects", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ThingsKind, + memberKind: policysvc.ThingsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1159,8 +1156,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listSubjectResp: allowedIDs, - listObjectFilterResp: []string{}, + listSubjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{}, listObjectFilterErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -1168,9 +1165,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with groups kind due to failed to authorize", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.GroupsKind, + memberKind: policysvc.GroupsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1187,9 +1184,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with groups kind due to failed to list subjects", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.GroupsKind, + memberKind: policysvc.GroupsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1199,7 +1196,7 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listObjectResp: []string{}, + listObjectResp: policysvc.PolicyPage{}, listObjectErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -1207,9 +1204,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with groups kind due to failed to list filtered objects", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.GroupsKind, + memberKind: policysvc.GroupsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1219,8 +1216,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listObjectResp: allowedIDs, - listObjectFilterResp: []string{}, + listObjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{}, listObjectFilterErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -1228,9 +1225,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with channels kind due to failed to authorize", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ChannelsKind, + memberKind: policysvc.ChannelsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1247,9 +1244,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with channels kind due to failed to list subjects", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ChannelsKind, + memberKind: policysvc.ChannelsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1259,7 +1256,7 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listSubjectResp: []string{}, + listSubjectResp: policysvc.PolicyPage{}, listSubjectErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -1267,9 +1264,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with channels kind due to failed to list filtered objects", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ChannelsKind, + memberKind: policysvc.ChannelsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1279,8 +1276,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listSubjectResp: allowedIDs, - listObjectFilterResp: []string{}, + listSubjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{}, listObjectFilterErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -1288,9 +1285,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with users kind due to failed to authorize", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.UsersKind, + memberKind: policysvc.UsersKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1307,9 +1304,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with users kind due to failed to list subjects", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.UsersKind, + memberKind: policysvc.UsersKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1319,7 +1316,7 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listObjectResp: []string{}, + listObjectResp: policysvc.PolicyPage{}, listObjectErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -1327,9 +1324,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with users kind due to failed to list filtered objects", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.UsersKind, + memberKind: policysvc.UsersKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1339,17 +1336,17 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listObjectResp: allowedIDs, - listObjectFilterResp: []string{}, + listObjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{}, listObjectFilterErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, { desc: "successfully with users kind admin", token: token, - memberKind: auth.UsersKind, + memberKind: policysvc.UsersKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1360,8 +1357,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listObjectResp: allowedIDs, - listObjectFilterResp: allowedIDs, + listObjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{Policies: allowedIDs}, repoResp: mggroups.Page{ Groups: []mggroups.Group{ validGroup, @@ -1370,8 +1367,8 @@ func TestListGroups(t *testing.T) { }, }, listPermResp: []string{ - auth.ViewPermission, - auth.EditPermission, + policysvc.ViewPermission, + policysvc.EditPermission, }, }, { @@ -1380,7 +1377,7 @@ func TestListGroups(t *testing.T) { memberID: testsutil.GenerateUUID(t), memberKind: "invalid", page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1393,9 +1390,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with things kind due to repo error", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ThingsKind, + memberKind: policysvc.ThingsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1405,8 +1402,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listSubjectResp: allowedIDs, - listObjectFilterResp: allowedIDs, + listSubjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{Policies: allowedIDs}, repoResp: mggroups.Page{}, repoErr: repoerr.ErrViewEntity, err: repoerr.ErrViewEntity, @@ -1415,9 +1412,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with things kind due to failed to list permissions", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ThingsKind, + memberKind: policysvc.ThingsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{ @@ -1427,8 +1424,8 @@ func TestListGroups(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - listSubjectResp: allowedIDs, - listObjectFilterResp: allowedIDs, + listSubjectResp: policysvc.PolicyPage{Policies: allowedIDs}, + listObjectFilterResp: policysvc.PolicyPage{Policies: allowedIDs}, repoResp: mggroups.Page{ Groups: []mggroups.Group{ validGroup, @@ -1444,9 +1441,9 @@ func TestListGroups(t *testing.T) { desc: "unsuccessfully with invalid token", token: token, memberID: testsutil.GenerateUUID(t), - memberKind: auth.ThingsKind, + memberKind: policysvc.ThingsKind, page: mggroups.Page{ - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, ListPerms: true, }, idResp: &magistrala.IdentityRes{}, @@ -1459,114 +1456,114 @@ func TestListGroups(t *testing.T) { t.Run(tc.desc, func(t *testing.T) { authCall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr) authCall1 := &mock.Call{} - authCall2 := &mock.Call{} - authCall3 := &mock.Call{} + policyCall := &mock.Call{} + policyCall1 := &mock.Call{} adminCheck := &mock.Call{} switch tc.memberKind { - case auth.ThingsKind: + case policysvc.ThingsKind: authCall1 = authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.idResp.GetId(), - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, Object: tc.memberID, - ObjectType: auth.ThingType, + ObjectType: policysvc.ThingType, }).Return(tc.authzResp, tc.authzErr) - authCall2 = policy.On("ListAllSubjects", context.Background(), &magistrala.ListSubjectsReq{ - SubjectType: auth.GroupType, - Permission: auth.GroupRelation, - ObjectType: auth.ThingType, + policyCall = policy.On("ListAllSubjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.GroupType, + Permission: policysvc.GroupRelation, + ObjectType: policysvc.ThingType, Object: tc.memberID, }).Return(tc.listSubjectResp, tc.listSubjectErr) - authCall3 = policy.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{ - SubjectType: auth.UserType, + policyCall1 = policy.On("ListAllObjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Subject: tc.idResp.GetId(), Permission: tc.page.Permission, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.listObjectFilterResp, tc.listObjectFilterErr) - case auth.GroupsKind: + case policysvc.GroupsKind: authCall1 = authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.idResp.GetId(), Permission: tc.page.Permission, Object: tc.memberID, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzResp, tc.authzErr) - authCall2 = policy.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{ - SubjectType: auth.GroupType, + policyCall = policy.On("ListAllObjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.GroupType, Subject: tc.memberID, - Permission: auth.ParentGroupRelation, - ObjectType: auth.GroupType, + Permission: policysvc.ParentGroupRelation, + ObjectType: policysvc.GroupType, }).Return(tc.listObjectResp, tc.listObjectErr) - authCall3 = policy.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{ - SubjectType: auth.UserType, + policyCall1 = policy.On("ListAllObjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Subject: tc.idResp.GetId(), Permission: tc.page.Permission, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.listObjectFilterResp, tc.listObjectFilterErr) - case auth.ChannelsKind: + case policysvc.ChannelsKind: authCall1 = authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.idResp.GetId(), - Permission: auth.ViewPermission, + Permission: policysvc.ViewPermission, Object: tc.memberID, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzResp, tc.authzErr) - authCall2 = policy.On("ListAllSubjects", context.Background(), &magistrala.ListSubjectsReq{ - SubjectType: auth.GroupType, - Permission: auth.ParentGroupRelation, - ObjectType: auth.GroupType, + policyCall = policy.On("ListAllSubjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.GroupType, + Permission: policysvc.ParentGroupRelation, + ObjectType: policysvc.GroupType, Object: tc.memberID, }).Return(tc.listSubjectResp, tc.listSubjectErr) - authCall3 = policy.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{ - SubjectType: auth.UserType, + policyCall1 = policy.On("ListAllObjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Subject: tc.idResp.GetId(), Permission: tc.page.Permission, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.listObjectFilterResp, tc.listObjectFilterErr) - case auth.UsersKind: + case policysvc.UsersKind: adminCheckReq := &magistrala.AuthorizeReq{ - SubjectType: auth.UserType, + SubjectType: policysvc.UserType, Subject: tc.idResp.GetUserId(), - Permission: auth.AdminPermission, - Object: auth.MagistralaObject, - ObjectType: auth.PlatformType, + Permission: policysvc.AdminPermission, + Object: policysvc.MagistralaObject, + ObjectType: policysvc.PlatformType, } adminCheck = authsvc.On("Authorize", context.Background(), adminCheckReq).Return(tc.authzResp, tc.authzErr) authReq := &magistrala.AuthorizeReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.idResp.GetId(), - Permission: auth.AdminPermission, + Permission: policysvc.AdminPermission, Object: tc.idResp.GetDomainId(), - ObjectType: auth.DomainType, + ObjectType: policysvc.DomainType, } if tc.memberID == "" { authReq.Domain = "" - authReq.Permission = auth.MembershipPermission + authReq.Permission = policysvc.MembershipPermission } authCall1 = authsvc.On("Authorize", context.Background(), authReq).Return(tc.authzResp, tc.authzErr) - authCall2 = policy.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{ - SubjectType: auth.UserType, + policyCall = policy.On("ListAllObjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Subject: auth.EncodeDomainUserID(tc.idResp.GetDomainId(), tc.memberID), Permission: tc.page.Permission, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.listObjectResp, tc.listObjectErr) - authCall3 = policy.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{ - SubjectType: auth.UserType, + policyCall1 = policy.On("ListAllObjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Subject: tc.idResp.GetId(), Permission: tc.page.Permission, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.listObjectFilterResp, tc.listObjectFilterErr) } repoCall := repo.On("RetrieveByIDs", context.Background(), mock.Anything, mock.Anything).Return(tc.repoResp, tc.repoErr) - authCall4 := policy.On("ListPermissions", mock.Anything, mock.Anything).Return(tc.listPermResp, tc.listPermErr) + authCall4 := policy.On("ListPermissions", mock.Anything, mock.Anything, mock.Anything).Return(tc.listPermResp, tc.listPermErr) got, err := svc.ListGroups(context.Background(), tc.token, tc.memberKind, tc.memberID, tc.page) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err)) if err == nil { @@ -1575,10 +1572,10 @@ func TestListGroups(t *testing.T) { authCall.Unset() repoCall.Unset() switch tc.memberKind { - case auth.ThingsKind, auth.GroupsKind, auth.ChannelsKind, auth.UsersKind: + case policysvc.ThingsKind, policysvc.GroupsKind, policysvc.ChannelsKind, policysvc.UsersKind: authCall1.Unset() - authCall2.Unset() - authCall3.Unset() + policyCall.Unset() + policyCall1.Unset() authCall4.Unset() if tc.memberID == "" { adminCheck.Unset() @@ -1591,7 +1588,7 @@ func TestListGroups(t *testing.T) { func TestAssign(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { @@ -1605,13 +1602,10 @@ func TestAssign(t *testing.T) { idErr error authzResp *magistrala.AuthorizeRes authzErr error - addPoliciesRes bool addPoliciesErr error repoResp mggroups.Page repoErr error - addParentPoliciesRes bool addParentPoliciesErr error - deleteParentPoliciesRes bool deleteParentPoliciesErr error repoParentGroupErr error err error @@ -1620,8 +1614,8 @@ func TestAssign(t *testing.T) { desc: "successfully with things kind", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.ThingsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.ThingsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1630,14 +1624,13 @@ func TestAssign(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - addPoliciesRes: true, }, { desc: "successfully with channels kind", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.ChannelsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.ChannelsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1646,14 +1639,13 @@ func TestAssign(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - addPoliciesRes: true, }, { desc: "successfully with groups kind", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1669,15 +1661,14 @@ func TestAssign(t *testing.T) { validGroup, }, }, - addPoliciesRes: true, repoParentGroupErr: nil, }, { desc: "successfully with users kind", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.UsersKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.UsersKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1686,14 +1677,13 @@ func TestAssign(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - addPoliciesRes: true, }, { desc: "unsuccessfully with groups kind due to repo err", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1710,8 +1700,8 @@ func TestAssign(t *testing.T) { desc: "unsuccessfully with groups kind due to empty page", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1729,8 +1719,8 @@ func TestAssign(t *testing.T) { desc: "unsuccessfully with groups kind due to non empty parent", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1753,8 +1743,8 @@ func TestAssign(t *testing.T) { desc: "unsuccessfully with groups kind due to failed to add policies", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1770,7 +1760,6 @@ func TestAssign(t *testing.T) { validGroup, }, }, - addPoliciesRes: false, addPoliciesErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -1778,8 +1767,8 @@ func TestAssign(t *testing.T) { desc: "unsuccessfully with groups kind due to failed to assign parent", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1795,7 +1784,6 @@ func TestAssign(t *testing.T) { validGroup, }, }, - addPoliciesRes: true, repoParentGroupErr: repoerr.ErrConflict, err: repoerr.ErrConflict, }, @@ -1803,8 +1791,8 @@ func TestAssign(t *testing.T) { desc: "unsuccessfully with groups kind due to failed to assign parent and delete policy", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1820,8 +1808,6 @@ func TestAssign(t *testing.T) { validGroup, }, }, - addPoliciesRes: true, - deleteParentPoliciesRes: false, deleteParentPoliciesErr: svcerr.ErrAuthorization, repoParentGroupErr: repoerr.ErrConflict, err: apiutil.ErrRollbackTx, @@ -1830,7 +1816,7 @@ func TestAssign(t *testing.T) { desc: "unsuccessfully with invalid kind", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, + relation: policysvc.ContributorRelation, memberKind: "invalid", memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ @@ -1846,8 +1832,8 @@ func TestAssign(t *testing.T) { desc: "unsuccessfully with invalid token", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.UsersKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.UsersKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{}, idErr: svcerr.ErrAuthentication, @@ -1857,8 +1843,8 @@ func TestAssign(t *testing.T) { desc: "unsuccessfully with failed to authorize", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.ThingsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.ThingsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1874,8 +1860,8 @@ func TestAssign(t *testing.T) { desc: "unsuccessfully with failed to add policies", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.ThingsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.ThingsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -1884,7 +1870,6 @@ func TestAssign(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - addPoliciesRes: false, addPoliciesErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -1895,83 +1880,74 @@ func TestAssign(t *testing.T) { authCall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr) authCall1 := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.idResp.GetId(), - Permission: auth.EditPermission, + Permission: policysvc.EditPermission, Object: tc.groupID, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzResp, tc.authzErr) retrieveByIDsCall := &mock.Call{} deletePoliciesCall := &mock.Call{} assignParentCall := &mock.Call{} - policies := magistrala.AddPoliciesReq{} + policies := []policysvc.PolicyReq{} switch tc.memberKind { - case auth.ThingsKind: + case policysvc.ThingsKind: for _, memberID := range tc.memberIDs { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policysvc.PolicyReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.GroupType, - SubjectKind: auth.ChannelsKind, + SubjectType: policysvc.GroupType, + SubjectKind: policysvc.ChannelsKind, Subject: tc.groupID, Relation: tc.relation, - ObjectType: auth.ThingType, + ObjectType: policysvc.ThingType, Object: memberID, }) } - case auth.GroupsKind: + case policysvc.GroupsKind: retrieveByIDsCall = repo.On("RetrieveByIDs", context.Background(), mggroups.Page{PageMeta: mggroups.PageMeta{Limit: 1<<63 - 1}}, mock.Anything).Return(tc.repoResp, tc.repoErr) - var deletePolicies magistrala.DeletePoliciesReq for _, group := range tc.repoResp.Groups { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ - Domain: tc.idResp.GetDomainId(), - SubjectType: auth.GroupType, - Subject: tc.groupID, - Relation: auth.ParentGroupRelation, - ObjectType: auth.GroupType, - Object: group.ID, - }) - deletePolicies.DeletePoliciesReq = append(deletePolicies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policysvc.PolicyReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.GroupType, + SubjectType: policysvc.GroupType, Subject: tc.groupID, - Relation: auth.ParentGroupRelation, - ObjectType: auth.GroupType, + Relation: policysvc.ParentGroupRelation, + ObjectType: policysvc.GroupType, Object: group.ID, }) } - deletePoliciesCall = policy.On("DeletePolicies", context.Background(), &deletePolicies).Return(tc.deleteParentPoliciesRes, tc.deleteParentPoliciesErr) + deletePoliciesCall = policy.On("DeletePolicies", context.Background(), policies).Return(tc.deleteParentPoliciesErr) assignParentCall = repo.On("AssignParentGroup", context.Background(), tc.groupID, tc.memberIDs).Return(tc.repoParentGroupErr) - case auth.ChannelsKind: + case policysvc.ChannelsKind: for _, memberID := range tc.memberIDs { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policysvc.PolicyReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.GroupType, + SubjectType: policysvc.GroupType, Subject: memberID, Relation: tc.relation, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, Object: tc.groupID, }) } - case auth.UsersKind: + case policysvc.UsersKind: for _, memberID := range tc.memberIDs { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policysvc.PolicyReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.UserType, + SubjectType: policysvc.UserType, Subject: auth.EncodeDomainUserID(tc.idResp.GetDomainId(), memberID), Relation: tc.relation, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, Object: tc.groupID, }) } } - authCall2 := policy.On("AddPolicies", context.Background(), &policies).Return(tc.addPoliciesRes, tc.addPoliciesErr) + policyCall := policy.On("AddPolicies", context.Background(), policies).Return(tc.addPoliciesErr) err := svc.Assign(context.Background(), tc.token, tc.groupID, tc.relation, tc.memberKind, tc.memberIDs...) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err)) authCall.Unset() authCall1.Unset() - authCall2.Unset() - if tc.memberKind == auth.GroupsKind { + policyCall.Unset() + if tc.memberKind == policysvc.GroupsKind { retrieveByIDsCall.Unset() deletePoliciesCall.Unset() assignParentCall.Unset() @@ -1983,7 +1959,7 @@ func TestAssign(t *testing.T) { func TestUnassign(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { @@ -1997,13 +1973,10 @@ func TestUnassign(t *testing.T) { idErr error authzResp *magistrala.AuthorizeRes authzErr error - deletePoliciesRes bool deletePoliciesErr error repoResp mggroups.Page repoErr error - addParentPoliciesRes bool addParentPoliciesErr error - deleteParentPoliciesRes bool deleteParentPoliciesErr error repoParentGroupErr error err error @@ -2012,8 +1985,8 @@ func TestUnassign(t *testing.T) { desc: "successfully with things kind", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.ThingsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.ThingsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2022,14 +1995,13 @@ func TestUnassign(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - deletePoliciesRes: true, }, { desc: "successfully with channels kind", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.ChannelsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.ChannelsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2038,14 +2010,13 @@ func TestUnassign(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - deletePoliciesRes: true, }, { desc: "successfully with groups kind", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2061,15 +2032,14 @@ func TestUnassign(t *testing.T) { validGroup, }, }, - deletePoliciesRes: true, repoParentGroupErr: nil, }, { desc: "successfully with users kind", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.UsersKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.UsersKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2078,14 +2048,13 @@ func TestUnassign(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - deletePoliciesRes: true, }, { desc: "unsuccessfully with groups kind due to repo err", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2102,8 +2071,8 @@ func TestUnassign(t *testing.T) { desc: "unsuccessfully with groups kind due to empty page", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2121,8 +2090,8 @@ func TestUnassign(t *testing.T) { desc: "unsuccessfully with groups kind due to non empty parent", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2145,8 +2114,8 @@ func TestUnassign(t *testing.T) { desc: "unsuccessfully with groups kind due to failed to add policies", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2162,7 +2131,6 @@ func TestUnassign(t *testing.T) { validGroup, }, }, - deletePoliciesRes: false, deletePoliciesErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -2170,8 +2138,8 @@ func TestUnassign(t *testing.T) { desc: "unsuccessfully with groups kind due to failed to unassign parent", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2187,7 +2155,6 @@ func TestUnassign(t *testing.T) { validGroup, }, }, - deletePoliciesRes: true, repoParentGroupErr: repoerr.ErrConflict, err: repoerr.ErrConflict, }, @@ -2195,8 +2162,8 @@ func TestUnassign(t *testing.T) { desc: "unsuccessfully with groups kind due to failed to unassign parent and add policy", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.GroupsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.GroupsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2212,9 +2179,7 @@ func TestUnassign(t *testing.T) { validGroup, }, }, - deletePoliciesRes: true, repoParentGroupErr: repoerr.ErrConflict, - addParentPoliciesRes: false, addParentPoliciesErr: svcerr.ErrAuthorization, err: repoerr.ErrConflict, }, @@ -2222,7 +2187,7 @@ func TestUnassign(t *testing.T) { desc: "unsuccessfully with invalid kind", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, + relation: policysvc.ContributorRelation, memberKind: "invalid", memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ @@ -2238,8 +2203,8 @@ func TestUnassign(t *testing.T) { desc: "unsuccessfully with invalid token", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.UsersKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.UsersKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{}, idErr: svcerr.ErrAuthentication, @@ -2249,8 +2214,8 @@ func TestUnassign(t *testing.T) { desc: "unsuccessfully with failed to authorize", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.ThingsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.ThingsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2266,8 +2231,8 @@ func TestUnassign(t *testing.T) { desc: "unsuccessfully with failed to add policies", token: token, groupID: testsutil.GenerateUUID(t), - relation: auth.ContributorRelation, - memberKind: auth.ThingsKind, + relation: policysvc.ContributorRelation, + memberKind: policysvc.ThingsKind, memberIDs: allowedIDs, idResp: &magistrala.IdentityRes{ Id: testsutil.GenerateUUID(t), @@ -2276,7 +2241,6 @@ func TestUnassign(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - deletePoliciesRes: false, deletePoliciesErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -2287,83 +2251,74 @@ func TestUnassign(t *testing.T) { authCall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr) authCall1 := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.idResp.GetId(), - Permission: auth.EditPermission, + Permission: policysvc.EditPermission, Object: tc.groupID, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzResp, tc.authzErr) retrieveByIDsCall := &mock.Call{} addPoliciesCall := &mock.Call{} assignParentCall := &mock.Call{} - policies := magistrala.DeletePoliciesReq{} + policies := []policysvc.PolicyReq{} switch tc.memberKind { - case auth.ThingsKind: + case policysvc.ThingsKind: for _, memberID := range tc.memberIDs { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policysvc.PolicyReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.GroupType, - SubjectKind: auth.ChannelsKind, + SubjectType: policysvc.GroupType, + SubjectKind: policysvc.ChannelsKind, Subject: tc.groupID, Relation: tc.relation, - ObjectType: auth.ThingType, + ObjectType: policysvc.ThingType, Object: memberID, }) } - case auth.GroupsKind: + case policysvc.GroupsKind: retrieveByIDsCall = repo.On("RetrieveByIDs", context.Background(), mggroups.Page{PageMeta: mggroups.PageMeta{Limit: 1<<63 - 1}}, mock.Anything).Return(tc.repoResp, tc.repoErr) - var addPolicies magistrala.AddPoliciesReq for _, group := range tc.repoResp.Groups { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ - Domain: tc.idResp.GetDomainId(), - SubjectType: auth.GroupType, - Subject: tc.groupID, - Relation: auth.ParentGroupRelation, - ObjectType: auth.GroupType, - Object: group.ID, - }) - addPolicies.AddPoliciesReq = append(addPolicies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policysvc.PolicyReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.GroupType, + SubjectType: policysvc.GroupType, Subject: tc.groupID, - Relation: auth.ParentGroupRelation, - ObjectType: auth.GroupType, + Relation: policysvc.ParentGroupRelation, + ObjectType: policysvc.GroupType, Object: group.ID, }) } - addPoliciesCall = policy.On("AddPolicies", context.Background(), &addPolicies).Return(tc.addParentPoliciesRes, tc.addParentPoliciesErr) + addPoliciesCall = policy.On("AddPolicies", context.Background(), policies).Return(tc.addParentPoliciesErr) assignParentCall = repo.On("UnassignParentGroup", context.Background(), tc.groupID, tc.memberIDs).Return(tc.repoParentGroupErr) - case auth.ChannelsKind: + case policysvc.ChannelsKind: for _, memberID := range tc.memberIDs { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policysvc.PolicyReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.GroupType, + SubjectType: policysvc.GroupType, Subject: memberID, Relation: tc.relation, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, Object: tc.groupID, }) } - case auth.UsersKind: + case policysvc.UsersKind: for _, memberID := range tc.memberIDs { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policysvc.PolicyReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.UserType, + SubjectType: policysvc.UserType, Subject: auth.EncodeDomainUserID(tc.idResp.GetDomainId(), memberID), Relation: tc.relation, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, Object: tc.groupID, }) } } - authCall2 := policy.On("DeletePolicies", context.Background(), &policies).Return(tc.deletePoliciesRes, tc.deletePoliciesErr) + policyCall := policy.On("DeletePolicies", context.Background(), policies).Return(tc.deletePoliciesErr) err := svc.Unassign(context.Background(), tc.token, tc.groupID, tc.relation, tc.memberKind, tc.memberIDs...) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err)) authCall.Unset() authCall1.Unset() - authCall2.Unset() - if tc.memberKind == auth.GroupsKind { + policyCall.Unset() + if tc.memberKind == policysvc.GroupsKind { retrieveByIDsCall.Unset() addPoliciesCall.Unset() assignParentCall.Unset() @@ -2375,21 +2330,21 @@ func TestUnassign(t *testing.T) { func TestDeleteGroup(t *testing.T) { repo := new(mocks.Repository) authsvc := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) svc := groups.NewService(repo, idProvider, authsvc, policy) cases := []struct { - desc string - token string - groupID string - idResp *magistrala.IdentityRes - idErr error - authzResp *magistrala.AuthorizeRes - authzErr error - deletePoliciesRes bool - deletePoliciesErr error - repoErr error - err error + desc string + token string + groupID string + idResp *magistrala.IdentityRes + idErr error + authzResp *magistrala.AuthorizeRes + authzErr error + deleteSubjectPoliciesErr error + deleteObjectPoliciesErr error + repoErr error + err error }{ { desc: "successfully", @@ -2402,16 +2357,14 @@ func TestDeleteGroup(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - deletePoliciesRes: true, }, { - desc: "unsuccessfully with invalid token", - token: token, - groupID: testsutil.GenerateUUID(t), - idResp: &magistrala.IdentityRes{}, - deletePoliciesRes: false, - idErr: svcerr.ErrAuthentication, - err: svcerr.ErrAuthentication, + desc: "unsuccessfully with invalid token", + token: token, + groupID: testsutil.GenerateUUID(t), + idResp: &magistrala.IdentityRes{}, + idErr: svcerr.ErrAuthentication, + err: svcerr.ErrAuthentication, }, { desc: "unsuccessfully with authorization error", @@ -2424,12 +2377,11 @@ func TestDeleteGroup(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: false, }, - deletePoliciesRes: false, - authzErr: svcerr.ErrAuthorization, - err: svcerr.ErrAuthorization, + authzErr: svcerr.ErrAuthorization, + err: svcerr.ErrAuthorization, }, { - desc: "unsuccessfully with failed to remove policy", + desc: "unsuccessfully with failed to remove subject policies", token: token, groupID: testsutil.GenerateUUID(t), idResp: &magistrala.IdentityRes{ @@ -2439,9 +2391,22 @@ func TestDeleteGroup(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - deletePoliciesRes: false, - deletePoliciesErr: svcerr.ErrAuthorization, - err: svcerr.ErrAuthorization, + deleteSubjectPoliciesErr: svcerr.ErrAuthorization, + err: svcerr.ErrAuthorization, + }, + { + desc: "unsuccessfully with failed to remove object policies", + token: token, + groupID: testsutil.GenerateUUID(t), + idResp: &magistrala.IdentityRes{ + Id: testsutil.GenerateUUID(t), + DomainId: testsutil.GenerateUUID(t), + }, + authzResp: &magistrala.AuthorizeRes{ + Authorized: true, + }, + deleteObjectPoliciesErr: svcerr.ErrAuthorization, + err: svcerr.ErrAuthorization, }, { desc: "unsuccessfully with repo err", @@ -2454,9 +2419,8 @@ func TestDeleteGroup(t *testing.T) { authzResp: &magistrala.AuthorizeRes{ Authorized: true, }, - deletePoliciesRes: true, - repoErr: repoerr.ErrNotFound, - err: repoerr.ErrNotFound, + repoErr: repoerr.ErrNotFound, + err: repoerr.ErrNotFound, }, } @@ -2465,23 +2429,28 @@ func TestDeleteGroup(t *testing.T) { authCall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr) authCall1 := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ Domain: tc.idResp.GetDomainId(), - SubjectType: auth.UserType, - SubjectKind: auth.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.idResp.GetId(), - Permission: auth.DeletePermission, + Permission: policysvc.DeletePermission, Object: tc.groupID, - ObjectType: auth.GroupType, + ObjectType: policysvc.GroupType, }).Return(tc.authzResp, tc.authzErr) - authCall2 := policy.On("DeleteEntityPolicies", context.Background(), &magistrala.DeleteEntityPoliciesReq{ - EntityType: auth.GroupType, - Id: tc.groupID, - }).Return(tc.deletePoliciesRes, tc.deletePoliciesErr) + policyCall := policy.On("DeletePolicyFilter", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.GroupType, + Subject: tc.groupID, + }).Return(tc.deleteSubjectPoliciesErr) + policyCall2 := policy.On("DeletePolicyFilter", context.Background(), policysvc.PolicyReq{ + ObjectType: policysvc.GroupType, + Object: tc.groupID, + }).Return(tc.deleteObjectPoliciesErr) repoCall := repo.On("Delete", context.Background(), tc.groupID).Return(tc.repoErr) err := svc.DeleteGroup(context.Background(), tc.token, tc.groupID) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err)) authCall.Unset() authCall1.Unset() - authCall2.Unset() + policyCall.Unset() + policyCall2.Unset() repoCall.Unset() }) } diff --git a/internal/policy/client.go b/internal/policy/client.go new file mode 100644 index 0000000000..1c73dc0872 --- /dev/null +++ b/internal/policy/client.go @@ -0,0 +1,950 @@ +// Copyright (c) Abstract Machines +// SPDX-License-Identifier: Apache-2.0 + +package policy + +import ( + "context" + "fmt" + "io" + "log/slog" + + "github.com/absmach/magistrala/pkg/errors" + repoerr "github.com/absmach/magistrala/pkg/errors/repository" + svcerr "github.com/absmach/magistrala/pkg/errors/service" + "github.com/absmach/magistrala/pkg/policy" + v1 "github.com/authzed/authzed-go/proto/authzed/api/v1" + "github.com/authzed/authzed-go/v1" + gstatus "google.golang.org/genproto/googleapis/rpc/status" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +const defRetrieveAllLimit = 1000 + +var ( + errInvalidSubject = errors.New("invalid subject kind") + errAddPolicies = errors.New("failed to add policies") + errRetrievePolicies = errors.New("failed to retrieve policies") + errRemovePolicies = errors.New("failed to remove the policies") + errNoPolicies = errors.New("no policies provided") + errInternal = errors.New("spicedb internal error") + errPlatform = errors.New("invalid platform id") +) + +var ( + defThingsFilterPermissions = []string{ + policy.AdminPermission, + policy.DeletePermission, + policy.EditPermission, + policy.ViewPermission, + policy.SharePermission, + policy.PublishPermission, + policy.SubscribePermission, + } + + defGroupsFilterPermissions = []string{ + policy.AdminPermission, + policy.DeletePermission, + policy.EditPermission, + policy.ViewPermission, + policy.MembershipPermission, + policy.SharePermission, + } + + defDomainsFilterPermissions = []string{ + policy.AdminPermission, + policy.EditPermission, + policy.ViewPermission, + policy.MembershipPermission, + policy.SharePermission, + } + + defPlatformFilterPermissions = []string{ + policy.AdminPermission, + policy.MembershipPermission, + } +) + +type policyClient struct { + client *authzed.ClientWithExperimental + permissionClient v1.PermissionsServiceClient + logger *slog.Logger +} + +func NewPolicyClient(client *authzed.ClientWithExperimental, logger *slog.Logger) policy.PolicyClient { + return &policyClient{ + client: client, + permissionClient: client.PermissionsServiceClient, + logger: logger, + } +} + +func (pc policyClient) AddPolicy(ctx context.Context, pr policy.PolicyReq) error { + if err := pc.policyValidation(pr); err != nil { + return errors.Wrap(svcerr.ErrInvalidPolicy, err) + } + precond, err := pc.addPolicyPreCondition(ctx, pr) + if err != nil { + return err + } + + updates := []*v1.RelationshipUpdate{ + { + Operation: v1.RelationshipUpdate_OPERATION_CREATE, + Relationship: &v1.Relationship{ + Resource: &v1.ObjectReference{ObjectType: pr.ObjectType, ObjectId: pr.Object}, + Relation: pr.Relation, + Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, + }, + }, + } + _, err = pc.permissionClient.WriteRelationships(ctx, &v1.WriteRelationshipsRequest{Updates: updates, OptionalPreconditions: precond}) + if err != nil { + return errors.Wrap(errAddPolicies, handleSpicedbError(err)) + } + + return nil +} + +func (pc policyClient) AddPolicies(ctx context.Context, prs []policy.PolicyReq) error { + updates := []*v1.RelationshipUpdate{} + var preconds []*v1.Precondition + for _, pr := range prs { + if err := pc.policyValidation(pr); err != nil { + return errors.Wrap(svcerr.ErrInvalidPolicy, err) + } + precond, err := pc.addPolicyPreCondition(ctx, pr) + if err != nil { + return err + } + preconds = append(preconds, precond...) + updates = append(updates, &v1.RelationshipUpdate{ + Operation: v1.RelationshipUpdate_OPERATION_CREATE, + Relationship: &v1.Relationship{ + Resource: &v1.ObjectReference{ObjectType: pr.ObjectType, ObjectId: pr.Object}, + Relation: pr.Relation, + Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, + }, + }) + } + if len(updates) == 0 { + return errors.Wrap(errors.ErrMalformedEntity, errNoPolicies) + } + _, err := pc.permissionClient.WriteRelationships(ctx, &v1.WriteRelationshipsRequest{Updates: updates, OptionalPreconditions: preconds}) + if err != nil { + return errors.Wrap(errAddPolicies, handleSpicedbError(err)) + } + + return nil +} + +func (pc policyClient) DeletePolicyFilter(ctx context.Context, pr policy.PolicyReq) error { + req := &v1.DeleteRelationshipsRequest{ + RelationshipFilter: &v1.RelationshipFilter{ + ResourceType: pr.ObjectType, + OptionalResourceId: pr.Object, + }, + } + + if pr.Relation != "" { + req.RelationshipFilter.OptionalRelation = pr.Relation + } + + if pr.SubjectType != "" { + req.RelationshipFilter.OptionalSubjectFilter = &v1.SubjectFilter{ + SubjectType: pr.SubjectType, + } + if pr.Subject != "" { + req.RelationshipFilter.OptionalSubjectFilter.OptionalSubjectId = pr.Subject + } + if pr.SubjectRelation != "" { + req.RelationshipFilter.OptionalSubjectFilter.OptionalRelation = &v1.SubjectFilter_RelationFilter{ + Relation: pr.SubjectRelation, + } + } + } + + if _, err := pc.permissionClient.DeleteRelationships(ctx, req); err != nil { + return errors.Wrap(errRemovePolicies, handleSpicedbError(err)) + } + + return nil +} + +func (pc policyClient) DeletePolicies(ctx context.Context, prs []policy.PolicyReq) error { + updates := []*v1.RelationshipUpdate{} + for _, pr := range prs { + if err := pc.policyValidation(pr); err != nil { + return errors.Wrap(svcerr.ErrInvalidPolicy, err) + } + updates = append(updates, &v1.RelationshipUpdate{ + Operation: v1.RelationshipUpdate_OPERATION_DELETE, + Relationship: &v1.Relationship{ + Resource: &v1.ObjectReference{ObjectType: pr.ObjectType, ObjectId: pr.Object}, + Relation: pr.Relation, + Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, + }, + }) + } + if len(updates) == 0 { + return errors.Wrap(errors.ErrMalformedEntity, errNoPolicies) + } + _, err := pc.permissionClient.WriteRelationships(ctx, &v1.WriteRelationshipsRequest{Updates: updates}) + if err != nil { + return errors.Wrap(errRemovePolicies, handleSpicedbError(err)) + } + + return nil +} + +func (pc policyClient) ListObjects(ctx context.Context, pr policy.PolicyReq, nextPageToken string, limit uint64) (policy.PolicyPage, error) { + if limit <= 0 { + limit = 100 + } + res, npt, err := pc.retrieveObjects(ctx, pr, nextPageToken, limit) + if err != nil { + return policy.PolicyPage{}, errors.Wrap(svcerr.ErrViewEntity, err) + } + var page policy.PolicyPage + for _, tuple := range res { + page.Policies = append(page.Policies, tuple.Object) + } + page.NextPageToken = npt + + return page, nil +} + +func (pc policyClient) ListAllObjects(ctx context.Context, pr policy.PolicyReq) (policy.PolicyPage, error) { + res, err := pc.retrieveAllObjects(ctx, pr) + if err != nil { + return policy.PolicyPage{}, errors.Wrap(svcerr.ErrViewEntity, err) + } + var page policy.PolicyPage + for _, tuple := range res { + page.Policies = append(page.Policies, tuple.Object) + } + + return page, nil +} + +func (pc policyClient) CountObjects(ctx context.Context, pr policy.PolicyReq) (uint64, error) { + var count uint64 + nextPageToken := "" + for { + relationTuples, npt, err := pc.retrieveObjects(ctx, pr, nextPageToken, defRetrieveAllLimit) + if err != nil { + return count, err + } + count = count + uint64(len(relationTuples)) + if npt == "" { + break + } + nextPageToken = npt + } + + return count, nil +} + +func (pc policyClient) ListSubjects(ctx context.Context, pr policy.PolicyReq, nextPageToken string, limit uint64) (policy.PolicyPage, error) { + if limit <= 0 { + limit = 100 + } + res, npt, err := pc.retrieveSubjects(ctx, pr, nextPageToken, limit) + if err != nil { + return policy.PolicyPage{}, errors.Wrap(svcerr.ErrViewEntity, err) + } + var page policy.PolicyPage + for _, tuple := range res { + page.Policies = append(page.Policies, tuple.Subject) + } + page.NextPageToken = npt + + return page, nil +} + +func (pc policyClient) ListAllSubjects(ctx context.Context, pr policy.PolicyReq) (policy.PolicyPage, error) { + res, err := pc.retrieveAllSubjects(ctx, pr) + if err != nil { + return policy.PolicyPage{}, errors.Wrap(svcerr.ErrViewEntity, err) + } + var page policy.PolicyPage + for _, tuple := range res { + page.Policies = append(page.Policies, tuple.Subject) + } + + return page, nil +} + +func (pc policyClient) CountSubjects(ctx context.Context, pr policy.PolicyReq) (uint64, error) { + var count uint64 + nextPageToken := "" + for { + relationTuples, npt, err := pc.retrieveSubjects(ctx, pr, nextPageToken, defRetrieveAllLimit) + if err != nil { + return count, err + } + count = count + uint64(len(relationTuples)) + if npt == "" { + break + } + nextPageToken = npt + } + + return count, nil +} + +func (pc policyClient) ListPermissions(ctx context.Context, pr policy.PolicyReq, permissionsFilter []string) (policy.Permissions, error) { + if len(permissionsFilter) == 0 { + switch pr.ObjectType { + case policy.ThingType: + permissionsFilter = defThingsFilterPermissions + case policy.GroupType: + permissionsFilter = defGroupsFilterPermissions + case policy.PlatformType: + permissionsFilter = defPlatformFilterPermissions + case policy.DomainType: + permissionsFilter = defDomainsFilterPermissions + default: + return nil, svcerr.ErrMalformedEntity + } + } + pers, err := pc.retrievePermissions(ctx, pr, permissionsFilter) + if err != nil { + return []string{}, errors.Wrap(svcerr.ErrViewEntity, err) + } + + return pers, nil +} + +func (pc policyClient) policyValidation(pr policy.PolicyReq) error { + if pr.ObjectType == policy.PlatformType && pr.Object != policy.MagistralaObject { + return errPlatform + } + + return nil +} + +func (pc policyClient) addPolicyPreCondition(ctx context.Context, pr policy.PolicyReq) ([]*v1.Precondition, error) { + // Checks are required for following ( -> means adding) + // 1.) user -> group (both user groups and channels) + // 2.) user -> thing + // 3.) group -> group (both for adding parent_group and channels) + // 4.) group (channel) -> thing + // 5.) user -> domain + + switch { + // 1.) user -> group (both user groups and channels) + // Checks : + // - USER with ANY RELATION to DOMAIN + // - GROUP with DOMAIN RELATION to DOMAIN + case pr.SubjectType == policy.UserType && pr.ObjectType == policy.GroupType: + return pc.userGroupPreConditions(ctx, pr) + + // 2.) user -> thing + // Checks : + // - USER with ANY RELATION to DOMAIN + // - THING with DOMAIN RELATION to DOMAIN + case pr.SubjectType == policy.UserType && pr.ObjectType == policy.ThingType: + return pc.userThingPreConditions(ctx, pr) + + // 3.) group -> group (both for adding parent_group and channels) + // Checks : + // - CHILD_GROUP with out PARENT_GROUP RELATION with any GROUP + case pr.SubjectType == policy.GroupType && pr.ObjectType == policy.GroupType: + return groupPreConditions(pr) + + // 4.) group (channel) -> thing + // Checks : + // - GROUP (channel) with DOMAIN RELATION to DOMAIN + // - NO GROUP should not have PARENT_GROUP RELATION with GROUP (channel) + // - THING with DOMAIN RELATION to DOMAIN + case pr.SubjectType == policy.GroupType && pr.ObjectType == policy.ThingType: + return channelThingPreCondition(pr) + + // 5.) user -> domain + // Checks : + // - User doesn't have any relation with domain + case pr.SubjectType == policy.UserType && pr.ObjectType == policy.DomainType: + return pc.userDomainPreConditions(ctx, pr) + + // Check thing and group not belongs to other domain before adding to domain + case pr.SubjectType == policy.DomainType && pr.Relation == policy.DomainRelation && (pr.ObjectType == policy.ThingType || pr.ObjectType == policy.GroupType): + preconds := []*v1.Precondition{ + { + Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: pr.ObjectType, + OptionalResourceId: pr.Object, + OptionalRelation: policy.DomainRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.DomainType, + }, + }, + }, + } + return preconds, nil + } + + return nil, nil +} + +func (pc policyClient) userGroupPreConditions(ctx context.Context, pr policy.PolicyReq) ([]*v1.Precondition, error) { + var preconds []*v1.Precondition + + // user should not have any relation with group + preconds = append(preconds, &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.GroupType, + OptionalResourceId: pr.Object, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.UserType, + OptionalSubjectId: pr.Subject, + }, + }, + }) + isSuperAdmin := false + if err := pc.checkPolicy(ctx, policy.PolicyReq{ + Subject: pr.Subject, + SubjectType: pr.SubjectType, + Permission: policy.AdminPermission, + Object: policy.MagistralaObject, + ObjectType: policy.PlatformType, + }); err == nil { + isSuperAdmin = true + } + + if !isSuperAdmin { + preconds = append(preconds, &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.DomainType, + OptionalResourceId: pr.Domain, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.UserType, + OptionalSubjectId: pr.Subject, + }, + }, + }) + } + switch { + case pr.ObjectKind == policy.NewGroupKind || pr.ObjectKind == policy.NewChannelKind: + preconds = append(preconds, + &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.GroupType, + OptionalResourceId: pr.Object, + OptionalRelation: policy.DomainRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.DomainType, + }, + }, + }, + ) + default: + preconds = append(preconds, + &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.GroupType, + OptionalResourceId: pr.Object, + OptionalRelation: policy.DomainRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.DomainType, + OptionalSubjectId: pr.Domain, + }, + }, + }, + ) + } + + return preconds, nil +} + +func (pc policyClient) userThingPreConditions(ctx context.Context, pr policy.PolicyReq) ([]*v1.Precondition, error) { + var preconds []*v1.Precondition + + // user should not have any relation with thing + preconds = append(preconds, &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.ThingType, + OptionalResourceId: pr.Object, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.UserType, + OptionalSubjectId: pr.Subject, + }, + }, + }) + + isSuperAdmin := false + if err := pc.checkPolicy(ctx, policy.PolicyReq{ + Subject: pr.Subject, + SubjectType: pr.SubjectType, + Permission: policy.AdminPermission, + Object: policy.MagistralaObject, + ObjectType: policy.PlatformType, + }); err == nil { + isSuperAdmin = true + } + + if !isSuperAdmin { + preconds = append(preconds, &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.DomainType, + OptionalResourceId: pr.Domain, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.UserType, + OptionalSubjectId: pr.Subject, + }, + }, + }) + } + switch { + // For New thing + // - THING without DOMAIN RELATION to ANY DOMAIN + case pr.ObjectKind == policy.NewThingKind: + preconds = append(preconds, + &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.ThingType, + OptionalResourceId: pr.Object, + OptionalRelation: policy.DomainRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.DomainType, + }, + }, + }, + ) + default: + // For existing thing + // - THING without DOMAIN RELATION to ANY DOMAIN + preconds = append(preconds, + &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.ThingType, + OptionalResourceId: pr.Object, + OptionalRelation: policy.DomainRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.DomainType, + OptionalSubjectId: pr.Domain, + }, + }, + }, + ) + } + + return preconds, nil +} + +func (pc policyClient) userDomainPreConditions(ctx context.Context, pr policy.PolicyReq) ([]*v1.Precondition, error) { + var preconds []*v1.Precondition + + if err := pc.checkPolicy(ctx, policy.PolicyReq{ + Subject: pr.Subject, + SubjectType: pr.SubjectType, + Permission: policy.AdminPermission, + Object: policy.MagistralaObject, + ObjectType: policy.PlatformType, + }); err == nil { + return preconds, fmt.Errorf("use already exists in domain") + } + + // user should not have any relation with domain. + preconds = append(preconds, &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.DomainType, + OptionalResourceId: pr.Object, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.UserType, + OptionalSubjectId: pr.Subject, + }, + }, + }) + + return preconds, nil +} + +func (pc policyClient) checkPolicy(ctx context.Context, pr policy.PolicyReq) error { + checkReq := v1.CheckPermissionRequest{ + // FullyConsistent means little caching will be available, which means performance will suffer. + // Only use if a ZedToken is not available or absolutely latest information is required. + // If we want to avoid FullyConsistent and to improve the performance of spicedb, then we need to cache the ZEDTOKEN whenever RELATIONS is created or updated. + // Instead of using FullyConsistent we need to use Consistency_AtLeastAsFresh, code looks like below one. + // Consistency: &v1.Consistency{ + // Requirement: &v1.Consistency_AtLeastAsFresh{ + // AtLeastAsFresh: getRelationTupleZedTokenFromCache() , + // } + // }, + // Reference: https://authzed.com/docs/reference/api-consistency + Consistency: &v1.Consistency{ + Requirement: &v1.Consistency_FullyConsistent{ + FullyConsistent: true, + }, + }, + Resource: &v1.ObjectReference{ObjectType: pr.ObjectType, ObjectId: pr.Object}, + Permission: pr.Permission, + Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, + } + + resp, err := pc.permissionClient.CheckPermission(ctx, &checkReq) + if err != nil { + return handleSpicedbError(err) + } + if resp.Permissionship == v1.CheckPermissionResponse_PERMISSIONSHIP_HAS_PERMISSION { + return nil + } + if reason, ok := v1.CheckPermissionResponse_Permissionship_name[int32(resp.Permissionship)]; ok { + return errors.Wrap(svcerr.ErrAuthorization, errors.New(reason)) + } + return svcerr.ErrAuthorization +} + +func (pc policyClient) retrieveObjects(ctx context.Context, pr policy.PolicyReq, nextPageToken string, limit uint64) ([]policy.PolicyRes, string, error) { + resourceReq := &v1.LookupResourcesRequest{ + Consistency: &v1.Consistency{ + Requirement: &v1.Consistency_FullyConsistent{ + FullyConsistent: true, + }, + }, + ResourceObjectType: pr.ObjectType, + Permission: pr.Permission, + Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, + OptionalLimit: uint32(limit), + } + if nextPageToken != "" { + resourceReq.OptionalCursor = &v1.Cursor{Token: nextPageToken} + } + stream, err := pc.permissionClient.LookupResources(ctx, resourceReq) + if err != nil { + return nil, "", errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) + } + resources := []*v1.LookupResourcesResponse{} + var token string + for { + resp, err := stream.Recv() + switch err { + case nil: + resources = append(resources, resp) + case io.EOF: + if len(resources) > 0 && resources[len(resources)-1].AfterResultCursor != nil { + token = resources[len(resources)-1].AfterResultCursor.Token + } + return objectsToAuthPolicies(resources), token, nil + default: + if len(resources) > 0 && resources[len(resources)-1].AfterResultCursor != nil { + token = resources[len(resources)-1].AfterResultCursor.Token + } + return []policy.PolicyRes{}, token, errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) + } + } +} + +func (pc policyClient) retrieveAllObjects(ctx context.Context, pr policy.PolicyReq) ([]policy.PolicyRes, error) { + resourceReq := &v1.LookupResourcesRequest{ + Consistency: &v1.Consistency{ + Requirement: &v1.Consistency_FullyConsistent{ + FullyConsistent: true, + }, + }, + ResourceObjectType: pr.ObjectType, + Permission: pr.Permission, + Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: pr.SubjectType, ObjectId: pr.Subject}, OptionalRelation: pr.SubjectRelation}, + } + stream, err := pc.permissionClient.LookupResources(ctx, resourceReq) + if err != nil { + return nil, errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) + } + tuples := []policy.PolicyRes{} + for { + resp, err := stream.Recv() + switch { + case errors.Contains(err, io.EOF): + return tuples, nil + case err != nil: + return tuples, errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) + default: + tuples = append(tuples, policy.PolicyRes{Object: resp.ResourceObjectId}) + } + } +} + +func (pc policyClient) retrieveSubjects(ctx context.Context, pr policy.PolicyReq, nextPageToken string, limit uint64) ([]policy.PolicyRes, string, error) { + subjectsReq := v1.LookupSubjectsRequest{ + Consistency: &v1.Consistency{ + Requirement: &v1.Consistency_FullyConsistent{ + FullyConsistent: true, + }, + }, + Resource: &v1.ObjectReference{ObjectType: pr.ObjectType, ObjectId: pr.Object}, + Permission: pr.Permission, + SubjectObjectType: pr.SubjectType, + OptionalSubjectRelation: pr.SubjectRelation, + OptionalConcreteLimit: uint32(limit), + WildcardOption: v1.LookupSubjectsRequest_WILDCARD_OPTION_INCLUDE_WILDCARDS, + } + if nextPageToken != "" { + subjectsReq.OptionalCursor = &v1.Cursor{Token: nextPageToken} + } + stream, err := pc.permissionClient.LookupSubjects(ctx, &subjectsReq) + if err != nil { + return nil, "", errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) + } + subjects := []*v1.LookupSubjectsResponse{} + var token string + for { + resp, err := stream.Recv() + + switch err { + case nil: + subjects = append(subjects, resp) + case io.EOF: + if len(subjects) > 0 && subjects[len(subjects)-1].AfterResultCursor != nil { + token = subjects[len(subjects)-1].AfterResultCursor.Token + } + return subjectsToAuthPolicies(subjects), token, nil + default: + if len(subjects) > 0 && subjects[len(subjects)-1].AfterResultCursor != nil { + token = subjects[len(subjects)-1].AfterResultCursor.Token + } + return []policy.PolicyRes{}, token, errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) + } + } +} + +func (pc policyClient) retrieveAllSubjects(ctx context.Context, pr policy.PolicyReq) ([]policy.PolicyRes, error) { + var tuples []policy.PolicyRes + nextPageToken := "" + for i := 0; ; i++ { + relationTuples, npt, err := pc.retrieveSubjects(ctx, pr, nextPageToken, defRetrieveAllLimit) + if err != nil { + return tuples, err + } + tuples = append(tuples, relationTuples...) + if npt == "" || (len(tuples) < defRetrieveAllLimit) { + break + } + nextPageToken = npt + } + return tuples, nil +} + +func (pc policyClient) retrievePermissions(ctx context.Context, pr policy.PolicyReq, filterPermission []string) (policy.Permissions, error) { + var permissionChecks []*v1.CheckBulkPermissionsRequestItem + for _, fp := range filterPermission { + permissionChecks = append(permissionChecks, &v1.CheckBulkPermissionsRequestItem{ + Resource: &v1.ObjectReference{ + ObjectType: pr.ObjectType, + ObjectId: pr.Object, + }, + Permission: fp, + Subject: &v1.SubjectReference{ + Object: &v1.ObjectReference{ + ObjectType: pr.SubjectType, + ObjectId: pr.Subject, + }, + OptionalRelation: pr.SubjectRelation, + }, + }) + } + resp, err := pc.client.PermissionsServiceClient.CheckBulkPermissions(ctx, &v1.CheckBulkPermissionsRequest{ + Consistency: &v1.Consistency{ + Requirement: &v1.Consistency_FullyConsistent{ + FullyConsistent: true, + }, + }, + Items: permissionChecks, + }) + if err != nil { + return policy.Permissions{}, errors.Wrap(errRetrievePolicies, handleSpicedbError(err)) + } + + permissions := []string{} + for _, pair := range resp.Pairs { + if pair.GetError() != nil { + s := pair.GetError() + return policy.Permissions{}, errors.Wrap(errRetrievePolicies, convertGRPCStatusToError(convertToGrpcStatus(s))) + } + item := pair.GetItem() + req := pair.GetRequest() + if item != nil && req != nil && item.Permissionship == v1.CheckPermissionResponse_PERMISSIONSHIP_HAS_PERMISSION { + permissions = append(permissions, req.GetPermission()) + } + } + return permissions, nil +} + +func groupPreConditions(pr policy.PolicyReq) ([]*v1.Precondition, error) { + // - PARENT_GROUP (subject) with DOMAIN RELATION to DOMAIN + precond := []*v1.Precondition{ + { + Operation: v1.Precondition_OPERATION_MUST_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.GroupType, + OptionalResourceId: pr.Subject, + OptionalRelation: policy.DomainRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.DomainType, + OptionalSubjectId: pr.Domain, + }, + }, + }, + } + if pr.ObjectKind != policy.ChannelsKind { + precond = append(precond, + &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.GroupType, + OptionalResourceId: pr.Object, + OptionalRelation: policy.ParentGroupRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.GroupType, + }, + }, + }, + ) + } + switch { + // - NEW CHILD_GROUP (object) with out DOMAIN RELATION to ANY DOMAIN + case pr.ObjectType == policy.GroupType && pr.ObjectKind == policy.NewGroupKind: + precond = append(precond, + &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.GroupType, + OptionalResourceId: pr.Object, + OptionalRelation: policy.DomainRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.DomainType, + }, + }, + }, + ) + default: + // - CHILD_GROUP (object) with DOMAIN RELATION to DOMAIN + precond = append(precond, + &v1.Precondition{ + Operation: v1.Precondition_OPERATION_MUST_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.GroupType, + OptionalResourceId: pr.Object, + OptionalRelation: policy.DomainRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.DomainType, + OptionalSubjectId: pr.Domain, + }, + }, + }, + ) + } + return precond, nil +} + +func channelThingPreCondition(pr policy.PolicyReq) ([]*v1.Precondition, error) { + if pr.SubjectKind != policy.ChannelsKind { + return nil, errors.Wrap(errors.ErrMalformedEntity, errInvalidSubject) + } + precond := []*v1.Precondition{ + { + Operation: v1.Precondition_OPERATION_MUST_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.GroupType, + OptionalResourceId: pr.Subject, + OptionalRelation: policy.DomainRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.DomainType, + OptionalSubjectId: pr.Domain, + }, + }, + }, + { + Operation: v1.Precondition_OPERATION_MUST_NOT_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.GroupType, + OptionalRelation: policy.ParentGroupRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.GroupType, + OptionalSubjectId: pr.Subject, + }, + }, + }, + { + Operation: v1.Precondition_OPERATION_MUST_MATCH, + Filter: &v1.RelationshipFilter{ + ResourceType: policy.ThingType, + OptionalResourceId: pr.Object, + OptionalRelation: policy.DomainRelation, + OptionalSubjectFilter: &v1.SubjectFilter{ + SubjectType: policy.DomainType, + OptionalSubjectId: pr.Domain, + }, + }, + }, + } + return precond, nil +} + +func objectsToAuthPolicies(objects []*v1.LookupResourcesResponse) []policy.PolicyRes { + var policies []policy.PolicyRes + for _, obj := range objects { + policies = append(policies, policy.PolicyRes{ + Object: obj.GetResourceObjectId(), + }) + } + return policies +} + +func subjectsToAuthPolicies(subjects []*v1.LookupSubjectsResponse) []policy.PolicyRes { + var policies []policy.PolicyRes + for _, sub := range subjects { + policies = append(policies, policy.PolicyRes{ + Subject: sub.Subject.GetSubjectObjectId(), + }) + } + return policies +} + +func handleSpicedbError(err error) error { + if st, ok := status.FromError(err); ok { + return convertGRPCStatusToError(st) + } + return err +} + +func convertToGrpcStatus(gst *gstatus.Status) *status.Status { + st := status.New(codes.Code(gst.Code), gst.GetMessage()) + return st +} + +func convertGRPCStatusToError(st *status.Status) error { + switch st.Code() { + case codes.NotFound: + return errors.Wrap(repoerr.ErrNotFound, errors.New(st.Message())) + case codes.InvalidArgument: + return errors.Wrap(errors.ErrMalformedEntity, errors.New(st.Message())) + case codes.AlreadyExists: + return errors.Wrap(repoerr.ErrConflict, errors.New(st.Message())) + case codes.Unauthenticated: + return errors.Wrap(svcerr.ErrAuthentication, errors.New(st.Message())) + case codes.Internal: + return errors.Wrap(errInternal, errors.New(st.Message())) + case codes.OK: + if msg := st.Message(); msg != "" { + return errors.Wrap(errors.ErrUnidentified, errors.New(msg)) + } + return nil + case codes.FailedPrecondition: + return errors.Wrap(errors.ErrMalformedEntity, errors.New(st.Message())) + case codes.PermissionDenied: + return errors.Wrap(svcerr.ErrAuthorization, errors.New(st.Message())) + default: + return errors.Wrap(fmt.Errorf("unexpected gRPC status: %s (status code:%v)", st.Code().String(), st.Code()), errors.New(st.Message())) + } +} diff --git a/internal/policy/service.go b/internal/policy/service.go deleted file mode 100644 index 72de9240fe..0000000000 --- a/internal/policy/service.go +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) Abstract Machines -// SPDX-License-Identifier: Apache-2.0 - -package policy - -import ( - "context" - - "github.com/absmach/magistrala" - "github.com/absmach/magistrala/pkg/policy" -) - -type service struct { - policy magistrala.PolicyServiceClient -} - -func NewService(policyClient magistrala.PolicyServiceClient) policy.PolicyService { - return &service{ - policy: policyClient, - } -} - -func (svc service) AddPolicy(ctx context.Context, req *magistrala.AddPolicyReq) (bool, error) { - res, err := svc.policy.AddPolicy(ctx, req) - if err != nil { - return false, err - } - - return res.GetAdded(), nil -} - -func (svc service) AddPolicies(ctx context.Context, req *magistrala.AddPoliciesReq) (bool, error) { - res, err := svc.policy.AddPolicies(ctx, req) - if err != nil { - return false, err - } - - return res.GetAdded(), nil -} - -func (svc service) DeletePolicyFilter(ctx context.Context, req *magistrala.DeletePolicyFilterReq) (bool, error) { - res, err := svc.policy.DeletePolicyFilter(ctx, req) - if err != nil { - return false, err - } - return res.GetDeleted(), nil -} - -func (svc service) DeletePolicies(ctx context.Context, req *magistrala.DeletePoliciesReq) (bool, error) { - res, err := svc.policy.DeletePolicies(ctx, req) - if err != nil { - return false, err - } - return res.GetDeleted(), nil -} - -func (svc service) ListObjects(ctx context.Context, req *magistrala.ListObjectsReq) ([]string, error) { - res, err := svc.policy.ListObjects(ctx, req) - if err != nil { - return nil, err - } - - return res.Policies, nil -} - -func (svc service) ListAllObjects(ctx context.Context, req *magistrala.ListObjectsReq) ([]string, error) { - res, err := svc.policy.ListAllObjects(ctx, req) - if err != nil { - return nil, err - } - - return res.Policies, nil -} - -func (svc service) CountObjects(ctx context.Context, req *magistrala.CountObjectsReq) (uint64, error) { - res, err := svc.policy.CountObjects(ctx, req) - if err != nil { - return 0, err - } - - return res.Count, nil -} - -func (svc service) ListSubjects(ctx context.Context, req *magistrala.ListSubjectsReq) ([]string, error) { - res, err := svc.policy.ListSubjects(ctx, req) - if err != nil { - return nil, err - } - - return res.Policies, nil -} - -func (svc service) ListAllSubjects(ctx context.Context, req *magistrala.ListSubjectsReq) ([]string, error) { - res, err := svc.policy.ListAllSubjects(ctx, req) - if err != nil { - return nil, err - } - - return res.Policies, nil -} - -func (svc service) CountSubjects(ctx context.Context, req *magistrala.CountSubjectsReq) (uint64, error) { - res, err := svc.policy.CountSubjects(ctx, req) - if err != nil { - return 0, err - } - - return res.Count, nil -} - -func (svc service) ListPermissions(ctx context.Context, req *magistrala.ListPermissionsReq) ([]string, error) { - res, err := svc.policy.ListPermissions(ctx, req) - if err != nil { - return nil, err - } - - return res.GetPermissions(), nil -} - -func (svc service) DeleteEntityPolicies(ctx context.Context, req *magistrala.DeleteEntityPoliciesReq) (bool, error) { - res, err := svc.policy.DeleteEntityPolicies(ctx, req) - if err != nil { - return false, err - } - - return res.GetDeleted(), nil -} diff --git a/pkg/policy/mocks/client.go b/pkg/policy/mocks/client.go new file mode 100644 index 0000000000..558bb318e7 --- /dev/null +++ b/pkg/policy/mocks/client.go @@ -0,0 +1,301 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +// Copyright (c) Abstract Machines + +package mocks + +import ( + context "context" + + policy "github.com/absmach/magistrala/pkg/policy" + mock "github.com/stretchr/testify/mock" +) + +// PolicyClient is an autogenerated mock type for the PolicyClient type +type PolicyClient struct { + mock.Mock +} + +// AddPolicies provides a mock function with given fields: ctx, prs +func (_m *PolicyClient) AddPolicies(ctx context.Context, prs []policy.PolicyReq) error { + ret := _m.Called(ctx, prs) + + if len(ret) == 0 { + panic("no return value specified for AddPolicies") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []policy.PolicyReq) error); ok { + r0 = rf(ctx, prs) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// AddPolicy provides a mock function with given fields: ctx, pr +func (_m *PolicyClient) AddPolicy(ctx context.Context, pr policy.PolicyReq) error { + ret := _m.Called(ctx, pr) + + if len(ret) == 0 { + panic("no return value specified for AddPolicy") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq) error); ok { + r0 = rf(ctx, pr) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CountObjects provides a mock function with given fields: ctx, pr +func (_m *PolicyClient) CountObjects(ctx context.Context, pr policy.PolicyReq) (uint64, error) { + ret := _m.Called(ctx, pr) + + if len(ret) == 0 { + panic("no return value specified for CountObjects") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq) (uint64, error)); ok { + return rf(ctx, pr) + } + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq) uint64); ok { + r0 = rf(ctx, pr) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(context.Context, policy.PolicyReq) error); ok { + r1 = rf(ctx, pr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CountSubjects provides a mock function with given fields: ctx, pr +func (_m *PolicyClient) CountSubjects(ctx context.Context, pr policy.PolicyReq) (uint64, error) { + ret := _m.Called(ctx, pr) + + if len(ret) == 0 { + panic("no return value specified for CountSubjects") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq) (uint64, error)); ok { + return rf(ctx, pr) + } + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq) uint64); ok { + r0 = rf(ctx, pr) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(context.Context, policy.PolicyReq) error); ok { + r1 = rf(ctx, pr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeletePolicies provides a mock function with given fields: ctx, prs +func (_m *PolicyClient) DeletePolicies(ctx context.Context, prs []policy.PolicyReq) error { + ret := _m.Called(ctx, prs) + + if len(ret) == 0 { + panic("no return value specified for DeletePolicies") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []policy.PolicyReq) error); ok { + r0 = rf(ctx, prs) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeletePolicyFilter provides a mock function with given fields: ctx, pr +func (_m *PolicyClient) DeletePolicyFilter(ctx context.Context, pr policy.PolicyReq) error { + ret := _m.Called(ctx, pr) + + if len(ret) == 0 { + panic("no return value specified for DeletePolicyFilter") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq) error); ok { + r0 = rf(ctx, pr) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListAllObjects provides a mock function with given fields: ctx, pr +func (_m *PolicyClient) ListAllObjects(ctx context.Context, pr policy.PolicyReq) (policy.PolicyPage, error) { + ret := _m.Called(ctx, pr) + + if len(ret) == 0 { + panic("no return value specified for ListAllObjects") + } + + var r0 policy.PolicyPage + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq) (policy.PolicyPage, error)); ok { + return rf(ctx, pr) + } + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq) policy.PolicyPage); ok { + r0 = rf(ctx, pr) + } else { + r0 = ret.Get(0).(policy.PolicyPage) + } + + if rf, ok := ret.Get(1).(func(context.Context, policy.PolicyReq) error); ok { + r1 = rf(ctx, pr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListAllSubjects provides a mock function with given fields: ctx, pr +func (_m *PolicyClient) ListAllSubjects(ctx context.Context, pr policy.PolicyReq) (policy.PolicyPage, error) { + ret := _m.Called(ctx, pr) + + if len(ret) == 0 { + panic("no return value specified for ListAllSubjects") + } + + var r0 policy.PolicyPage + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq) (policy.PolicyPage, error)); ok { + return rf(ctx, pr) + } + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq) policy.PolicyPage); ok { + r0 = rf(ctx, pr) + } else { + r0 = ret.Get(0).(policy.PolicyPage) + } + + if rf, ok := ret.Get(1).(func(context.Context, policy.PolicyReq) error); ok { + r1 = rf(ctx, pr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListObjects provides a mock function with given fields: ctx, pr, nextPageToken, limit +func (_m *PolicyClient) ListObjects(ctx context.Context, pr policy.PolicyReq, nextPageToken string, limit uint64) (policy.PolicyPage, error) { + ret := _m.Called(ctx, pr, nextPageToken, limit) + + if len(ret) == 0 { + panic("no return value specified for ListObjects") + } + + var r0 policy.PolicyPage + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq, string, uint64) (policy.PolicyPage, error)); ok { + return rf(ctx, pr, nextPageToken, limit) + } + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq, string, uint64) policy.PolicyPage); ok { + r0 = rf(ctx, pr, nextPageToken, limit) + } else { + r0 = ret.Get(0).(policy.PolicyPage) + } + + if rf, ok := ret.Get(1).(func(context.Context, policy.PolicyReq, string, uint64) error); ok { + r1 = rf(ctx, pr, nextPageToken, limit) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListPermissions provides a mock function with given fields: ctx, pr, permissionsFilter +func (_m *PolicyClient) ListPermissions(ctx context.Context, pr policy.PolicyReq, permissionsFilter []string) (policy.Permissions, error) { + ret := _m.Called(ctx, pr, permissionsFilter) + + if len(ret) == 0 { + panic("no return value specified for ListPermissions") + } + + var r0 policy.Permissions + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq, []string) (policy.Permissions, error)); ok { + return rf(ctx, pr, permissionsFilter) + } + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq, []string) policy.Permissions); ok { + r0 = rf(ctx, pr, permissionsFilter) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(policy.Permissions) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, policy.PolicyReq, []string) error); ok { + r1 = rf(ctx, pr, permissionsFilter) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListSubjects provides a mock function with given fields: ctx, pr, nextPageToken, limit +func (_m *PolicyClient) ListSubjects(ctx context.Context, pr policy.PolicyReq, nextPageToken string, limit uint64) (policy.PolicyPage, error) { + ret := _m.Called(ctx, pr, nextPageToken, limit) + + if len(ret) == 0 { + panic("no return value specified for ListSubjects") + } + + var r0 policy.PolicyPage + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq, string, uint64) (policy.PolicyPage, error)); ok { + return rf(ctx, pr, nextPageToken, limit) + } + if rf, ok := ret.Get(0).(func(context.Context, policy.PolicyReq, string, uint64) policy.PolicyPage); ok { + r0 = rf(ctx, pr, nextPageToken, limit) + } else { + r0 = ret.Get(0).(policy.PolicyPage) + } + + if rf, ok := ret.Get(1).(func(context.Context, policy.PolicyReq, string, uint64) error); ok { + r1 = rf(ctx, pr, nextPageToken, limit) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewPolicyClient creates a new instance of PolicyClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPolicyClient(t interface { + mock.TestingT + Cleanup(func()) +}) *PolicyClient { + mock := &PolicyClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/policy/mocks/service.go b/pkg/policy/mocks/service.go deleted file mode 100644 index 03729648fc..0000000000 --- a/pkg/policy/mocks/service.go +++ /dev/null @@ -1,377 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -// Copyright (c) Abstract Machines - -package mocks - -import ( - context "context" - - magistrala "github.com/absmach/magistrala" - mock "github.com/stretchr/testify/mock" -) - -// PolicyService is an autogenerated mock type for the PolicyService type -type PolicyService struct { - mock.Mock -} - -// AddPolicies provides a mock function with given fields: ctx, req -func (_m *PolicyService) AddPolicies(ctx context.Context, req *magistrala.AddPoliciesReq) (bool, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for AddPolicies") - } - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.AddPoliciesReq) (bool, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.AddPoliciesReq) bool); ok { - r0 = rf(ctx, req) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.AddPoliciesReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// AddPolicy provides a mock function with given fields: ctx, req -func (_m *PolicyService) AddPolicy(ctx context.Context, req *magistrala.AddPolicyReq) (bool, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for AddPolicy") - } - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.AddPolicyReq) (bool, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.AddPolicyReq) bool); ok { - r0 = rf(ctx, req) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.AddPolicyReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CountObjects provides a mock function with given fields: ctx, req -func (_m *PolicyService) CountObjects(ctx context.Context, req *magistrala.CountObjectsReq) (uint64, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for CountObjects") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.CountObjectsReq) (uint64, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.CountObjectsReq) uint64); ok { - r0 = rf(ctx, req) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.CountObjectsReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CountSubjects provides a mock function with given fields: ctx, req -func (_m *PolicyService) CountSubjects(ctx context.Context, req *magistrala.CountSubjectsReq) (uint64, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for CountSubjects") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.CountSubjectsReq) (uint64, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.CountSubjectsReq) uint64); ok { - r0 = rf(ctx, req) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.CountSubjectsReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteEntityPolicies provides a mock function with given fields: ctx, req -func (_m *PolicyService) DeleteEntityPolicies(ctx context.Context, req *magistrala.DeleteEntityPoliciesReq) (bool, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for DeleteEntityPolicies") - } - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeleteEntityPoliciesReq) (bool, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeleteEntityPoliciesReq) bool); ok { - r0 = rf(ctx, req) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.DeleteEntityPoliciesReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeletePolicies provides a mock function with given fields: ctx, req -func (_m *PolicyService) DeletePolicies(ctx context.Context, req *magistrala.DeletePoliciesReq) (bool, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for DeletePolicies") - } - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeletePoliciesReq) (bool, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeletePoliciesReq) bool); ok { - r0 = rf(ctx, req) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.DeletePoliciesReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeletePolicyFilter provides a mock function with given fields: ctx, req -func (_m *PolicyService) DeletePolicyFilter(ctx context.Context, req *magistrala.DeletePolicyFilterReq) (bool, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for DeletePolicyFilter") - } - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeletePolicyFilterReq) (bool, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.DeletePolicyFilterReq) bool); ok { - r0 = rf(ctx, req) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.DeletePolicyFilterReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListAllObjects provides a mock function with given fields: ctx, req -func (_m *PolicyService) ListAllObjects(ctx context.Context, req *magistrala.ListObjectsReq) ([]string, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for ListAllObjects") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListObjectsReq) ([]string, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListObjectsReq) []string); ok { - r0 = rf(ctx, req) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.ListObjectsReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListAllSubjects provides a mock function with given fields: ctx, req -func (_m *PolicyService) ListAllSubjects(ctx context.Context, req *magistrala.ListSubjectsReq) ([]string, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for ListAllSubjects") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListSubjectsReq) ([]string, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListSubjectsReq) []string); ok { - r0 = rf(ctx, req) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.ListSubjectsReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListObjects provides a mock function with given fields: ctx, req -func (_m *PolicyService) ListObjects(ctx context.Context, req *magistrala.ListObjectsReq) ([]string, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for ListObjects") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListObjectsReq) ([]string, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListObjectsReq) []string); ok { - r0 = rf(ctx, req) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.ListObjectsReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListPermissions provides a mock function with given fields: ctx, req -func (_m *PolicyService) ListPermissions(ctx context.Context, req *magistrala.ListPermissionsReq) ([]string, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for ListPermissions") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListPermissionsReq) ([]string, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListPermissionsReq) []string); ok { - r0 = rf(ctx, req) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.ListPermissionsReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListSubjects provides a mock function with given fields: ctx, req -func (_m *PolicyService) ListSubjects(ctx context.Context, req *magistrala.ListSubjectsReq) ([]string, error) { - ret := _m.Called(ctx, req) - - if len(ret) == 0 { - panic("no return value specified for ListSubjects") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListSubjectsReq) ([]string, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(context.Context, *magistrala.ListSubjectsReq) []string); ok { - r0 = rf(ctx, req) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *magistrala.ListSubjectsReq) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NewPolicyService creates a new instance of PolicyService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewPolicyService(t interface { - mock.TestingT - Cleanup(func()) -}) *PolicyService { - mock := &PolicyService{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/pkg/policy/policy.go b/pkg/policy/policy.go index 4bbd8cdfa4..3f266e52d1 100644 --- a/pkg/policy/policy.go +++ b/pkg/policy/policy.go @@ -5,49 +5,159 @@ package policy import ( "context" + "encoding/json" +) + +const ( + TokenKind = "token" + GroupsKind = "groups" + NewGroupKind = "new_group" + ChannelsKind = "channels" + NewChannelKind = "new_channel" + ThingsKind = "things" + NewThingKind = "new_thing" + UsersKind = "users" + DomainsKind = "domains" + PlatformKind = "platform" +) + +const ( + GroupType = "group" + ThingType = "thing" + UserType = "user" + DomainType = "domain" + PlatformType = "platform" +) + +const ( + AdministratorRelation = "administrator" + EditorRelation = "editor" + ContributorRelation = "contributor" + MemberRelation = "member" + DomainRelation = "domain" + ParentGroupRelation = "parent_group" + RoleGroupRelation = "role_group" + GroupRelation = "group" + PlatformRelation = "platform" + GuestRelation = "guest" +) - "github.com/absmach/magistrala" +const ( + AdminPermission = "admin" + DeletePermission = "delete" + EditPermission = "edit" + ViewPermission = "view" + MembershipPermission = "membership" + SharePermission = "share" + PublishPermission = "publish" + SubscribePermission = "subscribe" + CreatePermission = "create" ) -//go:generate mockery --name PolicyService --filename service.go --quiet --note "Copyright (c) Abstract Machines" -type PolicyService interface { +const MagistralaObject = "magistrala" + +type PolicyReq struct { + // Domain contains the domain ID. + Domain string `json:"domain,omitempty"` + + // Subject contains the subject ID or Token. + Subject string `json:"subject"` + + // SubjectType contains the subject type. Supported subject types are + // platform, group, domain, thing, users. + SubjectType string `json:"subject_type"` + + // SubjectKind contains the subject kind. Supported subject kinds are + // token, users, platform, things, channels, groups, domain. + SubjectKind string `json:"subject_kind"` + + // SubjectRelation contains subject relations. + SubjectRelation string `json:"subject_relation,omitempty"` + + // Object contains the object ID. + Object string `json:"object"` + + // ObjectKind contains the object kind. Supported object kinds are + // users, platform, things, channels, groups, domain. + ObjectKind string `json:"object_kind"` + + // ObjectType contains the object type. Supported object types are + // platform, group, domain, thing, users. + ObjectType string `json:"object_type"` + + // Relation contains the relation. Supported relations are administrator, editor, contributor, member, guest, parent_group,group,domain. + Relation string `json:"relation,omitempty"` + + // Permission contains the permission. Supported permissions are admin, delete, edit, share, view, + // membership, create, admin_only, edit_only, view_only, membership_only, ext_admin, ext_edit, ext_view. + Permission string `json:"permission,omitempty"` +} + +func (pr PolicyReq) String() string { + data, err := json.Marshal(pr) + if err != nil { + return "" + } + return string(data) +} + +type PolicyRes struct { + Namespace string + Subject string + SubjectType string + SubjectRelation string + Object string + ObjectType string + Relation string + Permission string +} + +type PolicyPage struct { + Policies []string + NextPageToken string +} + +type Permissions []string + +// PolicyClient facilitates the communication to authorization +// services and implements Authz functionalities for spicedb +// +//go:generate mockery --name PolicyClient --filename client.go --quiet --note "Copyright (c) Abstract Machines" +type PolicyClient interface { // AddPolicy creates a policy for the given subject, so that, after // AddPolicy, `subject` has a `relation` on `object`. Returns a non-nil // error in case of failures. - AddPolicy(ctx context.Context, req *magistrala.AddPolicyReq) (bool, error) + AddPolicy(ctx context.Context, pr PolicyReq) error // AddPolicies adds new policies for given subjects. This method is // only allowed to use as an admin. - AddPolicies(ctx context.Context, req *magistrala.AddPoliciesReq) (bool, error) + AddPolicies(ctx context.Context, prs []PolicyReq) error // DeletePolicyFilter removes policy for given policy filter request. - DeletePolicyFilter(ctx context.Context, req *magistrala.DeletePolicyFilterReq) (bool, error) + DeletePolicyFilter(ctx context.Context, pr PolicyReq) error // DeletePolicies deletes policies for given subjects. This method is // only allowed to use as an admin. - DeletePolicies(ctx context.Context, req *magistrala.DeletePoliciesReq) (bool, error) + DeletePolicies(ctx context.Context, prs []PolicyReq) error // ListObjects lists policies based on the given PolicyReq structure. - ListObjects(ctx context.Context, req *magistrala.ListObjectsReq) ([]string, error) + ListObjects(ctx context.Context, pr PolicyReq, nextPageToken string, limit uint64) (PolicyPage, error) // ListAllObjects lists all policies based on the given PolicyReq structure. - ListAllObjects(ctx context.Context, req *magistrala.ListObjectsReq) ([]string, error) + ListAllObjects(ctx context.Context, pr PolicyReq) (PolicyPage, error) // CountObjects count policies based on the given PolicyReq structure. - CountObjects(ctx context.Context, req *magistrala.CountObjectsReq) (uint64, error) + CountObjects(ctx context.Context, pr PolicyReq) (uint64, error) // ListSubjects lists subjects based on the given PolicyReq structure. - ListSubjects(ctx context.Context, req *magistrala.ListSubjectsReq) ([]string, error) + ListSubjects(ctx context.Context, pr PolicyReq, nextPageToken string, limit uint64) (PolicyPage, error) // ListAllSubjects lists all subjects based on the given PolicyReq structure. - ListAllSubjects(ctx context.Context, req *magistrala.ListSubjectsReq) ([]string, error) + ListAllSubjects(ctx context.Context, pr PolicyReq) (PolicyPage, error) // CountSubjects count policies based on the given PolicyReq structure. - CountSubjects(ctx context.Context, req *magistrala.CountSubjectsReq) (uint64, error) + CountSubjects(ctx context.Context, pr PolicyReq) (uint64, error) // ListPermissions lists permission betweeen given subject and object . - ListPermissions(ctx context.Context, req *magistrala.ListPermissionsReq) ([]string, error) - - // DeleteEntityPolicies deletes all policies for the given entity. - DeleteEntityPolicies(ctx context.Context, req *magistrala.DeleteEntityPoliciesReq) (bool, error) + ListPermissions(ctx context.Context, pr PolicyReq, permissionsFilter []string) (Permissions, error) } diff --git a/things/service.go b/things/service.go index 610ee42777..8033c647c1 100644 --- a/things/service.go +++ b/things/service.go @@ -20,7 +20,7 @@ import ( type service struct { auth grpcclient.AuthServiceClient - policy policy.PolicyService + policy policy.PolicyClient clients postgres.Repository clientCache Cache idProvider magistrala.IDProvider @@ -28,10 +28,10 @@ type service struct { } // NewService returns a new Clients service implementation. -func NewService(auth grpcclient.AuthServiceClient, policyService policy.PolicyService, c postgres.Repository, grepo mggroups.Repository, tcache Cache, idp magistrala.IDProvider) Service { +func NewService(authClient grpcclient.AuthServiceClient, policyClient policy.PolicyClient, c postgres.Repository, grepo mggroups.Repository, tcache Cache, idp magistrala.IDProvider) Service { return service{ - auth: auth, - policy: policyService, + auth: authClient, + policy: policyClient, clients: c, grepo: grepo, clientCache: tcache, @@ -221,12 +221,12 @@ func (svc service) retrievePermissions(ctx context.Context, userID string, clien } func (svc service) listUserThingPermission(ctx context.Context, userID, thingID string) ([]string, error) { - permissions, err := svc.policy.ListPermissions(ctx, &magistrala.ListPermissionsReq{ + permissions, err := svc.policy.ListPermissions(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Object: thingID, ObjectType: auth.ThingType, - }) + }, []string{}) if err != nil { return []string{}, errors.Wrap(svcerr.ErrAuthorization, err) } @@ -234,7 +234,7 @@ func (svc service) listUserThingPermission(ctx context.Context, userID, thingID } func (svc service) listClientIDs(ctx context.Context, userID, permission string) ([]string, error) { - tids, err := svc.policy.ListAllObjects(ctx, &magistrala.ListObjectsReq{ + tids, err := svc.policy.ListAllObjects(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Permission: permission, @@ -243,12 +243,12 @@ func (svc service) listClientIDs(ctx context.Context, userID, permission string) if err != nil { return nil, errors.Wrap(svcerr.ErrNotFound, err) } - return tids, nil + return tids.Policies, nil } func (svc service) filterAllowedThingIDs(ctx context.Context, userID, permission string, thingIDs []string) ([]string, error) { var ids []string - tids, err := svc.policy.ListAllObjects(ctx, &magistrala.ListObjectsReq{ + tids, err := svc.policy.ListAllObjects(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Permission: permission, @@ -258,7 +258,7 @@ func (svc service) filterAllowedThingIDs(ctx context.Context, userID, permission return nil, errors.Wrap(svcerr.ErrNotFound, err) } for _, thingID := range thingIDs { - for _, tid := range tids { + for _, tid := range tids.Policies { if thingID == tid { ids = append(ids, thingID) } @@ -386,9 +386,9 @@ func (svc service) Share(ctx context.Context, token, id, relation string, userid return errors.Wrap(svcerr.ErrAuthorization, err) } - policies := magistrala.AddPoliciesReq{} + policies := []policy.PolicyReq{} for _, userid := range userids { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policy.PolicyReq{ SubjectType: auth.UserType, Subject: auth.EncodeDomainUserID(user.GetDomainId(), userid), Relation: relation, @@ -396,13 +396,11 @@ func (svc service) Share(ctx context.Context, token, id, relation string, userid Object: id, }) } - added, err := svc.policy.AddPolicies(ctx, &policies) + err = svc.policy.AddPolicies(ctx, policies) if err != nil { return errors.Wrap(svcerr.ErrUpdateEntity, err) } - if !added { - return errors.Wrap(svcerr.ErrUpdateEntity, err) - } + return nil } @@ -415,9 +413,9 @@ func (svc service) Unshare(ctx context.Context, token, id, relation string, user return errors.Wrap(svcerr.ErrAuthorization, err) } - policies := magistrala.DeletePoliciesReq{} + policies := []policy.PolicyReq{} for _, userid := range userids { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ SubjectType: auth.UserType, Subject: auth.EncodeDomainUserID(user.GetDomainId(), userid), Relation: relation, @@ -425,13 +423,11 @@ func (svc service) Unshare(ctx context.Context, token, id, relation string, user Object: id, }) } - deleted, err := svc.policy.DeletePolicies(ctx, &policies) + err = svc.policy.DeletePolicies(ctx, policies) if err != nil { return errors.Wrap(svcerr.ErrUpdateEntity, err) } - if !deleted { - return err - } + return nil } @@ -448,15 +444,13 @@ func (svc service) DeleteClient(ctx context.Context, token, id string) error { return errors.Wrap(svcerr.ErrRemoveEntity, err) } - deleted, err := svc.policy.DeleteEntityPolicies(ctx, &magistrala.DeleteEntityPoliciesReq{ - EntityType: auth.ThingType, - Id: id, - }) - if err != nil { - return errors.Wrap(svcerr.ErrRemoveEntity, err) + req := policy.PolicyReq{ + Object: id, + ObjectType: policy.ThingType, } - if !deleted { - return svcerr.ErrAuthorization + + if err := svc.policy.DeletePolicyFilter(ctx, req); err != nil { + return errors.Wrap(svcerr.ErrRemoveEntity, err) } if err := svc.clients.Delete(ctx, id); err != nil { @@ -497,7 +491,7 @@ func (svc service) ListClientsByGroup(ctx context.Context, token, groupID string return mgclients.MembersPage{}, err } - tids, err := svc.policy.ListAllObjects(ctx, &magistrala.ListObjectsReq{ + tids, err := svc.policy.ListAllObjects(ctx, policy.PolicyReq{ SubjectType: auth.GroupType, Subject: groupID, Permission: auth.GroupRelation, @@ -507,7 +501,7 @@ func (svc service) ListClientsByGroup(ctx context.Context, token, groupID string return mgclients.MembersPage{}, errors.Wrap(svcerr.ErrNotFound, err) } - pm.IDs = tids + pm.IDs = tids.Policies cp, err := svc.clients.RetrieveAllByIDs(ctx, pm) if err != nil { @@ -586,9 +580,9 @@ func (svc *service) authorize(ctx context.Context, domainID, subjType, subjKind, } func (svc service) addThingPolicies(ctx context.Context, userID, domainID string, things []mgclients.Client) error { - policies := magistrala.AddPoliciesReq{} + policies := []policy.PolicyReq{} for _, thing := range things { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: domainID, SubjectType: auth.UserType, Subject: userID, @@ -597,7 +591,7 @@ func (svc service) addThingPolicies(ctx context.Context, userID, domainID string ObjectType: auth.ThingType, Object: thing.ID, }) - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: domainID, SubjectType: auth.DomainType, Subject: domainID, @@ -606,8 +600,7 @@ func (svc service) addThingPolicies(ctx context.Context, userID, domainID string Object: thing.ID, }) } - - if _, err := svc.policy.AddPolicies(ctx, &policies); err != nil { + if err := svc.policy.AddPolicies(ctx, policies); err != nil { return errors.Wrap(svcerr.ErrCreateEntity, err) } @@ -615,9 +608,9 @@ func (svc service) addThingPolicies(ctx context.Context, userID, domainID string } func (svc service) addThingPoliciesRollback(ctx context.Context, userID, domainID string, things []mgclients.Client) error { - policies := magistrala.DeletePoliciesReq{} + policies := []policy.PolicyReq{} for _, thing := range things { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: domainID, SubjectType: auth.UserType, Subject: userID, @@ -626,7 +619,7 @@ func (svc service) addThingPoliciesRollback(ctx context.Context, userID, domainI ObjectType: auth.ThingType, Object: thing.ID, }) - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ Domain: domainID, SubjectType: auth.DomainType, Subject: domainID, @@ -635,8 +628,7 @@ func (svc service) addThingPoliciesRollback(ctx context.Context, userID, domainI Object: thing.ID, }) } - - if _, err := svc.policy.DeletePolicies(ctx, &policies); err != nil { + if err := svc.policy.DeletePolicies(ctx, policies); err != nil { return errors.Wrap(svcerr.ErrRemoveEntity, err) } diff --git a/things/service_test.go b/things/service_test.go index b4845e7261..45e81ebe36 100644 --- a/things/service_test.go +++ b/things/service_test.go @@ -9,7 +9,6 @@ import ( "testing" "github.com/absmach/magistrala" - authsvc "github.com/absmach/magistrala/auth" authmocks "github.com/absmach/magistrala/auth/mocks" "github.com/absmach/magistrala/internal/testsutil" mgclients "github.com/absmach/magistrala/pkg/clients" @@ -17,6 +16,7 @@ import ( repoerr "github.com/absmach/magistrala/pkg/errors/repository" svcerr "github.com/absmach/magistrala/pkg/errors/service" gmocks "github.com/absmach/magistrala/pkg/groups/mocks" + policysvc "github.com/absmach/magistrala/pkg/policy" policymocks "github.com/absmach/magistrala/pkg/policy/mocks" "github.com/absmach/magistrala/pkg/uuid" "github.com/absmach/magistrala/things" @@ -47,9 +47,9 @@ var ( errRemovePolicies = errors.New("failed to delete policies") ) -func newService() (things.Service, *mocks.Repository, *authmocks.AuthServiceClient, *policymocks.PolicyService, *mocks.Cache) { +func newService() (things.Service, *mocks.Repository, *authmocks.AuthServiceClient, *policymocks.PolicyClient, *mocks.Cache) { auth := new(authmocks.AuthServiceClient) - policyClient := new(policymocks.PolicyService) + policyClient := new(policymocks.PolicyClient) thingCache := new(mocks.Cache) idProvider := uuid.NewMock() cRepo := new(mocks.Repository) @@ -62,18 +62,16 @@ func TestCreateThings(t *testing.T) { svc, cRepo, auth, policy, _ := newService() cases := []struct { - desc string - thing mgclients.Client - token string - authResponse *magistrala.AuthorizeRes - addPolicyResponse bool - deletePolicyRes bool - authorizeErr error - identifyErr error - addPolicyErr error - deletePolicyErr error - saveErr error - err error + desc string + thing mgclients.Client + token string + authResponse *magistrala.AuthorizeRes + authorizeErr error + identifyErr error + addPolicyErr error + deletePolicyErr error + saveErr error + err error }{ { desc: "create a new thing successfully", @@ -99,10 +97,9 @@ func TestCreateThings(t *testing.T) { }, Status: mgclients.EnabledStatus, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - err: nil, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "create a new thing without identity", @@ -113,10 +110,9 @@ func TestCreateThings(t *testing.T) { }, Status: mgclients.EnabledStatus, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - err: nil, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "create a new enabled thing with name", @@ -128,10 +124,9 @@ func TestCreateThings(t *testing.T) { }, Status: mgclients.EnabledStatus, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - err: nil, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { @@ -143,10 +138,9 @@ func TestCreateThings(t *testing.T) { Secret: secret, }, }, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - token: validToken, - err: nil, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + token: validToken, + err: nil, }, { desc: "create a new enabled thing with tags", @@ -158,10 +152,9 @@ func TestCreateThings(t *testing.T) { }, Status: mgclients.EnabledStatus, }, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - token: validToken, - err: nil, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + token: validToken, + err: nil, }, { desc: "create a new disabled thing with tags", @@ -173,10 +166,9 @@ func TestCreateThings(t *testing.T) { }, Status: mgclients.DisabledStatus, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - err: nil, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "create a new enabled thing with metadata", @@ -188,10 +180,9 @@ func TestCreateThings(t *testing.T) { Metadata: validCMetadata, Status: mgclients.EnabledStatus, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - err: nil, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "create a new disabled thing with metadata", @@ -202,10 +193,9 @@ func TestCreateThings(t *testing.T) { }, Metadata: validCMetadata, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - err: nil, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "create a new disabled thing", @@ -215,10 +205,9 @@ func TestCreateThings(t *testing.T) { Secret: secret, }, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - err: nil, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "create a new thing with valid disabled status", @@ -229,10 +218,9 @@ func TestCreateThings(t *testing.T) { }, Status: mgclients.DisabledStatus, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - err: nil, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "create a new thing with all fields", @@ -248,10 +236,9 @@ func TestCreateThings(t *testing.T) { }, Status: mgclients.EnabledStatus, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - err: nil, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "create a new thing with invalid status", @@ -262,10 +249,9 @@ func TestCreateThings(t *testing.T) { }, Status: mgclients.AllStatus, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - err: svcerr.ErrInvalidStatus, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: svcerr.ErrInvalidStatus, }, { desc: "create a new thing with invalid token", @@ -303,11 +289,10 @@ func TestCreateThings(t *testing.T) { }, Status: mgclients.EnabledStatus, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: false, - addPolicyErr: svcerr.ErrInvalidPolicy, - err: svcerr.ErrInvalidPolicy, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + addPolicyErr: svcerr.ErrInvalidPolicy, + err: svcerr.ErrInvalidPolicy, }, { desc: "create a new thing with failed delete policy response", @@ -318,13 +303,11 @@ func TestCreateThings(t *testing.T) { }, Status: mgclients.EnabledStatus, }, - token: validToken, - authResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - saveErr: repoerr.ErrConflict, - deletePolicyRes: false, - deletePolicyErr: svcerr.ErrInvalidPolicy, - err: repoerr.ErrConflict, + token: validToken, + authResponse: &magistrala.AuthorizeRes{Authorized: true}, + saveErr: repoerr.ErrConflict, + deletePolicyErr: svcerr.ErrInvalidPolicy, + err: repoerr.ErrConflict, }, } @@ -332,8 +315,8 @@ func TestCreateThings(t *testing.T) { repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, tc.identifyErr) authcall := auth.On("Authorize", mock.Anything, mock.Anything).Return(tc.authResponse, tc.authorizeErr) repoCall1 := cRepo.On("Save", context.Background(), mock.Anything).Return([]mgclients.Client{tc.thing}, tc.saveErr) - authCall1 := policy.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.addPolicyResponse, tc.addPolicyErr) - authCall2 := policy.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePolicyRes, tc.deletePolicyErr) + authCall1 := policy.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.addPolicyErr) + authCall2 := policy.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePolicyErr) expected, err := svc.CreateThings(context.Background(), tc.token, tc.thing) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) if err == nil { @@ -431,10 +414,9 @@ func TestListClients(t *testing.T) { authorizeResponse *magistrala.AuthorizeRes authorizeResponse1 *magistrala.AuthorizeRes authorizeResponse2 *magistrala.AuthorizeRes - listObjectsResponse []string - listObjectsResponse1 []string + listObjectsResponse policysvc.PolicyPage retrieveAllResponse mgclients.ClientsPage - listPermissionsResponse []string + listPermissionsResponse policysvc.Permissions response mgclients.ClientsPage id string size uint64 @@ -460,7 +442,7 @@ func TestListClients(t *testing.T) { identifyResponse: &magistrala.IdentityRes{Id: nonAdminID, UserId: nonAdminID, DomainId: domainID}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, authorizeResponse2: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{Policies: []string{client.ID, client.ID}}, retrieveAllResponse: mgclients.ClientsPage{ Page: mgclients.Page{ Total: 2, @@ -564,7 +546,7 @@ func TestListClients(t *testing.T) { authorizeResponse: &magistrala.AuthorizeRes{Authorized: false}, authorizeResponse1: &magistrala.AuthorizeRes{Authorized: true}, response: mgclients.ClientsPage{}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, err: nil, }, { @@ -581,7 +563,7 @@ func TestListClients(t *testing.T) { authorizeResponse: &magistrala.AuthorizeRes{Authorized: false}, authorizeResponse1: &magistrala.AuthorizeRes{Authorized: false}, response: mgclients.ClientsPage{}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, err: svcerr.ErrAuthorization, }, { @@ -598,7 +580,7 @@ func TestListClients(t *testing.T) { authorizeResponse: &magistrala.AuthorizeRes{Authorized: false}, authorizeResponse1: &magistrala.AuthorizeRes{Authorized: true}, response: mgclients.ClientsPage{}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, listObjectsErr: svcerr.ErrNotFound, err: svcerr.ErrNotFound, }, @@ -607,16 +589,16 @@ func TestListClients(t *testing.T) { for _, tc := range cases { repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(tc.identifyResponse, tc.identifyErr) authorizeCall := auth.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, + SubjectType: policysvc.UserType, Subject: tc.identifyResponse.UserId, - Permission: authsvc.AdminPermission, - ObjectType: authsvc.PlatformType, - Object: authsvc.MagistralaObject, + Permission: policysvc.AdminPermission, + ObjectType: policysvc.PlatformType, + Object: policysvc.MagistralaObject, }).Return(tc.authorizeResponse, tc.authorizeErr) authorizeCall2 := auth.On("Authorize", context.Background(), &magistrala.AuthorizeReq{ Domain: "", - SubjectType: authsvc.UserType, - SubjectKind: authsvc.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: tc.identifyResponse.UserId, Permission: "membership", ObjectType: "domain", @@ -624,7 +606,7 @@ func TestListClients(t *testing.T) { }).Return(tc.authorizeResponse1, tc.authorizeErr1) listAllObjectsCall := policy.On("ListAllObjects", mock.Anything, mock.Anything).Return(tc.listObjectsResponse, tc.listObjectsErr) retrieveAllCall := cRepo.On("SearchClients", mock.Anything, mock.Anything).Return(tc.retrieveAllResponse, tc.retrieveAllErr) - listPermissionsCall := policy.On("ListPermissions", mock.Anything, mock.Anything).Return(tc.listPermissionsResponse, tc.listPermissionsErr) + listPermissionsCall := policy.On("ListPermissions", mock.Anything, mock.Anything, mock.Anything).Return(tc.listPermissionsResponse, tc.listPermissionsErr) page, err := svc.ListClients(context.Background(), tc.token, tc.id, tc.page) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) @@ -644,9 +626,9 @@ func TestListClients(t *testing.T) { page mgclients.Page identifyResponse *magistrala.IdentityRes authorizeResponse *magistrala.AuthorizeRes - listObjectsResponse []string + listObjectsResponse policysvc.PolicyPage retrieveAllResponse mgclients.ClientsPage - listPermissionsResponse []string + listPermissionsResponse policysvc.Permissions response mgclients.ClientsPage id string size uint64 @@ -670,7 +652,7 @@ func TestListClients(t *testing.T) { }, identifyResponse: &magistrala.IdentityRes{Id: nonAdminID, UserId: nonAdminID, DomainId: domainID}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{"test", "test"}, + listObjectsResponse: policysvc.PolicyPage{Policies: []string{client.ID, client.ID}}, retrieveAllResponse: mgclients.ClientsPage{ Page: mgclients.Page{ Total: 2, @@ -718,7 +700,7 @@ func TestListClients(t *testing.T) { }, identifyResponse: &magistrala.IdentityRes{Id: nonAdminID, UserId: nonAdminID, DomainId: domainID}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, retrieveAllResponse: mgclients.ClientsPage{}, retrieveAllErr: repoerr.ErrNotFound, err: svcerr.ErrNotFound, @@ -736,7 +718,7 @@ func TestListClients(t *testing.T) { }, identifyResponse: &magistrala.IdentityRes{Id: nonAdminID, UserId: nonAdminID, DomainId: domainID}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, retrieveAllResponse: mgclients.ClientsPage{ Page: mgclients.Page{ Total: 2, @@ -762,7 +744,7 @@ func TestListClients(t *testing.T) { }, identifyResponse: &magistrala.IdentityRes{Id: nonAdminID, UserId: nonAdminID, DomainId: domainID}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, listObjectsErr: svcerr.ErrNotFound, err: svcerr.ErrNotFound, }, @@ -779,7 +761,7 @@ func TestListClients(t *testing.T) { }, identifyResponse: &magistrala.IdentityRes{Id: nonAdminID, UserId: nonAdminID, DomainId: domainID}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, listObjectsErr: svcerr.ErrNotFound, err: svcerr.ErrNotFound, }, @@ -788,20 +770,20 @@ func TestListClients(t *testing.T) { for _, tc := range cases2 { repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(tc.identifyResponse, tc.identifyErr) authorizeCall := auth.On("Authorize", mock.Anything, mock.Anything).Return(tc.authorizeResponse, tc.authorizeErr) - listAllObjectsCall := policy.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{ - SubjectType: authsvc.UserType, + listAllObjectsCall := policy.On("ListAllObjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Subject: tc.identifyResponse.DomainId + "_" + adminID, Permission: "", - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, }).Return(tc.listObjectsResponse, tc.listObjectsErr) - listAllObjectsCall2 := policy.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{ - SubjectType: authsvc.UserType, + listAllObjectsCall2 := policy.On("ListAllObjects", context.Background(), policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Subject: tc.identifyResponse.Id, Permission: "", - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, }).Return(tc.listObjectsResponse, tc.listObjectsErr) retrieveAllCall := cRepo.On("SearchClients", mock.Anything, mock.Anything).Return(tc.retrieveAllResponse, tc.retrieveAllErr) - listPermissionsCall := policy.On("ListPermissions", mock.Anything, mock.Anything).Return(tc.listPermissionsResponse, tc.listPermissionsErr) + listPermissionsCall := policy.On("ListPermissions", mock.Anything, mock.Anything, mock.Anything).Return(tc.listPermissionsResponse, tc.listPermissionsErr) page, err := svc.ListClients(context.Background(), tc.token, tc.id, tc.page) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) @@ -1051,7 +1033,7 @@ func TestUpdateClientSecret(t *testing.T) { } func TestEnableClient(t *testing.T) { - svc, cRepo, auth, policy, _ := newService() + svc, cRepo, auth, _, _ := newService() enabledClient1 := mgclients.Client{ID: ID, Credentials: mgclients.Credentials{Identity: "client1@example.com", Secret: "password"}, Status: mgclients.EnabledStatus} disabledClient1 := mgclients.Client{ID: ID, Credentials: mgclients.Credentials{Identity: "client3@example.com", Secret: "password"}, Status: mgclients.DisabledStatus} @@ -1193,7 +1175,6 @@ func TestEnableClient(t *testing.T) { } repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil) repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil) - repoCall2 := policy.On("ListAllObjects", mock.Anything, mock.Anything).Return(&magistrala.ListObjectsRes{Policies: getIDs(tc.response.Clients)}, nil) repoCall3 := cRepo.On("SearchClients", context.Background(), mock.Anything).Return(tc.response, nil) page, err := svc.ListClients(context.Background(), validToken, "", pm) require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err)) @@ -1201,13 +1182,12 @@ func TestEnableClient(t *testing.T) { assert.Equal(t, tc.size, size, fmt.Sprintf("%s: expected size %d got %d\n", tc.desc, tc.size, size)) repoCall.Unset() repoCall1.Unset() - repoCall2.Unset() repoCall3.Unset() } } func TestDisableClient(t *testing.T) { - svc, cRepo, auth, policy, cache := newService() + svc, cRepo, auth, _, cache := newService() enabledClient1 := mgclients.Client{ID: ID, Credentials: mgclients.Credentials{Identity: "client1@example.com", Secret: "password"}, Status: mgclients.EnabledStatus} disabledClient1 := mgclients.Client{ID: ID, Credentials: mgclients.Credentials{Identity: "client3@example.com", Secret: "password"}, Status: mgclients.DisabledStatus} @@ -1363,7 +1343,6 @@ func TestDisableClient(t *testing.T) { } repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil) repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil) - repoCall2 := policy.On("ListAllObjects", mock.Anything, mock.Anything).Return(&magistrala.ListObjectsRes{Policies: getIDs(tc.response.Clients)}, nil) repoCall3 := cRepo.On("SearchClients", context.Background(), mock.Anything).Return(tc.response, nil) page, err := svc.ListClients(context.Background(), validToken, "", pm) require.Nil(t, err, fmt.Sprintf("unexpected error: %s", err)) @@ -1371,7 +1350,6 @@ func TestDisableClient(t *testing.T) { assert.Equal(t, tc.size, size, fmt.Sprintf("%s: expected size %d got %d\n", tc.desc, tc.size, size)) repoCall.Unset() repoCall1.Unset() - repoCall2.Unset() repoCall3.Unset() } } @@ -1406,8 +1384,8 @@ func TestListMembers(t *testing.T) { page mgclients.Page identifyResponse *magistrala.IdentityRes authorizeResponse *magistrala.AuthorizeRes - listObjectsResponse []string - listPermissionsResponse []string + listObjectsResponse policysvc.PolicyPage + listPermissionsResponse policysvc.Permissions retreiveAllByIDsResponse mgclients.ClientsPage response mgclients.MembersPage identifyErr error @@ -1423,7 +1401,7 @@ func TestListMembers(t *testing.T) { groupID: testsutil.GenerateUUID(t), identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, listPermissionsResponse: []string{}, retreiveAllByIDsResponse: mgclients.ClientsPage{ Page: mgclients.Page{ @@ -1454,7 +1432,7 @@ func TestListMembers(t *testing.T) { }, identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, listPermissionsResponse: []string{}, retreiveAllByIDsResponse: mgclients.ClientsPage{ Page: mgclients.Page{ @@ -1491,7 +1469,7 @@ func TestListMembers(t *testing.T) { groupID: wrongID, identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, listPermissionsResponse: []string{}, retreiveAllByIDsResponse: mgclients.ClientsPage{}, response: mgclients.MembersPage{ @@ -1513,7 +1491,7 @@ func TestListMembers(t *testing.T) { }, identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, listPermissionsResponse: []string{"admin"}, retreiveAllByIDsResponse: mgclients.ClientsPage{ Page: mgclients.Page{ @@ -1550,7 +1528,7 @@ func TestListMembers(t *testing.T) { }, identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, listObjectsErr: svcerr.ErrNotFound, err: svcerr.ErrNotFound, }, @@ -1570,7 +1548,7 @@ func TestListMembers(t *testing.T) { response: mgclients.MembersPage{}, identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listObjectsResponse: []string{}, + listObjectsResponse: policysvc.PolicyPage{}, listPermissionsResponse: []string{}, listPermissionsErr: svcerr.ErrNotFound, err: svcerr.ErrNotFound, @@ -1582,7 +1560,7 @@ func TestListMembers(t *testing.T) { repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(tc.authorizeResponse, tc.authorizeErr) repoCall2 := policy.On("ListAllObjects", mock.Anything, mock.Anything).Return(tc.listObjectsResponse, tc.listObjectsErr) repoCall3 := cRepo.On("RetrieveAllByIDs", context.Background(), mock.Anything).Return(tc.retreiveAllByIDsResponse, tc.retreiveAllByIDsErr) - repoCall4 := policy.On("ListPermissions", mock.Anything, mock.Anything).Return(tc.listPermissionsResponse, tc.listPermissionsErr) + repoCall4 := policy.On("ListPermissions", mock.Anything, mock.Anything, mock.Anything).Return(tc.listPermissionsResponse, tc.listPermissionsErr) page, err := svc.ListClientsByGroup(context.Background(), tc.token, tc.groupID, tc.page) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) assert.Equal(t, tc.response, page, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.response, page)) @@ -1602,27 +1580,25 @@ func TestDeleteClient(t *testing.T) { } cases := []struct { - desc string - token string - identifyResponse *magistrala.IdentityRes - authorizeResponse *magistrala.AuthorizeRes - deletePolicyResponse bool - clientID string - identifyErr error - authorizeErr error - removeErr error - deleteErr error - deletePolicyErr error - err error + desc string + token string + identifyResponse *magistrala.IdentityRes + authorizeResponse *magistrala.AuthorizeRes + clientID string + identifyErr error + authorizeErr error + removeErr error + deleteErr error + deletePolicyErr error + err error }{ { - desc: "Delete client with authorized token", - token: validToken, - clientID: client.ID, - identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - deletePolicyResponse: true, - err: nil, + desc: "Delete client with authorized token", + token: validToken, + clientID: client.ID, + identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, + authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "Delete client with unauthorized token", @@ -1642,14 +1618,13 @@ func TestDeleteClient(t *testing.T) { err: svcerr.ErrAuthorization, }, { - desc: "Delete client with repo error ", - token: validToken, - clientID: client.ID, - identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - deletePolicyResponse: true, - deleteErr: repoerr.ErrRemoveEntity, - err: repoerr.ErrRemoveEntity, + desc: "Delete client with repo error ", + token: validToken, + clientID: client.ID, + identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, + authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, + deleteErr: repoerr.ErrRemoveEntity, + err: repoerr.ErrRemoveEntity, }, { desc: "Delete client with cache error ", @@ -1661,14 +1636,13 @@ func TestDeleteClient(t *testing.T) { err: repoerr.ErrRemoveEntity, }, { - desc: "Delete client with failed to delete policy", - token: validToken, - clientID: client.ID, - identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - deletePolicyResponse: false, - deletePolicyErr: errRemovePolicies, - err: errRemovePolicies, + desc: "Delete client with failed to delete policy", + token: validToken, + clientID: client.ID, + identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, + authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, + deletePolicyErr: errRemovePolicies, + err: errRemovePolicies, }, } @@ -1676,10 +1650,7 @@ func TestDeleteClient(t *testing.T) { repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(tc.identifyResponse, tc.identifyErr) repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(tc.authorizeResponse, tc.authorizeErr) repoCall2 := cache.On("Remove", mock.Anything, tc.clientID).Return(tc.removeErr) - repoCall3 := policy.On("DeleteEntityPolicies", context.Background(), &magistrala.DeleteEntityPoliciesReq{ - EntityType: authsvc.ThingType, - Id: tc.clientID, - }).Return(tc.deletePolicyResponse, tc.deletePolicyErr) + repoCall3 := policy.On("DeletePolicyFilter", context.Background(), mock.Anything).Return(tc.deletePolicyErr) repoCall4 := cRepo.On("Delete", context.Background(), tc.clientID).Return(tc.deleteErr) err := svc.DeleteClient(context.Background(), tc.token, tc.clientID) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) @@ -1697,27 +1668,25 @@ func TestShare(t *testing.T) { clientID := "clientID" cases := []struct { - desc string - token string - clientID string - relation string - userID string - identifyResponse *magistrala.IdentityRes - authorizeResponse *magistrala.AuthorizeRes - addPoliciesResponse bool - identifyErr error - authorizeErr error - addPoliciesErr error - err error + desc string + token string + clientID string + relation string + userID string + identifyResponse *magistrala.IdentityRes + authorizeResponse *magistrala.AuthorizeRes + identifyErr error + authorizeErr error + addPoliciesErr error + err error }{ { - desc: "share thing successfully", - token: validToken, - clientID: clientID, - identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPoliciesResponse: true, - err: nil, + desc: "share thing successfully", + token: validToken, + clientID: clientID, + identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, + authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "share thing with invalid token", @@ -1737,30 +1706,20 @@ func TestShare(t *testing.T) { err: svcerr.ErrAuthorization, }, { - desc: "share thing with failed to add policies", - token: validToken, - clientID: clientID, - identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPoliciesResponse: false, - addPoliciesErr: svcerr.ErrInvalidPolicy, - err: svcerr.ErrInvalidPolicy, - }, - { - desc: "share thing with failed authorization from add policies", - token: validToken, - clientID: clientID, - identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPoliciesResponse: false, - err: svcerr.ErrUpdateEntity, + desc: "share thing with failed to add policies", + token: validToken, + clientID: clientID, + identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, + authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, + addPoliciesErr: svcerr.ErrInvalidPolicy, + err: svcerr.ErrInvalidPolicy, }, } for _, tc := range cases { repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(tc.identifyResponse, tc.identifyErr) repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(tc.authorizeResponse, tc.authorizeErr) - repoCall2 := policy.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.addPoliciesResponse, tc.addPoliciesErr) + repoCall2 := policy.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.addPoliciesErr) err := svc.Share(context.Background(), tc.token, tc.clientID, tc.relation, tc.userID) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) repoCall.Unset() @@ -1775,27 +1734,25 @@ func TestUnShare(t *testing.T) { clientID := "clientID" cases := []struct { - desc string - token string - clientID string - relation string - userID string - identifyResponse *magistrala.IdentityRes - authorizeResponse *magistrala.AuthorizeRes - deletePoliciesResponse bool - identifyErr error - authorizeErr error - deletePoliciesErr error - err error + desc string + token string + clientID string + relation string + userID string + identifyResponse *magistrala.IdentityRes + authorizeResponse *magistrala.AuthorizeRes + identifyErr error + authorizeErr error + deletePoliciesErr error + err error }{ { - desc: "unshare thing successfully", - token: validToken, - clientID: clientID, - identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - deletePoliciesResponse: true, - err: nil, + desc: "unshare thing successfully", + token: validToken, + clientID: clientID, + identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, + authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, + err: nil, }, { desc: "unshare thing with invalid token", @@ -1815,30 +1772,20 @@ func TestUnShare(t *testing.T) { err: svcerr.ErrAuthorization, }, { - desc: "share thing with failed to delete policies", - token: validToken, - clientID: clientID, - identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - deletePoliciesResponse: false, - deletePoliciesErr: svcerr.ErrInvalidPolicy, - err: svcerr.ErrInvalidPolicy, - }, - { - desc: "share thing with failed delete from delete policies", - token: validToken, - clientID: clientID, - identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - deletePoliciesResponse: false, - err: nil, + desc: "share thing with failed to delete policies", + token: validToken, + clientID: clientID, + identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, + authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, + deletePoliciesErr: svcerr.ErrInvalidPolicy, + err: svcerr.ErrInvalidPolicy, }, } for _, tc := range cases { repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(tc.identifyResponse, tc.identifyErr) repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(tc.authorizeResponse, tc.authorizeErr) - repoCall2 := policy.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePoliciesResponse, tc.deletePoliciesErr) + repoCall2 := policy.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePoliciesErr) err := svc.Unshare(context.Background(), tc.token, tc.clientID, tc.relation, tc.userID) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) repoCall.Unset() @@ -1858,7 +1805,7 @@ func TestViewClientPerms(t *testing.T) { thingID string identifyResponse *magistrala.IdentityRes authorizeResponse *magistrala.AuthorizeRes - listPermResponse []string + listPermResponse policysvc.Permissions identifyErr error authorizeErr error listPermErr error @@ -1870,7 +1817,7 @@ func TestViewClientPerms(t *testing.T) { thingID: validID, identifyResponse: &magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listPermResponse: []string{"admin"}, + listPermResponse: policysvc.Permissions{"admin"}, err: nil, }, { @@ -1904,11 +1851,11 @@ func TestViewClientPerms(t *testing.T) { for _, tc := range cases { repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: tc.token}).Return(tc.identifyResponse, tc.identifyErr) repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(tc.authorizeResponse, tc.authorizeErr) - repoCall2 := policy.On("ListPermissions", mock.Anything, mock.Anything).Return(tc.listPermResponse, tc.listPermErr) + repoCall2 := policy.On("ListPermissions", mock.Anything, mock.Anything, []string{}).Return(tc.listPermResponse, tc.listPermErr) res, err := svc.ViewClientPerms(context.Background(), tc.token, tc.thingID) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) if tc.err == nil { - assert.Equal(t, tc.listPermResponse, res, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.listPermResponse, res)) + assert.ElementsMatch(t, tc.listPermResponse, res, fmt.Sprintf("%s: expected %v got %v\n", tc.desc, tc.listPermResponse, res)) } repoCall.Unset() repoCall1.Unset() @@ -2073,11 +2020,3 @@ func TestAuthorize(t *testing.T) { authCall.Unset() } } - -func getIDs(clients []mgclients.Client) []string { - ids := []string{} - for _, client := range clients { - ids = append(ids, client.ID) - } - return ids -} diff --git a/things/standalone/standalone.go b/things/standalone/standalone.go index b64f70ac0e..479749be1a 100644 --- a/things/standalone/standalone.go +++ b/things/standalone/standalone.go @@ -9,12 +9,13 @@ import ( "github.com/absmach/magistrala" grpcclient "github.com/absmach/magistrala/auth/api/grpc" svcerr "github.com/absmach/magistrala/pkg/errors/service" + "github.com/absmach/magistrala/pkg/policy" "google.golang.org/grpc" ) var ( - _ grpcclient.AuthServiceClient = (*singleUserAuth)(nil) - _ magistrala.PolicyServiceClient = (*singleUserPolicyClient)(nil) + _ grpcclient.AuthServiceClient = (*singleUserAuth)(nil) + _ policy.PolicyClient = (*singleUserPolicyClient)(nil) ) type singleUserAuth struct { @@ -22,8 +23,8 @@ type singleUserAuth struct { token string } -// NewAuthService creates single user repository for constrained environments. -func NewAuthService(id, token string) grpcclient.AuthServiceClient { +// NewAuthClient creates single user auth client for constrained environments. +func NewAuthClient(id, token string) grpcclient.AuthServiceClient { return singleUserAuth{ id: id, token: token, @@ -63,58 +64,58 @@ type singleUserPolicyClient struct { token string } -// NewPolicyService creates single user policy service for constrained environments. -func NewPolicyService(id, token string) magistrala.PolicyServiceClient { +// NewPolicyClient creates single user policy client for constrained environments. +func NewPolicyClient(id, token string) policy.PolicyClient { return singleUserPolicyClient{ id: id, token: token, } } -func (repo singleUserPolicyClient) AddPolicy(ctx context.Context, in *magistrala.AddPolicyReq, opts ...grpc.CallOption) (*magistrala.AddPolicyRes, error) { - return nil, nil +func (repo singleUserPolicyClient) AddPolicy(ctx context.Context, pr policy.PolicyReq) error { + return nil } -func (repo singleUserPolicyClient) AddPolicies(ctx context.Context, in *magistrala.AddPoliciesReq, opts ...grpc.CallOption) (*magistrala.AddPoliciesRes, error) { - return nil, nil +func (repo singleUserPolicyClient) AddPolicies(ctx context.Context, prs []policy.PolicyReq) error { + return nil } -func (repo singleUserPolicyClient) DeletePolicyFilter(ctx context.Context, in *magistrala.DeletePolicyFilterReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { - return nil, nil +func (repo singleUserPolicyClient) DeletePolicyFilter(ctx context.Context, pr policy.PolicyReq) error { + return nil } -func (repo singleUserPolicyClient) DeletePolicies(ctx context.Context, in *magistrala.DeletePoliciesReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { - return nil, nil +func (repo singleUserPolicyClient) DeletePolicies(ctx context.Context, prs []policy.PolicyReq) error { + return nil } -func (repo singleUserPolicyClient) ListObjects(ctx context.Context, in *magistrala.ListObjectsReq, opts ...grpc.CallOption) (*magistrala.ListObjectsRes, error) { - return nil, nil +func (repo singleUserPolicyClient) ListObjects(ctx context.Context, pr policy.PolicyReq, nextPageToken string, limit uint64) (policy.PolicyPage, error) { + return policy.PolicyPage{}, nil } -func (repo singleUserPolicyClient) ListAllObjects(ctx context.Context, in *magistrala.ListObjectsReq, opts ...grpc.CallOption) (*magistrala.ListObjectsRes, error) { - return nil, nil +func (repo singleUserPolicyClient) ListAllObjects(ctx context.Context, pr policy.PolicyReq) (policy.PolicyPage, error) { + return policy.PolicyPage{}, nil } -func (repo singleUserPolicyClient) CountObjects(ctx context.Context, in *magistrala.CountObjectsReq, opts ...grpc.CallOption) (*magistrala.CountObjectsRes, error) { - return nil, nil +func (repo singleUserPolicyClient) CountObjects(ctx context.Context, pr policy.PolicyReq) (uint64, error) { + return 0, nil } -func (repo singleUserPolicyClient) ListSubjects(ctx context.Context, in *magistrala.ListSubjectsReq, opts ...grpc.CallOption) (*magistrala.ListSubjectsRes, error) { - return nil, nil +func (repo singleUserPolicyClient) ListSubjects(ctx context.Context, pr policy.PolicyReq, nextPageToken string, limit uint64) (policy.PolicyPage, error) { + return policy.PolicyPage{}, nil } -func (repo singleUserPolicyClient) ListAllSubjects(ctx context.Context, in *magistrala.ListSubjectsReq, opts ...grpc.CallOption) (*magistrala.ListSubjectsRes, error) { - return nil, nil +func (repo singleUserPolicyClient) ListAllSubjects(ctx context.Context, pr policy.PolicyReq) (policy.PolicyPage, error) { + return policy.PolicyPage{}, nil } -func (repo singleUserPolicyClient) CountSubjects(ctx context.Context, in *magistrala.CountSubjectsReq, opts ...grpc.CallOption) (*magistrala.CountSubjectsRes, error) { - return nil, nil +func (repo singleUserPolicyClient) CountSubjects(ctx context.Context, pr policy.PolicyReq) (uint64, error) { + return 0, nil } -func (repo singleUserPolicyClient) ListPermissions(ctx context.Context, in *magistrala.ListPermissionsReq, opts ...grpc.CallOption) (*magistrala.ListPermissionsRes, error) { +func (repo singleUserPolicyClient) ListPermissions(ctx context.Context, pr policy.PolicyReq, permissionsFilter []string) (policy.Permissions, error) { return nil, nil } -func (repo singleUserPolicyClient) DeleteEntityPolicies(ctx context.Context, in *magistrala.DeleteEntityPoliciesReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) { - return nil, nil +func (repo singleUserPolicyClient) DeleteEntityPolicies(ctx context.Context, entityType, id string) error { + return nil } diff --git a/users/delete_handler.go b/users/delete_handler.go index c6b02fd895..a772a72b34 100644 --- a/users/delete_handler.go +++ b/users/delete_handler.go @@ -15,10 +15,8 @@ import ( "time" "github.com/absmach/magistrala" - "github.com/absmach/magistrala/auth" mgclients "github.com/absmach/magistrala/pkg/clients" svcerr "github.com/absmach/magistrala/pkg/errors/service" - "github.com/absmach/magistrala/pkg/policy" "github.com/absmach/magistrala/users/postgres" ) @@ -26,16 +24,16 @@ const defLimit = uint64(100) type handler struct { clients postgres.Repository - policy policy.PolicyService + policy magistrala.PolicyServiceClient checkInterval time.Duration deleteAfter time.Duration logger *slog.Logger } -func NewDeleteHandler(ctx context.Context, clients postgres.Repository, policyService policy.PolicyService, defCheckInterval, deleteAfter time.Duration, logger *slog.Logger) { +func NewDeleteHandler(ctx context.Context, clients postgres.Repository, policyClient magistrala.PolicyServiceClient, defCheckInterval, deleteAfter time.Duration, logger *slog.Logger) { handler := &handler{ clients: clients, - policy: policyService, + policy: policyClient, checkInterval: defCheckInterval, deleteAfter: deleteAfter, logger: logger, @@ -74,15 +72,14 @@ func (h *handler) handle(ctx context.Context) { continue } - deleted, err := h.policy.DeleteEntityPolicies(ctx, &magistrala.DeleteEntityPoliciesReq{ - Id: u.ID, - EntityType: auth.UserType, + deletedRes, err := h.policy.DeleteUserPolicies(ctx, &magistrala.DeleteUserPoliciesReq{ + Id: u.ID, }) if err != nil { h.logger.Error("failed to delete user policies", slog.Any("error", err)) continue } - if !deleted { + if !deletedRes.Deleted { h.logger.Error("failed to delete user policies", slog.Any("error", svcerr.ErrAuthorization)) continue } diff --git a/users/service.go b/users/service.go index 2068f93910..93155dbb69 100644 --- a/users/service.go +++ b/users/service.go @@ -30,18 +30,18 @@ type service struct { clients postgres.Repository idProvider magistrala.IDProvider auth grpcclient.AuthServiceClient - policy policy.PolicyService + policy policy.PolicyClient hasher Hasher email Emailer selfRegister bool } // NewService returns a new Users service implementation. -func NewService(crepo postgres.Repository, authClient grpcclient.AuthServiceClient, policyService policy.PolicyService, emailer Emailer, hasher Hasher, idp magistrala.IDProvider, selfRegister bool) Service { +func NewService(crepo postgres.Repository, authClient grpcclient.AuthServiceClient, policyClient policy.PolicyClient, emailer Emailer, hasher Hasher, idp magistrala.IDProvider, selfRegister bool) Service { return service{ clients: crepo, auth: authClient, - policy: policyService, + policy: policyClient, hasher: hasher, email: emailer, idProvider: idp, @@ -504,7 +504,7 @@ func (svc service) ListMembers(ctx context.Context, token, objectKind, objectID if _, err := svc.authorize(ctx, auth.UserType, auth.TokenKind, token, authzPerm, objectType, objectID); err != nil { return mgclients.MembersPage{}, errors.Wrap(svcerr.ErrAuthorization, err) } - duids, err := svc.policy.ListAllSubjects(ctx, &magistrala.ListSubjectsReq{ + duids, err := svc.policy.ListAllSubjects(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Permission: pm.Permission, Object: objectID, @@ -513,7 +513,7 @@ func (svc service) ListMembers(ctx context.Context, token, objectKind, objectID if err != nil { return mgclients.MembersPage{}, errors.Wrap(svcerr.ErrNotFound, err) } - if len(duids) == 0 { + if len(duids.Policies) == 0 { return mgclients.MembersPage{ Page: mgclients.Page{Total: 0, Offset: pm.Offset, Limit: pm.Limit}, }, nil @@ -521,7 +521,7 @@ func (svc service) ListMembers(ctx context.Context, token, objectKind, objectID var userIDs []string - for _, domainUserID := range duids { + for _, domainUserID := range duids.Policies { _, userID := auth.DecodeDomainUserID(domainUserID) userIDs = append(userIDs, userID) } @@ -575,12 +575,12 @@ func (svc service) retrieveObjectUsersPermissions(ctx context.Context, domainID, } func (svc service) listObjectUserPermission(ctx context.Context, userID, objectType, objectID string) ([]string, error) { - permissions, err := svc.policy.ListPermissions(ctx, &magistrala.ListPermissionsReq{ + permissions, err := svc.policy.ListPermissions(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Object: objectID, ObjectType: objectType, - }) + }, []string{}) if err != nil { return []string{}, errors.Wrap(errFailedPermissionsList, err) } @@ -663,9 +663,9 @@ func (svc service) Identify(ctx context.Context, token string) (string, error) { } func (svc service) addClientPolicy(ctx context.Context, userID string, role mgclients.Role) error { - var policies magistrala.AddPoliciesReq + policies := []policy.PolicyReq{} - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Relation: auth.MemberRelation, @@ -674,7 +674,7 @@ func (svc service) addClientPolicy(ctx context.Context, userID string, role mgcl }) if role == mgclients.AdminRole { - policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{ + policies = append(policies, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Relation: auth.AdministratorRelation, @@ -682,20 +682,18 @@ func (svc service) addClientPolicy(ctx context.Context, userID string, role mgcl Object: auth.MagistralaObject, }) } - added, err := svc.policy.AddPolicies(ctx, &policies) + err := svc.policy.AddPolicies(ctx, policies) if err != nil { return errors.Wrap(svcerr.ErrAddPolicies, err) } - if !added { - return svcerr.ErrAuthorization - } + return nil } func (svc service) addClientPolicyRollback(ctx context.Context, userID string, role mgclients.Role) error { - var policies magistrala.DeletePoliciesReq + policies := []policy.PolicyReq{} - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Relation: auth.MemberRelation, @@ -704,7 +702,7 @@ func (svc service) addClientPolicyRollback(ctx context.Context, userID string, r }) if role == mgclients.AdminRole { - policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{ + policies = append(policies, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Relation: auth.AdministratorRelation, @@ -712,20 +710,18 @@ func (svc service) addClientPolicyRollback(ctx context.Context, userID string, r Object: auth.MagistralaObject, }) } - deleted, err := svc.policy.DeletePolicies(ctx, &policies) + err := svc.policy.DeletePolicies(ctx, policies) if err != nil { return errors.Wrap(svcerr.ErrDeletePolicies, err) } - if !deleted { - return svcerr.ErrAuthorization - } + return nil } func (svc service) updateClientPolicy(ctx context.Context, userID string, role mgclients.Role) error { switch role { case mgclients.AdminRole: - added, err := svc.policy.AddPolicy(ctx, &magistrala.AddPolicyReq{ + err := svc.policy.AddPolicy(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Relation: auth.AdministratorRelation, @@ -735,14 +731,12 @@ func (svc service) updateClientPolicy(ctx context.Context, userID string, role m if err != nil { return errors.Wrap(svcerr.ErrAddPolicies, err) } - if !added { - return svcerr.ErrAuthorization - } + return nil case mgclients.UserRole: fallthrough default: - deleted, err := svc.policy.DeletePolicyFilter(ctx, &magistrala.DeletePolicyFilterReq{ + err := svc.policy.DeletePolicyFilter(ctx, policy.PolicyReq{ SubjectType: auth.UserType, Subject: userID, Relation: auth.AdministratorRelation, @@ -752,9 +746,7 @@ func (svc service) updateClientPolicy(ctx context.Context, userID string, role m if err != nil { return errors.Wrap(svcerr.ErrDeletePolicies, err) } - if !deleted { - return svcerr.ErrAuthorization - } + return nil } } diff --git a/users/service_test.go b/users/service_test.go index 40b79a80db..f480f4230e 100644 --- a/users/service_test.go +++ b/users/service_test.go @@ -17,6 +17,7 @@ import ( "github.com/absmach/magistrala/pkg/errors" repoerr "github.com/absmach/magistrala/pkg/errors/repository" svcerr "github.com/absmach/magistrala/pkg/errors/service" + policysvc "github.com/absmach/magistrala/pkg/policy" policymocks "github.com/absmach/magistrala/pkg/policy/mocks" "github.com/absmach/magistrala/pkg/uuid" "github.com/absmach/magistrala/users" @@ -51,10 +52,10 @@ var ( errHashPassword = errors.New("generate hash from password failed") ) -func newService(selfRegister bool) (users.Service, *mocks.Repository, *authmocks.AuthServiceClient, *policymocks.PolicyService, *mocks.Emailer) { +func newService(selfRegister bool) (users.Service, *mocks.Repository, *authmocks.AuthServiceClient, *policymocks.PolicyClient, *mocks.Emailer) { cRepo := new(mocks.Repository) auth := new(authmocks.AuthServiceClient) - policy := new(policymocks.PolicyService) + policy := new(policymocks.PolicyClient) e := new(mocks.Emailer) return users.NewService(cRepo, auth, policy, e, phasher, idProvider, selfRegister), cRepo, auth, policy, e } @@ -66,8 +67,6 @@ func TestRegisterClient(t *testing.T) { desc string client mgclients.Client identifyResponse *magistrala.IdentityRes - addPoliciesResponse bool - deletePoliciesResponse bool token string identifyErr error addPoliciesResponseErr error @@ -76,20 +75,17 @@ func TestRegisterClient(t *testing.T) { err error }{ { - desc: "register new client successfully", - client: client, - addPoliciesResponse: true, - token: validToken, - err: nil, + desc: "register new client successfully", + client: client, + token: validToken, + err: nil, }, { - desc: "register existing client", - client: client, - addPoliciesResponse: true, - deletePoliciesResponse: true, - token: validToken, - saveErr: repoerr.ErrConflict, - err: repoerr.ErrConflict, + desc: "register existing client", + client: client, + token: validToken, + saveErr: repoerr.ErrConflict, + err: repoerr.ErrConflict, }, { desc: "register a new enabled client with name", @@ -101,9 +97,8 @@ func TestRegisterClient(t *testing.T) { }, Status: mgclients.EnabledStatus, }, - addPoliciesResponse: true, - err: nil, - token: validToken, + err: nil, + token: validToken, }, { desc: "register a new disabled client with name", @@ -114,9 +109,8 @@ func TestRegisterClient(t *testing.T) { Secret: secret, }, }, - addPoliciesResponse: true, - err: nil, - token: validToken, + err: nil, + token: validToken, }, { desc: "register a new client with all fields", @@ -132,9 +126,8 @@ func TestRegisterClient(t *testing.T) { }, Status: mgclients.EnabledStatus, }, - addPoliciesResponse: true, - err: nil, - token: validToken, + err: nil, + token: validToken, }, { desc: "register a new client with missing identity", @@ -144,11 +137,9 @@ func TestRegisterClient(t *testing.T) { Secret: secret, }, }, - addPoliciesResponse: true, - deletePoliciesResponse: true, - saveErr: errors.ErrMalformedEntity, - err: errors.ErrMalformedEntity, - token: validToken, + saveErr: errors.ErrMalformedEntity, + err: errors.ErrMalformedEntity, + token: validToken, }, { desc: "register a new client with missing secret", @@ -159,9 +150,7 @@ func TestRegisterClient(t *testing.T) { Secret: "", }, }, - addPoliciesResponse: true, - deletePoliciesResponse: true, - err: nil, + err: nil, }, { desc: " register a client with a secret that is too long", @@ -172,9 +161,7 @@ func TestRegisterClient(t *testing.T) { Secret: strings.Repeat("a", 73), }, }, - addPoliciesResponse: true, - deletePoliciesResponse: true, - err: repoerr.ErrMalformedEntity, + err: repoerr.ErrMalformedEntity, }, { desc: "register a new client with invalid status", @@ -186,9 +173,7 @@ func TestRegisterClient(t *testing.T) { }, Status: mgclients.AllStatus, }, - addPoliciesResponse: true, - deletePoliciesResponse: true, - err: svcerr.ErrInvalidStatus, + err: svcerr.ErrInvalidStatus, }, { desc: "register a new client with invalid role", @@ -200,22 +185,7 @@ func TestRegisterClient(t *testing.T) { }, Role: 2, }, - addPoliciesResponse: true, - deletePoliciesResponse: true, - err: svcerr.ErrInvalidRole, - }, - { - desc: "register a new client with failed to authorize add policies", - client: mgclients.Client{ - Name: "clientWithFailedToAddPolicies", - Credentials: mgclients.Credentials{ - Identity: "clientwithfailedpolicies@example.com", - Secret: secret, - }, - Role: mgclients.AdminRole, - }, - addPoliciesResponse: false, - err: svcerr.ErrAuthorization, + err: svcerr.ErrInvalidRole, }, { desc: "register a new client with failed to add policies with err", @@ -227,7 +197,6 @@ func TestRegisterClient(t *testing.T) { }, Role: mgclients.AdminRole, }, - addPoliciesResponse: true, addPoliciesResponseErr: svcerr.ErrAddPolicies, err: svcerr.ErrAddPolicies, }, @@ -241,32 +210,15 @@ func TestRegisterClient(t *testing.T) { }, Role: mgclients.AdminRole, }, - addPoliciesResponse: true, - deletePoliciesResponse: false, deletePoliciesResponseErr: svcerr.ErrConflict, saveErr: repoerr.ErrConflict, err: svcerr.ErrConflict, }, - { - desc: "register a new client with failed to delete policies with failed to delete", - client: mgclients.Client{ - Name: "clientWithFailedToDeletePolicies", - Credentials: mgclients.Credentials{ - Identity: "clientwithfailedtodelete@example.com", - Secret: secret, - }, - Role: mgclients.AdminRole, - }, - addPoliciesResponse: true, - deletePoliciesResponse: false, - saveErr: repoerr.ErrConflict, - err: svcerr.ErrConflict, - }, } for _, tc := range cases { - authCall := policy.On("AddPolicies", context.Background(), mock.Anything).Return(tc.addPoliciesResponse, tc.addPoliciesResponseErr) - authCall1 := policy.On("DeletePolicies", context.Background(), mock.Anything).Return(tc.deletePoliciesResponse, tc.deletePoliciesResponseErr) + authCall := policy.On("AddPolicies", context.Background(), mock.Anything).Return(tc.addPoliciesResponseErr) + authCall1 := policy.On("DeletePolicies", context.Background(), mock.Anything).Return(tc.deletePoliciesResponseErr) repoCall := cRepo.On("Save", context.Background(), mock.Anything).Return(tc.client, tc.saveErr) expected, err := svc.RegisterClient(context.Background(), tc.token, tc.client) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) @@ -292,8 +244,6 @@ func TestRegisterClient(t *testing.T) { client mgclients.Client identifyResponse *magistrala.IdentityRes authorizeResponse *magistrala.AuthorizeRes - addPoliciesResponse bool - deletePoliciesResponse bool token string identifyErr error authorizeErr error @@ -304,13 +254,12 @@ func TestRegisterClient(t *testing.T) { err error }{ { - desc: "register new client successfully as admin", - client: client, - identifyResponse: &magistrala.IdentityRes{UserId: validID}, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - addPoliciesResponse: true, - token: validToken, - err: nil, + desc: "register new client successfully as admin", + client: client, + identifyResponse: &magistrala.IdentityRes{UserId: validID}, + authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, + token: validToken, + err: nil, }, { desc: "register a new clinet as admin with invalid token", @@ -342,8 +291,8 @@ func TestRegisterClient(t *testing.T) { authCall := auth.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.identifyResponse, tc.identifyErr) authCall1 := auth.On("Authorize", context.Background(), mock.Anything).Return(tc.authorizeResponse, tc.authorizeErr) repoCall := cRepo.On("CheckSuperAdmin", context.Background(), mock.Anything).Return(tc.checkSuperAdminErr) - authCall2 := policy.On("AddPolicies", context.Background(), mock.Anything).Return(tc.addPoliciesResponse, tc.addPoliciesResponseErr) - authCall3 := policy.On("DeletePolicies", context.Background(), mock.Anything).Return(tc.deletePoliciesResponse, tc.deletePoliciesResponseErr) + authCall2 := policy.On("AddPolicies", context.Background(), mock.Anything).Return(tc.addPoliciesResponseErr) + authCall3 := policy.On("DeletePolicies", context.Background(), mock.Anything).Return(tc.deletePoliciesResponseErr) repoCall1 := cRepo.On("Save", context.Background(), mock.Anything).Return(tc.client, tc.saveErr) expected, err := svc.RegisterClient(context.Background(), tc.token, tc.client) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) @@ -1044,43 +993,41 @@ func TestUpdateClientRole(t *testing.T) { client2.Role = mgclients.UserRole superAdminAuthReq := &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: client.ID, - Permission: authsvc.AdminPermission, - ObjectType: authsvc.PlatformType, - Object: authsvc.MagistralaObject, + Permission: policysvc.AdminPermission, + ObjectType: policysvc.PlatformType, + Object: policysvc.MagistralaObject, } membershipAuthReq := &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: client.ID, - Permission: authsvc.MembershipPermission, - ObjectType: authsvc.PlatformType, - Object: authsvc.MagistralaObject, + Permission: policysvc.MembershipPermission, + ObjectType: policysvc.PlatformType, + Object: policysvc.MagistralaObject, } cases := []struct { - desc string - client mgclients.Client - identifyResponse *magistrala.IdentityRes - superAdminAuthReq *magistrala.AuthorizeReq - membershipAuthReq *magistrala.AuthorizeReq - superAdminAuthRes *magistrala.AuthorizeRes - membershipAuthRes *magistrala.AuthorizeRes - deletePolicyFilterResponse bool - addPolicyResponse bool - updateRoleResponse mgclients.Client - token string - identifyErr error - authorizeErr error - membershipAuthErr error - deletePolicyErr error - addPolicyErr error - updateRoleErr error - checkSuperAdminErr error - err error + desc string + client mgclients.Client + identifyResponse *magistrala.IdentityRes + superAdminAuthReq *magistrala.AuthorizeReq + membershipAuthReq *magistrala.AuthorizeReq + superAdminAuthRes *magistrala.AuthorizeRes + membershipAuthRes *magistrala.AuthorizeRes + updateRoleResponse mgclients.Client + token string + identifyErr error + authorizeErr error + membershipAuthErr error + deletePolicyErr error + addPolicyErr error + updateRoleErr error + checkSuperAdminErr error + err error }{ { desc: "update client role successfully", @@ -1090,7 +1037,6 @@ func TestUpdateClientRole(t *testing.T) { membershipAuthReq: membershipAuthReq, membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, updateRoleResponse: client, token: validToken, err: nil, @@ -1125,19 +1071,6 @@ func TestUpdateClientRole(t *testing.T) { checkSuperAdminErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, - { - desc: "update client role with failed authorization on add policy", - client: client, - identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, - superAdminAuthReq: superAdminAuthReq, - superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - membershipAuthReq: membershipAuthReq, - membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: false, - token: validToken, - authorizeErr: svcerr.ErrAuthorization, - err: svcerr.ErrAuthorization, - }, { desc: "update client role with failed to add policy", client: client, @@ -1146,81 +1079,74 @@ func TestUpdateClientRole(t *testing.T) { superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, membershipAuthReq: membershipAuthReq, membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: false, token: validToken, addPolicyErr: errors.ErrMalformedEntity, err: svcerr.ErrAddPolicies, }, { - desc: "update client role to user role successfully ", - client: client2, - identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, - superAdminAuthReq: superAdminAuthReq, - superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - membershipAuthReq: membershipAuthReq, - membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - deletePolicyFilterResponse: true, - updateRoleResponse: client2, - token: validToken, - err: nil, + desc: "update client role to user role successfully ", + client: client2, + identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, + superAdminAuthReq: superAdminAuthReq, + superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, + membershipAuthReq: membershipAuthReq, + membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, + updateRoleResponse: client2, + token: validToken, + err: nil, }, { - desc: "update client role to user role with failed to delete policy", - client: client2, - superAdminAuthReq: superAdminAuthReq, - identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, - superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - membershipAuthReq: membershipAuthReq, - membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - deletePolicyFilterResponse: false, - updateRoleResponse: mgclients.Client{}, - token: validToken, - deletePolicyErr: svcerr.ErrAuthorization, - err: svcerr.ErrAuthorization, + desc: "update client role to user role with failed to delete policy", + client: client2, + superAdminAuthReq: superAdminAuthReq, + identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, + superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, + membershipAuthReq: membershipAuthReq, + membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, + updateRoleResponse: mgclients.Client{}, + token: validToken, + deletePolicyErr: svcerr.ErrAuthorization, + err: svcerr.ErrAuthorization, }, { - desc: "update client role to user role with failed to delete policy with error", - client: client2, - identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, - superAdminAuthReq: superAdminAuthReq, - superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - membershipAuthReq: membershipAuthReq, - membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - deletePolicyFilterResponse: false, - updateRoleResponse: mgclients.Client{}, - token: validToken, - deletePolicyErr: svcerr.ErrMalformedEntity, - err: svcerr.ErrDeletePolicies, + desc: "update client role to user role with failed to delete policy with error", + client: client2, + identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, + superAdminAuthReq: superAdminAuthReq, + superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, + membershipAuthReq: membershipAuthReq, + membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, + updateRoleResponse: mgclients.Client{}, + token: validToken, + deletePolicyErr: svcerr.ErrMalformedEntity, + err: svcerr.ErrDeletePolicies, }, { - desc: "Update client with failed repo update and roll back", - client: client, - superAdminAuthReq: superAdminAuthReq, - identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, - superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - membershipAuthReq: membershipAuthReq, - membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - deletePolicyFilterResponse: true, - updateRoleResponse: mgclients.Client{}, - token: validToken, - updateRoleErr: svcerr.ErrAuthentication, - err: svcerr.ErrAuthentication, + desc: "Update client with failed repo update and roll back", + client: client, + superAdminAuthReq: superAdminAuthReq, + identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, + superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, + membershipAuthReq: membershipAuthReq, + membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, + updateRoleResponse: mgclients.Client{}, + token: validToken, + updateRoleErr: svcerr.ErrAuthentication, + err: svcerr.ErrAuthentication, }, { - desc: "Update client with failed repo update and failedroll back", - client: client, - identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, - superAdminAuthReq: superAdminAuthReq, - superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - membershipAuthReq: membershipAuthReq, - membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, - addPolicyResponse: true, - deletePolicyFilterResponse: false, - updateRoleResponse: mgclients.Client{}, - token: validToken, - updateRoleErr: svcerr.ErrAuthentication, - err: svcerr.ErrAuthentication, + desc: "Update client with failed repo update and failedroll back", + client: client, + identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, + superAdminAuthReq: superAdminAuthReq, + superAdminAuthRes: &magistrala.AuthorizeRes{Authorized: true}, + membershipAuthReq: membershipAuthReq, + membershipAuthRes: &magistrala.AuthorizeRes{Authorized: true}, + updateRoleResponse: mgclients.Client{}, + token: validToken, + deletePolicyErr: svcerr.ErrAuthorization, + updateRoleErr: svcerr.ErrAuthentication, + err: svcerr.ErrAuthentication, }, { desc: "update client role with failed MembershipPermission authorization", @@ -1241,8 +1167,8 @@ func TestUpdateClientRole(t *testing.T) { authCall1 := auth.On("Authorize", context.Background(), tc.superAdminAuthReq).Return(tc.superAdminAuthRes, tc.authorizeErr) repoCall := cRepo.On("CheckSuperAdmin", context.Background(), mock.Anything).Return(tc.checkSuperAdminErr) authCall2 := auth.On("Authorize", context.Background(), tc.membershipAuthReq).Return(tc.membershipAuthRes, tc.membershipAuthErr) - authCall3 := policy.On("AddPolicy", context.Background(), mock.Anything).Return(tc.addPolicyResponse, tc.addPolicyErr) - authCall4 := policy.On("DeletePolicyFilter", context.Background(), mock.Anything).Return(tc.deletePolicyFilterResponse, tc.deletePolicyErr) + authCall3 := policy.On("AddPolicy", context.Background(), mock.Anything).Return(tc.addPolicyErr) + authCall4 := policy.On("DeletePolicyFilter", context.Background(), mock.Anything).Return(tc.deletePolicyErr) repoCall1 := cRepo.On("UpdateRole", context.Background(), mock.Anything).Return(tc.updateRoleResponse, tc.updateRoleErr) updatedClient, err := svc.UpdateClientRole(context.Background(), tc.token, tc.client) @@ -1779,11 +1705,11 @@ func TestListMembers(t *testing.T) { page mgclients.Page identifyResponse *magistrala.IdentityRes authorizeReq *magistrala.AuthorizeReq - listAllSubjectsReq *magistrala.ListSubjectsReq + listAllSubjectsReq policysvc.PolicyReq authorizeResponse *magistrala.AuthorizeRes - listAllSubjectsResponse []string + listAllSubjectsResponse policysvc.PolicyPage retrieveAllResponse mgclients.ClientsPage - listPermissionsResponse []string + listPermissionsResponse policysvc.Permissions response mgclients.MembersPage authorizeErr error listAllSubjectsErr error @@ -1796,24 +1722,24 @@ func TestListMembers(t *testing.T) { desc: "list members with no policies successfully of the things kind", token: validToken, groupID: validID, - objectKind: authsvc.ThingsKind, + objectKind: policysvc.ThingsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read"}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, - listAllSubjectsResponse: []string{}, + listAllSubjectsResponse: policysvc.PolicyPage{}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, Object: validID, }, - listAllSubjectsReq: &magistrala.ListSubjectsReq{ - SubjectType: authsvc.UserType, + listAllSubjectsReq: policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: "read", Object: validID, - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, response: mgclients.MembersPage{ @@ -1829,26 +1755,26 @@ func TestListMembers(t *testing.T) { desc: "list members with policies successsfully of the things kind", token: validToken, groupID: validID, - objectKind: authsvc.ThingsKind, + objectKind: policysvc.ThingsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read"}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, Object: validID, }, - listAllSubjectsReq: &magistrala.ListSubjectsReq{ - SubjectType: authsvc.UserType, + listAllSubjectsReq: policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: "read", Object: validID, - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listAllSubjectsResponse: []string{validPolicy}, + listAllSubjectsResponse: policysvc.PolicyPage{Policies: []string{validPolicy}}, retrieveAllResponse: mgclients.ClientsPage{ Page: mgclients.Page{ Total: 1, @@ -1871,26 +1797,26 @@ func TestListMembers(t *testing.T) { desc: "list members with policies successsfully of the things kind with permissions", token: validToken, groupID: validID, - objectKind: authsvc.ThingsKind, + objectKind: policysvc.ThingsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read", ListPerms: true}, identifyResponse: &magistrala.IdentityRes{UserId: basicClient.ID}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, Object: validID, }, - listAllSubjectsReq: &magistrala.ListSubjectsReq{ - SubjectType: authsvc.UserType, + listAllSubjectsReq: policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: "read", Object: validID, - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listAllSubjectsResponse: []string{validPolicy}, + listAllSubjectsResponse: policysvc.PolicyPage{Policies: []string{validPolicy}}, retrieveAllResponse: mgclients.ClientsPage{ Page: mgclients.Page{ Total: 1, @@ -1914,26 +1840,26 @@ func TestListMembers(t *testing.T) { desc: "list members with policies of the things kind with permissionswith failed list permissions", token: validToken, groupID: validID, - objectKind: authsvc.ThingsKind, + objectKind: policysvc.ThingsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read", ListPerms: true}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, Object: validID, }, - listAllSubjectsReq: &magistrala.ListSubjectsReq{ - SubjectType: authsvc.UserType, + listAllSubjectsReq: policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: "read", Object: validID, - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listAllSubjectsResponse: []string{validPolicy}, + listAllSubjectsResponse: policysvc.PolicyPage{Policies: []string{validPolicy}}, retrieveAllResponse: mgclients.ClientsPage{ Page: mgclients.Page{ Total: 1, @@ -1951,16 +1877,16 @@ func TestListMembers(t *testing.T) { desc: "list members with of the things kind with failed to authorize", token: validToken, groupID: validID, - objectKind: authsvc.ThingsKind, + objectKind: policysvc.ThingsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read"}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, Object: validID, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: false}, @@ -1970,53 +1896,53 @@ func TestListMembers(t *testing.T) { desc: "list members with of the things kind with failed to list all subjects", token: validToken, groupID: validID, - objectKind: authsvc.ThingsKind, + objectKind: policysvc.ThingsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read"}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, Object: validID, }, - listAllSubjectsReq: &magistrala.ListSubjectsReq{ - SubjectType: authsvc.UserType, + listAllSubjectsReq: policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: "read", Object: validID, - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, listAllSubjectsErr: repoerr.ErrNotFound, - listAllSubjectsResponse: []string{}, + listAllSubjectsResponse: policysvc.PolicyPage{}, err: repoerr.ErrNotFound, }, { desc: "list members with of the things kind with failed to retrieve all", token: validToken, groupID: validID, - objectKind: authsvc.ThingsKind, + objectKind: policysvc.ThingsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read"}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, Object: validID, }, - listAllSubjectsReq: &magistrala.ListSubjectsReq{ - SubjectType: authsvc.UserType, + listAllSubjectsReq: policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: "read", Object: validID, - ObjectType: authsvc.ThingType, + ObjectType: policysvc.ThingType, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listAllSubjectsResponse: []string{validPolicy}, + listAllSubjectsResponse: policysvc.PolicyPage{Policies: []string{validPolicy}}, retrieveAllResponse: mgclients.ClientsPage{}, response: mgclients.MembersPage{}, retrieveAllErr: repoerr.ErrNotFound, @@ -2026,24 +1952,24 @@ func TestListMembers(t *testing.T) { desc: "list members with no policies successfully of the domain kind", token: validToken, groupID: validID, - objectKind: authsvc.DomainsKind, + objectKind: policysvc.DomainsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read"}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, - listAllSubjectsResponse: []string{}, + listAllSubjectsResponse: policysvc.PolicyPage{}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.DomainType, + ObjectType: policysvc.DomainType, Object: validID, }, - listAllSubjectsReq: &magistrala.ListSubjectsReq{ - SubjectType: authsvc.UserType, + listAllSubjectsReq: policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: "read", Object: validID, - ObjectType: authsvc.DomainType, + ObjectType: policysvc.DomainType, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, response: mgclients.MembersPage{ @@ -2059,26 +1985,26 @@ func TestListMembers(t *testing.T) { desc: "list members with policies successsfully of the domains kind", token: validToken, groupID: validID, - objectKind: authsvc.DomainsKind, + objectKind: policysvc.DomainsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read"}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.DomainType, + ObjectType: policysvc.DomainType, Object: validID, }, - listAllSubjectsReq: &magistrala.ListSubjectsReq{ - SubjectType: authsvc.UserType, + listAllSubjectsReq: policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: "read", Object: validID, - ObjectType: authsvc.DomainType, + ObjectType: policysvc.DomainType, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listAllSubjectsResponse: []string{validPolicy}, + listAllSubjectsResponse: policysvc.PolicyPage{Policies: []string{validPolicy}}, retrieveAllResponse: mgclients.ClientsPage{ Page: mgclients.Page{ Total: 1, @@ -2101,16 +2027,16 @@ func TestListMembers(t *testing.T) { desc: "list members with of the domains kind with failed to authorize", token: validToken, groupID: validID, - objectKind: authsvc.DomainsKind, + objectKind: policysvc.DomainsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read"}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.DomainType, + ObjectType: policysvc.DomainType, Object: validID, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: false}, @@ -2120,24 +2046,24 @@ func TestListMembers(t *testing.T) { desc: "list members with no policies successfully of the groups kind", token: validToken, groupID: validID, - objectKind: authsvc.GroupsKind, + objectKind: policysvc.GroupsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read"}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, - listAllSubjectsResponse: []string{}, + listAllSubjectsResponse: policysvc.PolicyPage{}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.GroupType, + ObjectType: policysvc.GroupType, Object: validID, }, - listAllSubjectsReq: &magistrala.ListSubjectsReq{ - SubjectType: authsvc.UserType, + listAllSubjectsReq: policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: "read", Object: validID, - ObjectType: authsvc.GroupType, + ObjectType: policysvc.GroupType, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, response: mgclients.MembersPage{ @@ -2153,26 +2079,26 @@ func TestListMembers(t *testing.T) { desc: "list members with policies successsfully of the groups kind", token: validToken, groupID: validID, - objectKind: authsvc.GroupsKind, + objectKind: policysvc.GroupsKind, objectID: validID, page: mgclients.Page{Offset: 0, Limit: 100, Permission: "read"}, identifyResponse: &magistrala.IdentityRes{UserId: client.ID}, authorizeReq: &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.TokenKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.TokenKind, Subject: validToken, Permission: "read", - ObjectType: authsvc.GroupType, + ObjectType: policysvc.GroupType, Object: validID, }, - listAllSubjectsReq: &magistrala.ListSubjectsReq{ - SubjectType: authsvc.UserType, + listAllSubjectsReq: policysvc.PolicyReq{ + SubjectType: policysvc.UserType, Permission: "read", Object: validID, - ObjectType: authsvc.GroupType, + ObjectType: policysvc.GroupType, }, authorizeResponse: &magistrala.AuthorizeRes{Authorized: true}, - listAllSubjectsResponse: []string{validPolicy}, + listAllSubjectsResponse: policysvc.PolicyPage{Policies: []string{validPolicy}}, retrieveAllResponse: mgclients.ClientsPage{ Page: mgclients.Page{ Total: 1, @@ -2206,7 +2132,7 @@ func TestListMembers(t *testing.T) { authCall1 := auth.On("Authorize", context.Background(), tc.authorizeReq).Return(tc.authorizeResponse, tc.authorizeErr) authCall2 := policy.On("ListAllSubjects", context.Background(), tc.listAllSubjectsReq).Return(tc.listAllSubjectsResponse, tc.listAllSubjectsErr) repoCall := cRepo.On("RetrieveAll", context.Background(), mock.Anything).Return(tc.retrieveAllResponse, tc.retrieveAllErr) - authCall3 := policy.On("ListPermissions", mock.Anything, mock.Anything).Return(tc.listPermissionsResponse, tc.listPermissionErr) + authCall3 := policy.On("ListPermissions", mock.Anything, mock.Anything, mock.Anything).Return(tc.listPermissionsResponse, tc.listPermissionErr) page, err := svc.ListMembers(context.Background(), tc.token, tc.objectKind, tc.objectID, tc.page) assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err)) @@ -2639,11 +2565,9 @@ func TestOAuthCallback(t *testing.T) { client mgclients.Client retrieveByIdentityResponse mgclients.Client retrieveByIdentityErr error - addPoliciesResponse bool addPoliciesErr error saveResponse mgclients.Client saveErr error - deletePoliciesResponse bool deletePoliciesErr error authorizeResponse *magistrala.AuthorizeRes authorizeErr error @@ -2678,7 +2602,6 @@ func TestOAuthCallback(t *testing.T) { }, }, retrieveByIdentityErr: repoerr.ErrNotFound, - addPoliciesResponse: true, saveResponse: mgclients.Client{ ID: testsutil.GenerateUUID(t), Role: mgclients.UserRole, @@ -2708,7 +2631,6 @@ func TestOAuthCallback(t *testing.T) { }, }, retrieveByIdentityErr: repoerr.ErrNotFound, - addPoliciesResponse: false, addPoliciesErr: svcerr.ErrAuthorization, err: svcerr.ErrAuthorization, }, @@ -2723,9 +2645,8 @@ func TestOAuthCallback(t *testing.T) { ID: testsutil.GenerateUUID(t), Role: mgclients.UserRole, }, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: false}, - authorizeErr: svcerr.ErrAuthorization, - addPoliciesResponse: true, + authorizeResponse: &magistrala.AuthorizeRes{Authorized: false}, + authorizeErr: svcerr.ErrAuthorization, issueResponse: &magistrala.Token{ AccessToken: strings.Repeat("a", 10), RefreshToken: &validToken, @@ -2744,11 +2665,10 @@ func TestOAuthCallback(t *testing.T) { ID: testsutil.GenerateUUID(t), Role: mgclients.UserRole, }, - authorizeResponse: &magistrala.AuthorizeRes{Authorized: false}, - authorizeErr: svcerr.ErrAuthorization, - addPoliciesResponse: false, - addPoliciesErr: svcerr.ErrAuthorization, - err: svcerr.ErrAuthorization, + authorizeResponse: &magistrala.AuthorizeRes{Authorized: false}, + authorizeErr: svcerr.ErrAuthorization, + addPoliciesErr: svcerr.ErrAuthorization, + err: svcerr.ErrAuthorization, }, { desc: "oauth signin callback with failed to issue token", @@ -2772,17 +2692,17 @@ func TestOAuthCallback(t *testing.T) { id = tc.retrieveByIdentityResponse.ID } authReq := &magistrala.AuthorizeReq{ - SubjectType: authsvc.UserType, - SubjectKind: authsvc.UsersKind, + SubjectType: policysvc.UserType, + SubjectKind: policysvc.UsersKind, Subject: id, - Permission: authsvc.MembershipPermission, - ObjectType: authsvc.PlatformType, - Object: authsvc.MagistralaObject, + Permission: policysvc.MembershipPermission, + ObjectType: policysvc.PlatformType, + Object: policysvc.MagistralaObject, } repoCall := cRepo.On("RetrieveByIdentity", context.Background(), tc.client.Credentials.Identity).Return(tc.retrieveByIdentityResponse, tc.retrieveByIdentityErr) repoCall1 := cRepo.On("Save", context.Background(), mock.Anything).Return(tc.saveResponse, tc.saveErr) authCall := auth.On("Issue", mock.Anything, mock.Anything).Return(tc.issueResponse, tc.issueErr) - authCall1 := policy.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.addPoliciesResponse, tc.addPoliciesErr) + authCall1 := policy.On("AddPolicies", mock.Anything, mock.Anything).Return(tc.addPoliciesErr) authCall2 := auth.On("Authorize", mock.Anything, authReq).Return(tc.authorizeResponse, tc.authorizeErr) token, err := svc.OAuthCallback(context.Background(), tc.client) if err == nil {