forked from mlrun/mlrun
-
Notifications
You must be signed in to change notification settings - Fork 0
/
auth.py
130 lines (112 loc) · 5.13 KB
/
auth.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# Copyright 2018 Iguazio
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import typing
import pydantic
from nuclio.auth import AuthInfo as NuclioAuthInfo
from nuclio.auth import AuthKinds as NuclioAuthKinds
from mlrun.api.utils.helpers import StrEnum
class ProjectsRole(StrEnum):
iguazio = "iguazio"
mlrun = "mlrun"
nuclio = "nuclio"
nop = "nop"
class AuthorizationAction(StrEnum):
read = "read"
create = "create"
update = "update"
delete = "delete"
# note that in the OPA manifest only the above actions exist, store is "an MLRun verb" an we internally map it to 2
# query permissions requests - create and update
store = "store"
class AuthorizationResourceTypes(StrEnum):
project = "project"
log = "log"
runtime_resource = "runtime-resource"
function = "function"
artifact = "artifact"
feature_set = "feature-set"
feature_vector = "feature-vector"
feature = "feature"
entity = "entity"
project_background_task = "project-background-task"
background_task = "background-task"
schedule = "schedule"
secret = "secret"
run = "run"
model_endpoint = "model-endpoint"
pipeline = "pipeline"
marketplace_source = "marketplace-source"
def to_resource_string(
self,
project_name: str,
resource_name: str,
):
return {
# project is the resource itself, so no need for both resource_name and project_name
AuthorizationResourceTypes.project: "/projects/{project_name}",
AuthorizationResourceTypes.function: "/projects/{project_name}/functions/{resource_name}",
AuthorizationResourceTypes.artifact: "/projects/{project_name}/artifacts/{resource_name}",
# fmt: off
AuthorizationResourceTypes.project_background_task:
"/projects/{project_name}/background-tasks/{resource_name}",
# fmt: on
AuthorizationResourceTypes.background_task: "/background-tasks/{resource_name}",
AuthorizationResourceTypes.feature_set: "/projects/{project_name}/feature-sets/{resource_name}",
AuthorizationResourceTypes.feature_vector: "/projects/{project_name}/feature-vectors/{resource_name}",
AuthorizationResourceTypes.feature: "/projects/{project_name}/features/{resource_name}",
AuthorizationResourceTypes.entity: "/projects/{project_name}/entities/{resource_name}",
AuthorizationResourceTypes.log: "/projects/{project_name}/runs/{resource_name}/logs",
AuthorizationResourceTypes.schedule: "/projects/{project_name}/schedules/{resource_name}",
AuthorizationResourceTypes.secret: "/projects/{project_name}/secrets/{resource_name}",
AuthorizationResourceTypes.run: "/projects/{project_name}/runs/{resource_name}",
# runtime resource doesn't have an identifier, we don't need any auth granularity behind project level
AuthorizationResourceTypes.runtime_resource: "/projects/{project_name}/runtime-resources",
AuthorizationResourceTypes.model_endpoint: "/projects/{project_name}/model-endpoints/{resource_name}",
AuthorizationResourceTypes.pipeline: "/projects/{project_name}/pipelines/{resource_name}",
# Marketplace sources are not project-scoped, and auth is globally on the sources endpoint.
AuthorizationResourceTypes.marketplace_source: "/marketplace/sources",
}[self].format(project_name=project_name, resource_name=resource_name)
class AuthorizationVerificationInput(pydantic.BaseModel):
resource: str
action: AuthorizationAction
class AuthInfo(pydantic.BaseModel):
# Basic + Iguazio auth
username: typing.Optional[str] = None
# Basic auth
password: typing.Optional[str] = None
# Bearer auth
token: typing.Optional[str] = None
# Iguazio auth
session: typing.Optional[str] = None
data_session: typing.Optional[str] = None
access_key: typing.Optional[str] = None
user_id: typing.Optional[str] = None
user_group_ids: typing.List[str] = []
user_unix_id: typing.Optional[int] = None
projects_role: typing.Optional[ProjectsRole] = None
planes: typing.List[str] = []
def to_nuclio_auth_info(self):
if self.session != "":
return NuclioAuthInfo(password=self.session, mode=NuclioAuthKinds.iguazio)
return None
def get_member_ids(self) -> typing.List[str]:
member_ids = []
if self.user_id:
member_ids.append(self.user_id)
if self.user_group_ids:
member_ids.extend(self.user_group_ids)
return member_ids
class Credentials(pydantic.BaseModel):
access_key: typing.Optional[str]