1+ require " uuid"
12require " office365"
23require " ./application"
34
@@ -10,15 +11,18 @@ module PlaceOS::Api
1011
1112 @[AC ::Route ::Filter (:before_action )]
1213 def get_host
13- unless host = request.hostname
14+ unless @domain_host = request.hostname
1415 Log .warn { " Host header not found" }
1516 raise Error ::NotFound .new(" Unable to get host from request" )
1617 end
1718 scheme = request.headers[" Scheme" ]? || " https"
18- @redirect_url = " #{ scheme } ://#{ host } #{ self .base_route} /callback"
19+ @redirect_url = " #{ scheme } ://#{ domain_host } #{ self .base_route} /callback"
20+ @domain_url = " #{ scheme } ://#{ domain_host } "
1921 end
2022
2123 getter! redirect_url : String
24+ getter! domain_url : String
25+ getter! domain_host : String
2226
2327 @[AC ::Route ::GET (" /:id" )]
2428 def index (id : String ) : NamedTuple (url: String )
@@ -49,9 +53,12 @@ module PlaceOS::Api
4953 raise Error ::NotFound .new(" Invalid state value returned in admin consent" ) unless authority
5054 begin
5155 redirect_back = " #{ redirect_back } /#{ authority_id } /authentication"
52- _ = create_app(tenant_id)
56+ create_app(tenant_id)
57+ create_outlook_repo
5358 strat = create_strat(tenant_id, authority.id.as(String ))
5459 auth_app = create_delegated_app(tenant_id, authority.domain, strat.id.as(String ))
60+ add_outlook_plugin_auth(auth_app[:client_id ])
61+ create_outlook_config(auth_app[:client_id ])
5562 strat.update!(client_id: auth_app[:client_id ], client_secret: auth_app[:client_secret ])
5663 update_auth(authority, strat.id.as(String ))
5764 ensure
@@ -135,6 +142,77 @@ module PlaceOS::Api
135142 end
136143 end
137144
145+ private def add_outlook_plugin_auth (app_id : String ) : Nil
146+ client = get_client
147+ app = client.get_application(app_id)
148+ app_redirect_uris = app.web.try & .redirect_uris || [] of String
149+ app_redirect_uris.push(" #{ domain_url } /outlook/#/book/spaces" )
150+
151+ scope_id = UUID .v4.to_s
152+
153+ updated = {
154+ " identifierUris" : [" api://#{ domain_host } /#{ app_id } " ],
155+ " web" : {
156+ " redirectUris" : app_redirect_uris,
157+ " implicitGrantSettings" : {" enableAccessTokenIssuance" => true , " enableIdTokenIssuance" => true },
158+ },
159+ " api" : {
160+ " oauth2PermissionScopes" : [
161+ {
162+ " id" : scope_id,
163+ " adminConsentDisplayName" : " Access User and Room Calendars" ,
164+ " adminConsentDescription" : " Allow the app to read the user calendar and calendars of rooms the user has permission to view/book." ,
165+ " userConsentDisplayName" : " Access User and Room Calendars" ,
166+ " userConsentDescription" : " Allow the app to read the user calendar and calendars of rooms the user has permission to view/book." ,
167+ " isEnabled" : true ,
168+ " type" : " User" ,
169+ " value" : " access_as_user" ,
170+ },
171+ ],
172+ },
173+ }
174+ client.update_application(app_id, updated.to_json)
175+
176+ updated = {
177+ " api" : {
178+ " preAuthorizedApplications" : [
179+ {" appId" : " d3590ed6-52b3-4102-aeff-aad2292ab01c" , " delegatedPermissionIds" : [scope_id]}, # Microsoft Office
180+ {" appId" : " ea5a67f6-b6f3-4338-b240-c655ddc3cc8e" , " delegatedPermissionIds" : [scope_id]}, # Microsoft Office
181+ {" appId" : " 57fb890c-0dab-4253-a5e0-7188c88b2bb4" , " delegatedPermissionIds" : [scope_id]}, # Office on the web
182+ {" appId" : " 08e18876-6177-487e-b8b5-cf950c1e598c" , " delegatedPermissionIds" : [scope_id]}, # Office on the web
183+ {" appId" : " bc59ab01-8403-45c6-8796-ac3ef710b3e3" , " delegatedPermissionIds" : [scope_id]}, # Outlook on the web
184+ {" appId" : " 93d53678-613d-4013-afc1-62e9e444a0a5" , " delegatedPermissionIds" : [scope_id]}, # Office on the web
185+ ],
186+ },
187+ }
188+ client.update_application(app_id, updated.to_json)
189+ end
190+
191+ private def create_outlook_repo : Nil
192+ return if ::PlaceOS ::Model ::Repository .where(name: " Outlook Plugin" , uri: " https://github.com/placeos/user-interfaces" , branch: " build/outlook-rooms-addin/prod" ,
193+ folder_name: " outlookplugin" , repo_type: ::PlaceOS ::Model ::Repository ::Type ::Interface .value).count > 0
194+
195+ ::PlaceOS ::Model ::Repository .create(
196+ name: " Outlook Plugin" , uri: " https://github.com/placeos/user-interfaces" , branch: " build/outlook-rooms-addin/prod" ,
197+ folder_name: " outlookplugin" , repo_type: ::PlaceOS ::Model ::Repository ::Type ::Interface
198+ )
199+ end
200+
201+ private def create_outlook_config (app_id : String ) : Nil
202+ tenant = ::PlaceOS ::Model ::Tenant .find_by?(domain: domain_host)
203+ unless tenant
204+ Log .error { {message: " Tenant not found" , domain: domain_host} }
205+ return
206+ end
207+
208+ outlook_config = {
209+ app_id: app_id, base_path: " outlook" , app_domain: " #{ domain_url } /outlook/" ,
210+ app_resource: " api://#{ domain_host } /#{ app_id } " , source_location: " " ,
211+ }
212+ tenant.outlook_config = ::PlaceOS ::Model ::Tenant ::OutlookConfig .from_json(outlook_config.to_json)
213+ tenant.save!
214+ end
215+
138216 private def already_exists_error? (error_msg ) : Bool
139217 error = JSON .parse(error_msg)
140218 error.as_h[" error" ].as_h[" message" ] == " One or more properties contains invalid values."
0 commit comments